1d4a67d9dSGabor Juhos /* 2d4a67d9dSGabor Juhos * Atheros AR71XX/AR724X/AR913X common routines 3d4a67d9dSGabor Juhos * 48889612bSGabor Juhos * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 5d4a67d9dSGabor Juhos * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 6d4a67d9dSGabor Juhos * 78889612bSGabor Juhos * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 88889612bSGabor Juhos * 9d4a67d9dSGabor Juhos * This program is free software; you can redistribute it and/or modify it 10d4a67d9dSGabor Juhos * under the terms of the GNU General Public License version 2 as published 11d4a67d9dSGabor Juhos * by the Free Software Foundation. 12d4a67d9dSGabor Juhos */ 13d4a67d9dSGabor Juhos 14d4a67d9dSGabor Juhos #include <linux/kernel.h> 15d4a67d9dSGabor Juhos #include <linux/init.h> 16d4a67d9dSGabor Juhos #include <linux/err.h> 17d4a67d9dSGabor Juhos #include <linux/clk.h> 182c4f1ac5SGabor Juhos #include <linux/clkdev.h> 19411520afSAlban Bedel #include <linux/clk-provider.h> 203bdf1071SAntony Pavlov #include <linux/of.h> 213bdf1071SAntony Pavlov #include <linux/of_address.h> 22af5ad0deSAntony Pavlov #include <dt-bindings/clock/ath79-clk.h> 23d4a67d9dSGabor Juhos 2497541ccfSGabor Juhos #include <asm/div64.h> 2597541ccfSGabor Juhos 26d4a67d9dSGabor Juhos #include <asm/mach-ath79/ath79.h> 27d4a67d9dSGabor Juhos #include <asm/mach-ath79/ar71xx_regs.h> 28d4a67d9dSGabor Juhos #include "common.h" 293bdf1071SAntony Pavlov #include "machtypes.h" 30d4a67d9dSGabor Juhos 31d4a67d9dSGabor Juhos #define AR71XX_BASE_FREQ 40000000 32c338d59dSWeijie Gao #define AR724X_BASE_FREQ 40000000 33d4a67d9dSGabor Juhos 34af5ad0deSAntony Pavlov static struct clk *clks[ATH79_CLK_END]; 356451af02SAlban Bedel static struct clk_onecell_data clk_data = { 366451af02SAlban Bedel .clks = clks, 376451af02SAlban Bedel .clk_num = ARRAY_SIZE(clks), 386451af02SAlban Bedel }; 396451af02SAlban Bedel 409b56e0d0SFelix Fietkau static const char * const clk_names[ATH79_CLK_END] = { 419b56e0d0SFelix Fietkau [ATH79_CLK_CPU] = "cpu", 429b56e0d0SFelix Fietkau [ATH79_CLK_DDR] = "ddr", 439b56e0d0SFelix Fietkau [ATH79_CLK_AHB] = "ahb", 449b56e0d0SFelix Fietkau [ATH79_CLK_REF] = "ref", 459b56e0d0SFelix Fietkau }; 469b56e0d0SFelix Fietkau 479b56e0d0SFelix Fietkau static const char * __init ath79_clk_name(int type) 482c4f1ac5SGabor Juhos { 499b56e0d0SFelix Fietkau BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); 509b56e0d0SFelix Fietkau return clk_names[type]; 519b56e0d0SFelix Fietkau } 522c4f1ac5SGabor Juhos 539b56e0d0SFelix Fietkau static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) 549b56e0d0SFelix Fietkau { 5520d6f0c3SChristophe JAILLET if (IS_ERR(clk)) 569b56e0d0SFelix Fietkau panic("failed to allocate %s clock structure", clk_names[type]); 572c4f1ac5SGabor Juhos 589b56e0d0SFelix Fietkau clks[type] = clk; 599b56e0d0SFelix Fietkau clk_register_clkdev(clk, name, NULL); 609b56e0d0SFelix Fietkau } 616451af02SAlban Bedel 629b56e0d0SFelix Fietkau static struct clk * __init ath79_set_clk(int type, unsigned long rate) 639b56e0d0SFelix Fietkau { 649b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 659b56e0d0SFelix Fietkau struct clk *clk; 669b56e0d0SFelix Fietkau 679b56e0d0SFelix Fietkau clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); 689b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 699b56e0d0SFelix Fietkau return clk; 709b56e0d0SFelix Fietkau } 719b56e0d0SFelix Fietkau 729b56e0d0SFelix Fietkau static struct clk * __init ath79_set_ff_clk(int type, const char *parent, 739b56e0d0SFelix Fietkau unsigned int mult, unsigned int div) 749b56e0d0SFelix Fietkau { 759b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 769b56e0d0SFelix Fietkau struct clk *clk; 779b56e0d0SFelix Fietkau 789b56e0d0SFelix Fietkau clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); 799b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 806451af02SAlban Bedel return clk; 812c4f1ac5SGabor Juhos } 82d4a67d9dSGabor Juhos 83*9aca5cb5SFelix Fietkau static void __init ar71xx_clocks_init(void __iomem *pll_base) 84d4a67d9dSGabor Juhos { 856612a688SGabor Juhos unsigned long ref_rate; 866612a688SGabor Juhos unsigned long cpu_rate; 876612a688SGabor Juhos unsigned long ddr_rate; 886612a688SGabor Juhos unsigned long ahb_rate; 89d4a67d9dSGabor Juhos u32 pll; 90d4a67d9dSGabor Juhos u32 freq; 91d4a67d9dSGabor Juhos u32 div; 92d4a67d9dSGabor Juhos 936612a688SGabor Juhos ref_rate = AR71XX_BASE_FREQ; 94d4a67d9dSGabor Juhos 95*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); 96d4a67d9dSGabor Juhos 97626a0695SAlban Bedel div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; 986612a688SGabor Juhos freq = div * ref_rate; 99d4a67d9dSGabor Juhos 100d4a67d9dSGabor Juhos div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 1016612a688SGabor Juhos cpu_rate = freq / div; 102d4a67d9dSGabor Juhos 103d4a67d9dSGabor Juhos div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 1046612a688SGabor Juhos ddr_rate = freq / div; 105d4a67d9dSGabor Juhos 106d4a67d9dSGabor Juhos div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 1076612a688SGabor Juhos ahb_rate = cpu_rate / div; 1086612a688SGabor Juhos 1099b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 1109b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 1119b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 1129b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 113d4a67d9dSGabor Juhos } 114d4a67d9dSGabor Juhos 1153bdf1071SAntony Pavlov static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) 1163bdf1071SAntony Pavlov { 1173bdf1071SAntony Pavlov u32 pll; 1183bdf1071SAntony Pavlov u32 mult, div, ddr_div, ahb_div; 1193bdf1071SAntony Pavlov 1203bdf1071SAntony Pavlov pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 1213bdf1071SAntony Pavlov 1223bdf1071SAntony Pavlov mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 1233bdf1071SAntony Pavlov div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 1243bdf1071SAntony Pavlov 1253bdf1071SAntony Pavlov ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 1263bdf1071SAntony Pavlov ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 1273bdf1071SAntony Pavlov 1289b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); 1299b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); 1309b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); 1313bdf1071SAntony Pavlov } 1323bdf1071SAntony Pavlov 133*9aca5cb5SFelix Fietkau static void __init ar724x_clocks_init(void __iomem *pll_base) 134d4a67d9dSGabor Juhos { 1353bdf1071SAntony Pavlov struct clk *ref_clk; 136d4a67d9dSGabor Juhos 1379b56e0d0SFelix Fietkau ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); 138d4a67d9dSGabor Juhos 139*9aca5cb5SFelix Fietkau ar724x_clk_init(ref_clk, pll_base); 140d4a67d9dSGabor Juhos } 141d4a67d9dSGabor Juhos 1425ae5c452SAntony Pavlov static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) 1435ae5c452SAntony Pavlov { 1445ae5c452SAntony Pavlov u32 clock_ctrl; 1455ae5c452SAntony Pavlov u32 ref_div; 1465ae5c452SAntony Pavlov u32 ninit_mul; 1475ae5c452SAntony Pavlov u32 out_div; 1485ae5c452SAntony Pavlov 1495ae5c452SAntony Pavlov u32 cpu_div; 1505ae5c452SAntony Pavlov u32 ddr_div; 1515ae5c452SAntony Pavlov u32 ahb_div; 1525ae5c452SAntony Pavlov 1535ae5c452SAntony Pavlov clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 1545ae5c452SAntony Pavlov if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 1555ae5c452SAntony Pavlov ref_div = 1; 1565ae5c452SAntony Pavlov ninit_mul = 1; 1575ae5c452SAntony Pavlov out_div = 1; 1585ae5c452SAntony Pavlov 1595ae5c452SAntony Pavlov cpu_div = 1; 1605ae5c452SAntony Pavlov ddr_div = 1; 1615ae5c452SAntony Pavlov ahb_div = 1; 1625ae5c452SAntony Pavlov } else { 1635ae5c452SAntony Pavlov u32 cpu_config; 1645ae5c452SAntony Pavlov u32 t; 1655ae5c452SAntony Pavlov 1665ae5c452SAntony Pavlov cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); 1675ae5c452SAntony Pavlov 1685ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 1695ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 1705ae5c452SAntony Pavlov ref_div = t; 1715ae5c452SAntony Pavlov 1725ae5c452SAntony Pavlov ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 1735ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_NINT_MASK; 1745ae5c452SAntony Pavlov 1755ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 1765ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 1775ae5c452SAntony Pavlov if (t == 0) 1785ae5c452SAntony Pavlov t = 1; 1795ae5c452SAntony Pavlov 1805ae5c452SAntony Pavlov out_div = (1 << t); 1815ae5c452SAntony Pavlov 1825ae5c452SAntony Pavlov cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 1835ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 1845ae5c452SAntony Pavlov 1855ae5c452SAntony Pavlov ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 1865ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 1875ae5c452SAntony Pavlov 1885ae5c452SAntony Pavlov ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 1895ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 1905ae5c452SAntony Pavlov } 1915ae5c452SAntony Pavlov 1929b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, 1939b56e0d0SFelix Fietkau ref_div * out_div * cpu_div); 1949b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, 1959b56e0d0SFelix Fietkau ref_div * out_div * ddr_div); 1969b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, 1979b56e0d0SFelix Fietkau ref_div * out_div * ahb_div); 1985ae5c452SAntony Pavlov } 1995ae5c452SAntony Pavlov 200*9aca5cb5SFelix Fietkau static void __init ar933x_clocks_init(void __iomem *pll_base) 20104225e1dSGabor Juhos { 2025ae5c452SAntony Pavlov struct clk *ref_clk; 2036612a688SGabor Juhos unsigned long ref_rate; 20404225e1dSGabor Juhos u32 t; 20504225e1dSGabor Juhos 20604225e1dSGabor Juhos t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 20704225e1dSGabor Juhos if (t & AR933X_BOOTSTRAP_REF_CLK_40) 2086612a688SGabor Juhos ref_rate = (40 * 1000 * 1000); 20904225e1dSGabor Juhos else 2106612a688SGabor Juhos ref_rate = (25 * 1000 * 1000); 21104225e1dSGabor Juhos 2129b56e0d0SFelix Fietkau ref_clk = ath79_set_clk(ATH79_CLK_REF, ref_rate); 21304225e1dSGabor Juhos 2145ae5c452SAntony Pavlov ar9330_clk_init(ref_clk, ath79_pll_base); 21504225e1dSGabor Juhos } 21604225e1dSGabor Juhos 21797541ccfSGabor Juhos static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 21897541ccfSGabor Juhos u32 frac, u32 out_div) 21997541ccfSGabor Juhos { 22097541ccfSGabor Juhos u64 t; 22197541ccfSGabor Juhos u32 ret; 22297541ccfSGabor Juhos 223837f036cSGabor Juhos t = ref; 22497541ccfSGabor Juhos t *= nint; 22597541ccfSGabor Juhos do_div(t, ref_div); 22697541ccfSGabor Juhos ret = t; 22797541ccfSGabor Juhos 228837f036cSGabor Juhos t = ref; 22997541ccfSGabor Juhos t *= nfrac; 23097541ccfSGabor Juhos do_div(t, ref_div * frac); 23197541ccfSGabor Juhos ret += t; 23297541ccfSGabor Juhos 23397541ccfSGabor Juhos ret /= (1 << out_div); 23497541ccfSGabor Juhos return ret; 23597541ccfSGabor Juhos } 23697541ccfSGabor Juhos 237*9aca5cb5SFelix Fietkau static void __init ar934x_clocks_init(void __iomem *pll_base) 2388889612bSGabor Juhos { 2396612a688SGabor Juhos unsigned long ref_rate; 2406612a688SGabor Juhos unsigned long cpu_rate; 2416612a688SGabor Juhos unsigned long ddr_rate; 2426612a688SGabor Juhos unsigned long ahb_rate; 24397541ccfSGabor Juhos u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 2448889612bSGabor Juhos u32 cpu_pll, ddr_pll; 2458889612bSGabor Juhos u32 bootstrap; 24697541ccfSGabor Juhos void __iomem *dpll_base; 24797541ccfSGabor Juhos 24897541ccfSGabor Juhos dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 2498889612bSGabor Juhos 2508889612bSGabor Juhos bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 2518889612bSGabor Juhos if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 2526612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 2538889612bSGabor Juhos else 2546612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 2558889612bSGabor Juhos 25697541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 25797541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 25897541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 25997541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 26097541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); 26197541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 26297541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 26397541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 26497541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 26597541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 26697541ccfSGabor Juhos frac = 1 << 18; 26797541ccfSGabor Juhos } else { 268*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); 2698889612bSGabor Juhos out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 2708889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 2718889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 2728889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 2738889612bSGabor Juhos nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 2748889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NINT_MASK; 27597541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 2768889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 27797541ccfSGabor Juhos frac = 1 << 6; 27897541ccfSGabor Juhos } 2798889612bSGabor Juhos 2806612a688SGabor Juhos cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 28197541ccfSGabor Juhos nfrac, frac, out_div); 2828889612bSGabor Juhos 28397541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); 28497541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 28597541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 28697541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 28797541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); 28897541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 28997541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 29097541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 29197541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 29297541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 29397541ccfSGabor Juhos frac = 1 << 18; 29497541ccfSGabor Juhos } else { 295*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); 2968889612bSGabor Juhos out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 2978889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 2988889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 2998889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 3008889612bSGabor Juhos nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 3018889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NINT_MASK; 30297541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 3038889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 30497541ccfSGabor Juhos frac = 1 << 10; 30597541ccfSGabor Juhos } 3068889612bSGabor Juhos 3076612a688SGabor Juhos ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 30897541ccfSGabor Juhos nfrac, frac, out_div); 3098889612bSGabor Juhos 310*9aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 3118889612bSGabor Juhos 3128889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 3138889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 3148889612bSGabor Juhos 3158889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 3166612a688SGabor Juhos cpu_rate = ref_rate; 3178889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 3186612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 3198889612bSGabor Juhos else 3206612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 3218889612bSGabor Juhos 3228889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 3238889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 3248889612bSGabor Juhos 3258889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 3266612a688SGabor Juhos ddr_rate = ref_rate; 3278889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 3286612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 3298889612bSGabor Juhos else 3306612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 3318889612bSGabor Juhos 3328889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 3338889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 3348889612bSGabor Juhos 3358889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 3366612a688SGabor Juhos ahb_rate = ref_rate; 3378889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 3386612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 3398889612bSGabor Juhos else 3406612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 3416612a688SGabor Juhos 3429b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 3439b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 3449b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 3459b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 3468889612bSGabor Juhos 34797541ccfSGabor Juhos iounmap(dpll_base); 3488889612bSGabor Juhos } 3498889612bSGabor Juhos 350*9aca5cb5SFelix Fietkau static void __init qca953x_clocks_init(void __iomem *pll_base) 351af2d1b52SMatthias Schiffer { 352af2d1b52SMatthias Schiffer unsigned long ref_rate; 353af2d1b52SMatthias Schiffer unsigned long cpu_rate; 354af2d1b52SMatthias Schiffer unsigned long ddr_rate; 355af2d1b52SMatthias Schiffer unsigned long ahb_rate; 356af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 357af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 358af2d1b52SMatthias Schiffer u32 bootstrap; 359af2d1b52SMatthias Schiffer 360af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); 361af2d1b52SMatthias Schiffer if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) 362af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 363af2d1b52SMatthias Schiffer else 364af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 365af2d1b52SMatthias Schiffer 366*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); 367af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 368af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 369af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 370af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; 371af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & 372af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NINT_MASK; 373af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 374af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; 375af2d1b52SMatthias Schiffer 376af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 377af2d1b52SMatthias Schiffer cpu_pll += frac * (ref_rate >> 6) / ref_div; 378af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 379af2d1b52SMatthias Schiffer 380*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); 381af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 382af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 383af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 384af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; 385af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & 386af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NINT_MASK; 387af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 388af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; 389af2d1b52SMatthias Schiffer 390af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 391af2d1b52SMatthias Schiffer ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 392af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 393af2d1b52SMatthias Schiffer 394*9aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); 395af2d1b52SMatthias Schiffer 396af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 397af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 398af2d1b52SMatthias Schiffer 399af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 400af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 401af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 402af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 403af2d1b52SMatthias Schiffer else 404af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 405af2d1b52SMatthias Schiffer 406af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 407af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 408af2d1b52SMatthias Schiffer 409af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 410af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 411af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 412af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 413af2d1b52SMatthias Schiffer else 414af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 415af2d1b52SMatthias Schiffer 416af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 417af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 418af2d1b52SMatthias Schiffer 419af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 420af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 421af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 422af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 423af2d1b52SMatthias Schiffer else 424af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 425af2d1b52SMatthias Schiffer 4269b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 4279b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 4289b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 4299b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 430af2d1b52SMatthias Schiffer } 431af2d1b52SMatthias Schiffer 432*9aca5cb5SFelix Fietkau static void __init qca955x_clocks_init(void __iomem *pll_base) 43341583c05SGabor Juhos { 4346612a688SGabor Juhos unsigned long ref_rate; 4356612a688SGabor Juhos unsigned long cpu_rate; 4366612a688SGabor Juhos unsigned long ddr_rate; 4376612a688SGabor Juhos unsigned long ahb_rate; 43841583c05SGabor Juhos u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 43941583c05SGabor Juhos u32 cpu_pll, ddr_pll; 44041583c05SGabor Juhos u32 bootstrap; 44141583c05SGabor Juhos 44241583c05SGabor Juhos bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 44341583c05SGabor Juhos if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 4446612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 44541583c05SGabor Juhos else 4466612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 44741583c05SGabor Juhos 448*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); 44941583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 45041583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 45141583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 45241583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 45341583c05SGabor Juhos nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 45441583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NINT_MASK; 45541583c05SGabor Juhos frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 45641583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 45741583c05SGabor Juhos 4586612a688SGabor Juhos cpu_pll = nint * ref_rate / ref_div; 4596612a688SGabor Juhos cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 46041583c05SGabor Juhos cpu_pll /= (1 << out_div); 46141583c05SGabor Juhos 462*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); 46341583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 46441583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 46541583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 46641583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 46741583c05SGabor Juhos nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 46841583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NINT_MASK; 46941583c05SGabor Juhos frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 47041583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 47141583c05SGabor Juhos 4726612a688SGabor Juhos ddr_pll = nint * ref_rate / ref_div; 4736612a688SGabor Juhos ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 47441583c05SGabor Juhos ddr_pll /= (1 << out_div); 47541583c05SGabor Juhos 476*9aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); 47741583c05SGabor Juhos 47841583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 47941583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 48041583c05SGabor Juhos 48141583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 4826612a688SGabor Juhos cpu_rate = ref_rate; 48341583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 4846612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 48541583c05SGabor Juhos else 4866612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 48741583c05SGabor Juhos 48841583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 48941583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 49041583c05SGabor Juhos 49141583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 4926612a688SGabor Juhos ddr_rate = ref_rate; 49341583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 4946612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 49541583c05SGabor Juhos else 4966612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 49741583c05SGabor Juhos 49841583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 49941583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 50041583c05SGabor Juhos 50141583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 5026612a688SGabor Juhos ahb_rate = ref_rate; 50341583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 5046612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 50541583c05SGabor Juhos else 5066612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 5076612a688SGabor Juhos 5089b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 5099b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 5109b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 5119b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 51241583c05SGabor Juhos } 51341583c05SGabor Juhos 514*9aca5cb5SFelix Fietkau static void __init qca956x_clocks_init(void __iomem *pll_base) 515af2d1b52SMatthias Schiffer { 516af2d1b52SMatthias Schiffer unsigned long ref_rate; 517af2d1b52SMatthias Schiffer unsigned long cpu_rate; 518af2d1b52SMatthias Schiffer unsigned long ddr_rate; 519af2d1b52SMatthias Schiffer unsigned long ahb_rate; 520af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; 521af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 522af2d1b52SMatthias Schiffer u32 bootstrap; 523af2d1b52SMatthias Schiffer 524af2d1b52SMatthias Schiffer /* 525af2d1b52SMatthias Schiffer * QCA956x timer init workaround has to be applied right before setting 526af2d1b52SMatthias Schiffer * up the clock. Else, there will be no jiffies 527af2d1b52SMatthias Schiffer */ 528af2d1b52SMatthias Schiffer u32 misc; 529af2d1b52SMatthias Schiffer 530af2d1b52SMatthias Schiffer misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); 531af2d1b52SMatthias Schiffer misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; 532af2d1b52SMatthias Schiffer ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); 533af2d1b52SMatthias Schiffer 534af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); 535af2d1b52SMatthias Schiffer if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) 536af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 537af2d1b52SMatthias Schiffer else 538af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 539af2d1b52SMatthias Schiffer 540*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); 541af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 542af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 543af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 544af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 545af2d1b52SMatthias Schiffer 546*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); 547af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 548af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 549af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 550af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; 551af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & 552af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; 553af2d1b52SMatthias Schiffer 554af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 555af2d1b52SMatthias Schiffer cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 556af2d1b52SMatthias Schiffer cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 557af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 558af2d1b52SMatthias Schiffer 559*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); 560af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 561af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 562af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 563af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 564*9aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); 565af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 566af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 567af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 568af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; 569af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & 570af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; 571af2d1b52SMatthias Schiffer 572af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 573af2d1b52SMatthias Schiffer ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 574af2d1b52SMatthias Schiffer ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 575af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 576af2d1b52SMatthias Schiffer 577*9aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); 578af2d1b52SMatthias Schiffer 579af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 580af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 581af2d1b52SMatthias Schiffer 582af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 583af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 584af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) 585af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 586af2d1b52SMatthias Schiffer else 587af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 588af2d1b52SMatthias Schiffer 589af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 590af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 591af2d1b52SMatthias Schiffer 592af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 593af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 594af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) 595af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 596af2d1b52SMatthias Schiffer else 597af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 598af2d1b52SMatthias Schiffer 599af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 600af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 601af2d1b52SMatthias Schiffer 602af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 603af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 604af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 605af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 606af2d1b52SMatthias Schiffer else 607af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 608af2d1b52SMatthias Schiffer 6099b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 6109b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 6119b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 6129b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 613af2d1b52SMatthias Schiffer } 614af2d1b52SMatthias Schiffer 615d4a67d9dSGabor Juhos void __init ath79_clocks_init(void) 616d4a67d9dSGabor Juhos { 6174a0e89b9SFelix Fietkau const char *wdt; 6184a0e89b9SFelix Fietkau const char *uart; 6194a0e89b9SFelix Fietkau 620d4a67d9dSGabor Juhos if (soc_is_ar71xx()) 621*9aca5cb5SFelix Fietkau ar71xx_clocks_init(ath79_pll_base); 622f4c87b7aSAlban Bedel else if (soc_is_ar724x() || soc_is_ar913x()) 623*9aca5cb5SFelix Fietkau ar724x_clocks_init(ath79_pll_base); 62404225e1dSGabor Juhos else if (soc_is_ar933x()) 625*9aca5cb5SFelix Fietkau ar933x_clocks_init(ath79_pll_base); 6268889612bSGabor Juhos else if (soc_is_ar934x()) 627*9aca5cb5SFelix Fietkau ar934x_clocks_init(ath79_pll_base); 628af2d1b52SMatthias Schiffer else if (soc_is_qca953x()) 629*9aca5cb5SFelix Fietkau qca953x_clocks_init(ath79_pll_base); 63041583c05SGabor Juhos else if (soc_is_qca955x()) 631*9aca5cb5SFelix Fietkau qca955x_clocks_init(ath79_pll_base); 632af2d1b52SMatthias Schiffer else if (soc_is_qca956x() || soc_is_tp9343()) 633*9aca5cb5SFelix Fietkau qca956x_clocks_init(ath79_pll_base); 634d4a67d9dSGabor Juhos else 635d4a67d9dSGabor Juhos BUG(); 6364a0e89b9SFelix Fietkau 6374a0e89b9SFelix Fietkau if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x()) { 6384a0e89b9SFelix Fietkau wdt = "ahb"; 6394a0e89b9SFelix Fietkau uart = "ahb"; 6404a0e89b9SFelix Fietkau } else if (soc_is_ar933x()) { 6414a0e89b9SFelix Fietkau wdt = "ahb"; 6424a0e89b9SFelix Fietkau uart = "ref"; 6434a0e89b9SFelix Fietkau } else { 6444a0e89b9SFelix Fietkau wdt = "ref"; 6454a0e89b9SFelix Fietkau uart = "ref"; 6464a0e89b9SFelix Fietkau } 6474a0e89b9SFelix Fietkau 6484a0e89b9SFelix Fietkau clk_add_alias("wdt", NULL, wdt, NULL); 6494a0e89b9SFelix Fietkau clk_add_alias("uart", NULL, uart, NULL); 650d4a67d9dSGabor Juhos } 651d4a67d9dSGabor Juhos 65223107802SGabor Juhos unsigned long __init 65323107802SGabor Juhos ath79_get_sys_clk_rate(const char *id) 65423107802SGabor Juhos { 65523107802SGabor Juhos struct clk *clk; 65623107802SGabor Juhos unsigned long rate; 65723107802SGabor Juhos 65823107802SGabor Juhos clk = clk_get(NULL, id); 65923107802SGabor Juhos if (IS_ERR(clk)) 66023107802SGabor Juhos panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); 66123107802SGabor Juhos 66223107802SGabor Juhos rate = clk_get_rate(clk); 66323107802SGabor Juhos clk_put(clk); 66423107802SGabor Juhos 66523107802SGabor Juhos return rate; 66623107802SGabor Juhos } 6676451af02SAlban Bedel 6686451af02SAlban Bedel #ifdef CONFIG_OF 6696451af02SAlban Bedel static void __init ath79_clocks_init_dt(struct device_node *np) 6706451af02SAlban Bedel { 6716451af02SAlban Bedel of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 6726451af02SAlban Bedel } 6736451af02SAlban Bedel 6746451af02SAlban Bedel CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); 6756451af02SAlban Bedel CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); 6766451af02SAlban Bedel CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); 6776451af02SAlban Bedel CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); 6783bdf1071SAntony Pavlov 6793bdf1071SAntony Pavlov static void __init ath79_clocks_init_dt_ng(struct device_node *np) 6803bdf1071SAntony Pavlov { 6813bdf1071SAntony Pavlov struct clk *ref_clk; 6823bdf1071SAntony Pavlov void __iomem *pll_base; 6833bdf1071SAntony Pavlov 6843bdf1071SAntony Pavlov ref_clk = of_clk_get(np, 0); 6853bdf1071SAntony Pavlov if (IS_ERR(ref_clk)) { 6867f27b5b8SRob Herring pr_err("%pOF: of_clk_get failed\n", np); 6873bdf1071SAntony Pavlov goto err; 6883bdf1071SAntony Pavlov } 6893bdf1071SAntony Pavlov 6903bdf1071SAntony Pavlov pll_base = of_iomap(np, 0); 6913bdf1071SAntony Pavlov if (!pll_base) { 6927f27b5b8SRob Herring pr_err("%pOF: can't map pll registers\n", np); 6933bdf1071SAntony Pavlov goto err_clk; 6943bdf1071SAntony Pavlov } 6953bdf1071SAntony Pavlov 6965ae5c452SAntony Pavlov if (of_device_is_compatible(np, "qca,ar9130-pll")) 6973bdf1071SAntony Pavlov ar724x_clk_init(ref_clk, pll_base); 6985ae5c452SAntony Pavlov else if (of_device_is_compatible(np, "qca,ar9330-pll")) 6995ae5c452SAntony Pavlov ar9330_clk_init(ref_clk, pll_base); 7005ae5c452SAntony Pavlov else { 7017f27b5b8SRob Herring pr_err("%pOF: could not find any appropriate clk_init()\n", np); 702b3d91db3SArvind Yadav goto err_iounmap; 7035ae5c452SAntony Pavlov } 7043bdf1071SAntony Pavlov 7053bdf1071SAntony Pavlov if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 7067f27b5b8SRob Herring pr_err("%pOF: could not register clk provider\n", np); 707b3d91db3SArvind Yadav goto err_iounmap; 7083bdf1071SAntony Pavlov } 7093bdf1071SAntony Pavlov 7103bdf1071SAntony Pavlov return; 7113bdf1071SAntony Pavlov 712b3d91db3SArvind Yadav err_iounmap: 713b3d91db3SArvind Yadav iounmap(pll_base); 714b3d91db3SArvind Yadav 7153bdf1071SAntony Pavlov err_clk: 7163bdf1071SAntony Pavlov clk_put(ref_clk); 7173bdf1071SAntony Pavlov 7183bdf1071SAntony Pavlov err: 7193bdf1071SAntony Pavlov return; 7203bdf1071SAntony Pavlov } 7213bdf1071SAntony Pavlov CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); 7225ae5c452SAntony Pavlov CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); 7236451af02SAlban Bedel #endif 724