1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2d4a67d9dSGabor Juhos /* 3d4a67d9dSGabor Juhos * Atheros AR71XX/AR724X/AR913X common routines 4d4a67d9dSGabor Juhos * 58889612bSGabor Juhos * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 6d4a67d9dSGabor Juhos * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 7d4a67d9dSGabor Juhos * 88889612bSGabor Juhos * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 9d4a67d9dSGabor Juhos */ 10d4a67d9dSGabor Juhos 11d4a67d9dSGabor Juhos #include <linux/kernel.h> 12d4a67d9dSGabor Juhos #include <linux/init.h> 1362e59c4eSStephen Boyd #include <linux/io.h> 14d4a67d9dSGabor Juhos #include <linux/err.h> 15d4a67d9dSGabor Juhos #include <linux/clk.h> 162c4f1ac5SGabor Juhos #include <linux/clkdev.h> 17411520afSAlban Bedel #include <linux/clk-provider.h> 183bdf1071SAntony Pavlov #include <linux/of.h> 193bdf1071SAntony Pavlov #include <linux/of_address.h> 20af5ad0deSAntony Pavlov #include <dt-bindings/clock/ath79-clk.h> 21d4a67d9dSGabor Juhos 2297541ccfSGabor Juhos #include <asm/div64.h> 2397541ccfSGabor Juhos 24d4a67d9dSGabor Juhos #include <asm/mach-ath79/ath79.h> 25d4a67d9dSGabor Juhos #include <asm/mach-ath79/ar71xx_regs.h> 26d4a67d9dSGabor Juhos #include "common.h" 27d4a67d9dSGabor Juhos 28d4a67d9dSGabor Juhos #define AR71XX_BASE_FREQ 40000000 29c338d59dSWeijie Gao #define AR724X_BASE_FREQ 40000000 30d4a67d9dSGabor Juhos 31af5ad0deSAntony Pavlov static struct clk *clks[ATH79_CLK_END]; 326451af02SAlban Bedel static struct clk_onecell_data clk_data = { 336451af02SAlban Bedel .clks = clks, 346451af02SAlban Bedel .clk_num = ARRAY_SIZE(clks), 356451af02SAlban Bedel }; 366451af02SAlban Bedel 379b56e0d0SFelix Fietkau static const char * const clk_names[ATH79_CLK_END] = { 389b56e0d0SFelix Fietkau [ATH79_CLK_CPU] = "cpu", 399b56e0d0SFelix Fietkau [ATH79_CLK_DDR] = "ddr", 409b56e0d0SFelix Fietkau [ATH79_CLK_AHB] = "ahb", 419b56e0d0SFelix Fietkau [ATH79_CLK_REF] = "ref", 426810ed32SFelix Fietkau [ATH79_CLK_MDIO] = "mdio", 439b56e0d0SFelix Fietkau }; 449b56e0d0SFelix Fietkau 459b56e0d0SFelix Fietkau static const char * __init ath79_clk_name(int type) 462c4f1ac5SGabor Juhos { 479b56e0d0SFelix Fietkau BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); 489b56e0d0SFelix Fietkau return clk_names[type]; 499b56e0d0SFelix Fietkau } 502c4f1ac5SGabor Juhos 519b56e0d0SFelix Fietkau static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) 529b56e0d0SFelix Fietkau { 5320d6f0c3SChristophe JAILLET if (IS_ERR(clk)) 549b56e0d0SFelix Fietkau panic("failed to allocate %s clock structure", clk_names[type]); 552c4f1ac5SGabor Juhos 569b56e0d0SFelix Fietkau clks[type] = clk; 579b56e0d0SFelix Fietkau clk_register_clkdev(clk, name, NULL); 589b56e0d0SFelix Fietkau } 596451af02SAlban Bedel 609b56e0d0SFelix Fietkau static struct clk * __init ath79_set_clk(int type, unsigned long rate) 619b56e0d0SFelix Fietkau { 629b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 639b56e0d0SFelix Fietkau struct clk *clk; 649b56e0d0SFelix Fietkau 659b56e0d0SFelix Fietkau clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); 669b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 679b56e0d0SFelix Fietkau return clk; 689b56e0d0SFelix Fietkau } 699b56e0d0SFelix Fietkau 709b56e0d0SFelix Fietkau static struct clk * __init ath79_set_ff_clk(int type, const char *parent, 719b56e0d0SFelix Fietkau unsigned int mult, unsigned int div) 729b56e0d0SFelix Fietkau { 739b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 749b56e0d0SFelix Fietkau struct clk *clk; 759b56e0d0SFelix Fietkau 769b56e0d0SFelix Fietkau clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); 779b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 786451af02SAlban Bedel return clk; 792c4f1ac5SGabor Juhos } 80d4a67d9dSGabor Juhos 818e641752SFelix Fietkau static unsigned long __init ath79_setup_ref_clk(unsigned long rate) 828e641752SFelix Fietkau { 838e641752SFelix Fietkau struct clk *clk = clks[ATH79_CLK_REF]; 848e641752SFelix Fietkau 858e641752SFelix Fietkau if (clk) 868e641752SFelix Fietkau rate = clk_get_rate(clk); 878e641752SFelix Fietkau else 888e641752SFelix Fietkau clk = ath79_set_clk(ATH79_CLK_REF, rate); 898e641752SFelix Fietkau 908e641752SFelix Fietkau return rate; 918e641752SFelix Fietkau } 928e641752SFelix Fietkau 939aca5cb5SFelix Fietkau static void __init ar71xx_clocks_init(void __iomem *pll_base) 94d4a67d9dSGabor Juhos { 956612a688SGabor Juhos unsigned long ref_rate; 966612a688SGabor Juhos unsigned long cpu_rate; 976612a688SGabor Juhos unsigned long ddr_rate; 986612a688SGabor Juhos unsigned long ahb_rate; 99d4a67d9dSGabor Juhos u32 pll; 100d4a67d9dSGabor Juhos u32 freq; 101d4a67d9dSGabor Juhos u32 div; 102d4a67d9dSGabor Juhos 1038e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); 104d4a67d9dSGabor Juhos 1059aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); 106d4a67d9dSGabor Juhos 107626a0695SAlban Bedel div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; 1086612a688SGabor Juhos freq = div * ref_rate; 109d4a67d9dSGabor Juhos 110d4a67d9dSGabor Juhos div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 1116612a688SGabor Juhos cpu_rate = freq / div; 112d4a67d9dSGabor Juhos 113d4a67d9dSGabor Juhos div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 1146612a688SGabor Juhos ddr_rate = freq / div; 115d4a67d9dSGabor Juhos 116d4a67d9dSGabor Juhos div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 1176612a688SGabor Juhos ahb_rate = cpu_rate / div; 1186612a688SGabor Juhos 1199b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 1209b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 1219b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 122d4a67d9dSGabor Juhos } 123d4a67d9dSGabor Juhos 1248e641752SFelix Fietkau static void __init ar724x_clocks_init(void __iomem *pll_base) 1253bdf1071SAntony Pavlov { 1263bdf1071SAntony Pavlov u32 mult, div, ddr_div, ahb_div; 1278e641752SFelix Fietkau u32 pll; 1288e641752SFelix Fietkau 1298e641752SFelix Fietkau ath79_setup_ref_clk(AR71XX_BASE_FREQ); 1303bdf1071SAntony Pavlov 1313bdf1071SAntony Pavlov pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 1323bdf1071SAntony Pavlov 1333bdf1071SAntony Pavlov mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 1343bdf1071SAntony Pavlov div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 1353bdf1071SAntony Pavlov 1363bdf1071SAntony Pavlov ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 1373bdf1071SAntony Pavlov ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 1383bdf1071SAntony Pavlov 1399b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); 1409b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); 1419b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); 1423bdf1071SAntony Pavlov } 1433bdf1071SAntony Pavlov 1448e641752SFelix Fietkau static void __init ar933x_clocks_init(void __iomem *pll_base) 145d4a67d9dSGabor Juhos { 1468e641752SFelix Fietkau unsigned long ref_rate; 1475ae5c452SAntony Pavlov u32 clock_ctrl; 1485ae5c452SAntony Pavlov u32 ref_div; 1495ae5c452SAntony Pavlov u32 ninit_mul; 1505ae5c452SAntony Pavlov u32 out_div; 1515ae5c452SAntony Pavlov 1525ae5c452SAntony Pavlov u32 cpu_div; 1535ae5c452SAntony Pavlov u32 ddr_div; 1545ae5c452SAntony Pavlov u32 ahb_div; 1558e641752SFelix Fietkau u32 t; 1568e641752SFelix Fietkau 1578e641752SFelix Fietkau t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 1588e641752SFelix Fietkau if (t & AR933X_BOOTSTRAP_REF_CLK_40) 1598e641752SFelix Fietkau ref_rate = (40 * 1000 * 1000); 1608e641752SFelix Fietkau else 1618e641752SFelix Fietkau ref_rate = (25 * 1000 * 1000); 1628e641752SFelix Fietkau 1638e641752SFelix Fietkau ath79_setup_ref_clk(ref_rate); 1645ae5c452SAntony Pavlov 1655ae5c452SAntony Pavlov clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 1665ae5c452SAntony Pavlov if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 1675ae5c452SAntony Pavlov ref_div = 1; 1685ae5c452SAntony Pavlov ninit_mul = 1; 1695ae5c452SAntony Pavlov out_div = 1; 1705ae5c452SAntony Pavlov 1715ae5c452SAntony Pavlov cpu_div = 1; 1725ae5c452SAntony Pavlov ddr_div = 1; 1735ae5c452SAntony Pavlov ahb_div = 1; 1745ae5c452SAntony Pavlov } else { 1755ae5c452SAntony Pavlov u32 cpu_config; 1765ae5c452SAntony Pavlov u32 t; 1775ae5c452SAntony Pavlov 1785ae5c452SAntony Pavlov cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); 1795ae5c452SAntony Pavlov 1805ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 1815ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 1825ae5c452SAntony Pavlov ref_div = t; 1835ae5c452SAntony Pavlov 1845ae5c452SAntony Pavlov ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 1855ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_NINT_MASK; 1865ae5c452SAntony Pavlov 1875ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 1885ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 1895ae5c452SAntony Pavlov if (t == 0) 1905ae5c452SAntony Pavlov t = 1; 1915ae5c452SAntony Pavlov 1925ae5c452SAntony Pavlov out_div = (1 << t); 1935ae5c452SAntony Pavlov 1945ae5c452SAntony Pavlov cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 1955ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 1965ae5c452SAntony Pavlov 1975ae5c452SAntony Pavlov ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 1985ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 1995ae5c452SAntony Pavlov 2005ae5c452SAntony Pavlov ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 2015ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 2025ae5c452SAntony Pavlov } 2035ae5c452SAntony Pavlov 2049b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, 2059b56e0d0SFelix Fietkau ref_div * out_div * cpu_div); 2069b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, 2079b56e0d0SFelix Fietkau ref_div * out_div * ddr_div); 2089b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, 2099b56e0d0SFelix Fietkau ref_div * out_div * ahb_div); 2105ae5c452SAntony Pavlov } 2115ae5c452SAntony Pavlov 21297541ccfSGabor Juhos static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 21397541ccfSGabor Juhos u32 frac, u32 out_div) 21497541ccfSGabor Juhos { 21597541ccfSGabor Juhos u64 t; 21697541ccfSGabor Juhos u32 ret; 21797541ccfSGabor Juhos 218837f036cSGabor Juhos t = ref; 21997541ccfSGabor Juhos t *= nint; 22097541ccfSGabor Juhos do_div(t, ref_div); 22197541ccfSGabor Juhos ret = t; 22297541ccfSGabor Juhos 223837f036cSGabor Juhos t = ref; 22497541ccfSGabor Juhos t *= nfrac; 22597541ccfSGabor Juhos do_div(t, ref_div * frac); 22697541ccfSGabor Juhos ret += t; 22797541ccfSGabor Juhos 22897541ccfSGabor Juhos ret /= (1 << out_div); 22997541ccfSGabor Juhos return ret; 23097541ccfSGabor Juhos } 23197541ccfSGabor Juhos 2329aca5cb5SFelix Fietkau static void __init ar934x_clocks_init(void __iomem *pll_base) 2338889612bSGabor Juhos { 2346612a688SGabor Juhos unsigned long ref_rate; 2356612a688SGabor Juhos unsigned long cpu_rate; 2366612a688SGabor Juhos unsigned long ddr_rate; 2376612a688SGabor Juhos unsigned long ahb_rate; 23897541ccfSGabor Juhos u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 2398889612bSGabor Juhos u32 cpu_pll, ddr_pll; 2408889612bSGabor Juhos u32 bootstrap; 24197541ccfSGabor Juhos void __iomem *dpll_base; 24297541ccfSGabor Juhos 24397541ccfSGabor Juhos dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 2448889612bSGabor Juhos 2458889612bSGabor Juhos bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 2468889612bSGabor Juhos if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 2476612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 2488889612bSGabor Juhos else 2496612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 2508889612bSGabor Juhos 2518e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 2528e641752SFelix Fietkau 25397541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 25497541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 25597541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 25697541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 25797541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); 25897541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 25997541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 26097541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 26197541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 26297541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 26397541ccfSGabor Juhos frac = 1 << 18; 26497541ccfSGabor Juhos } else { 2659aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); 2668889612bSGabor Juhos out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 2678889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 2688889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 2698889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 2708889612bSGabor Juhos nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 2718889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NINT_MASK; 27297541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 2738889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 27497541ccfSGabor Juhos frac = 1 << 6; 27597541ccfSGabor Juhos } 2768889612bSGabor Juhos 2776612a688SGabor Juhos cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 27897541ccfSGabor Juhos nfrac, frac, out_div); 2798889612bSGabor Juhos 28097541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); 28197541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 28297541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 28397541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 28497541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); 28597541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 28697541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 28797541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 28897541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 28997541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 29097541ccfSGabor Juhos frac = 1 << 18; 29197541ccfSGabor Juhos } else { 2929aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); 2938889612bSGabor Juhos out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 2948889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 2958889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 2968889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 2978889612bSGabor Juhos nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 2988889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NINT_MASK; 29997541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 3008889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 30197541ccfSGabor Juhos frac = 1 << 10; 30297541ccfSGabor Juhos } 3038889612bSGabor Juhos 3046612a688SGabor Juhos ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 30597541ccfSGabor Juhos nfrac, frac, out_div); 3068889612bSGabor Juhos 3079aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 3088889612bSGabor Juhos 3098889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 3108889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 3118889612bSGabor Juhos 3128889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 3136612a688SGabor Juhos cpu_rate = ref_rate; 3148889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 3156612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 3168889612bSGabor Juhos else 3176612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 3188889612bSGabor Juhos 3198889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 3208889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 3218889612bSGabor Juhos 3228889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 3236612a688SGabor Juhos ddr_rate = ref_rate; 3248889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 3256612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 3268889612bSGabor Juhos else 3276612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 3288889612bSGabor Juhos 3298889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 3308889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 3318889612bSGabor Juhos 3328889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 3336612a688SGabor Juhos ahb_rate = ref_rate; 3348889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 3356612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 3368889612bSGabor Juhos else 3376612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 3386612a688SGabor Juhos 3399b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 3409b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 3419b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 3428889612bSGabor Juhos 3436810ed32SFelix Fietkau clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); 3446810ed32SFelix Fietkau if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) 3456810ed32SFelix Fietkau ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); 3466810ed32SFelix Fietkau 34797541ccfSGabor Juhos iounmap(dpll_base); 3488889612bSGabor Juhos } 3498889612bSGabor Juhos 3509aca5cb5SFelix 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 3668e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 3678e641752SFelix Fietkau 3689aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); 369af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 370af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 371af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 372af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; 373af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & 374af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NINT_MASK; 375af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 376af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; 377af2d1b52SMatthias Schiffer 378af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 379af2d1b52SMatthias Schiffer cpu_pll += frac * (ref_rate >> 6) / ref_div; 380af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 381af2d1b52SMatthias Schiffer 3829aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); 383af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 384af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 385af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 386af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; 387af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & 388af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NINT_MASK; 389af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 390af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; 391af2d1b52SMatthias Schiffer 392af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 393af2d1b52SMatthias Schiffer ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 394af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 395af2d1b52SMatthias Schiffer 3969aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); 397af2d1b52SMatthias Schiffer 398af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 399af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 400af2d1b52SMatthias Schiffer 401af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 402af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 403af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 404af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 405af2d1b52SMatthias Schiffer else 406af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 407af2d1b52SMatthias Schiffer 408af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 409af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 410af2d1b52SMatthias Schiffer 411af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 412af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 413af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 414af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 415af2d1b52SMatthias Schiffer else 416af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 417af2d1b52SMatthias Schiffer 418af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 419af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 420af2d1b52SMatthias Schiffer 421af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 422af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 423af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 424af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 425af2d1b52SMatthias Schiffer else 426af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 427af2d1b52SMatthias Schiffer 4289b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 4299b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 4309b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 431af2d1b52SMatthias Schiffer } 432af2d1b52SMatthias Schiffer 4339aca5cb5SFelix Fietkau static void __init qca955x_clocks_init(void __iomem *pll_base) 43441583c05SGabor Juhos { 4356612a688SGabor Juhos unsigned long ref_rate; 4366612a688SGabor Juhos unsigned long cpu_rate; 4376612a688SGabor Juhos unsigned long ddr_rate; 4386612a688SGabor Juhos unsigned long ahb_rate; 43941583c05SGabor Juhos u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 44041583c05SGabor Juhos u32 cpu_pll, ddr_pll; 44141583c05SGabor Juhos u32 bootstrap; 44241583c05SGabor Juhos 44341583c05SGabor Juhos bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 44441583c05SGabor Juhos if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 4456612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 44641583c05SGabor Juhos else 4476612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 44841583c05SGabor Juhos 4498e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 4508e641752SFelix Fietkau 4519aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); 45241583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 45341583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 45441583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 45541583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 45641583c05SGabor Juhos nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 45741583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NINT_MASK; 45841583c05SGabor Juhos frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 45941583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 46041583c05SGabor Juhos 4616612a688SGabor Juhos cpu_pll = nint * ref_rate / ref_div; 4626612a688SGabor Juhos cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 46341583c05SGabor Juhos cpu_pll /= (1 << out_div); 46441583c05SGabor Juhos 4659aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); 46641583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 46741583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 46841583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 46941583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 47041583c05SGabor Juhos nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 47141583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NINT_MASK; 47241583c05SGabor Juhos frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 47341583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 47441583c05SGabor Juhos 4756612a688SGabor Juhos ddr_pll = nint * ref_rate / ref_div; 4766612a688SGabor Juhos ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 47741583c05SGabor Juhos ddr_pll /= (1 << out_div); 47841583c05SGabor Juhos 4799aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); 48041583c05SGabor Juhos 48141583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 48241583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 48341583c05SGabor Juhos 48441583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 4856612a688SGabor Juhos cpu_rate = ref_rate; 48641583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 4876612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 48841583c05SGabor Juhos else 4896612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 49041583c05SGabor Juhos 49141583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 49241583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 49341583c05SGabor Juhos 49441583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 4956612a688SGabor Juhos ddr_rate = ref_rate; 49641583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 4976612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 49841583c05SGabor Juhos else 4996612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 50041583c05SGabor Juhos 50141583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 50241583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 50341583c05SGabor Juhos 50441583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 5056612a688SGabor Juhos ahb_rate = ref_rate; 50641583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 5076612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 50841583c05SGabor Juhos else 5096612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 5106612a688SGabor Juhos 5119b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 5129b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 5139b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 51441583c05SGabor Juhos } 51541583c05SGabor Juhos 5169aca5cb5SFelix Fietkau static void __init qca956x_clocks_init(void __iomem *pll_base) 517af2d1b52SMatthias Schiffer { 518af2d1b52SMatthias Schiffer unsigned long ref_rate; 519af2d1b52SMatthias Schiffer unsigned long cpu_rate; 520af2d1b52SMatthias Schiffer unsigned long ddr_rate; 521af2d1b52SMatthias Schiffer unsigned long ahb_rate; 522af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; 523af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 524af2d1b52SMatthias Schiffer u32 bootstrap; 525af2d1b52SMatthias Schiffer 526af2d1b52SMatthias Schiffer /* 527af2d1b52SMatthias Schiffer * QCA956x timer init workaround has to be applied right before setting 528af2d1b52SMatthias Schiffer * up the clock. Else, there will be no jiffies 529af2d1b52SMatthias Schiffer */ 530af2d1b52SMatthias Schiffer u32 misc; 531af2d1b52SMatthias Schiffer 532af2d1b52SMatthias Schiffer misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); 533af2d1b52SMatthias Schiffer misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; 534af2d1b52SMatthias Schiffer ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); 535af2d1b52SMatthias Schiffer 536af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); 537af2d1b52SMatthias Schiffer if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) 538af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 539af2d1b52SMatthias Schiffer else 540af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 541af2d1b52SMatthias Schiffer 5428e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 5438e641752SFelix Fietkau 5449aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); 545af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 546af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 547af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 548af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 549af2d1b52SMatthias Schiffer 5509aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); 551af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 552af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 553af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 554af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; 555af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & 556af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; 557af2d1b52SMatthias Schiffer 558af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 559af2d1b52SMatthias Schiffer cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 560af2d1b52SMatthias Schiffer cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 561af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 562af2d1b52SMatthias Schiffer 5639aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); 564af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 565af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 566af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 567af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 5689aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); 569af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 570af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 571af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 572af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; 573af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & 574af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; 575af2d1b52SMatthias Schiffer 576af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 577af2d1b52SMatthias Schiffer ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 578af2d1b52SMatthias Schiffer ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 579af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 580af2d1b52SMatthias Schiffer 5819aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); 582af2d1b52SMatthias Schiffer 583af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 584af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 585af2d1b52SMatthias Schiffer 586af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 587af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 588af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) 589af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 590af2d1b52SMatthias Schiffer else 591af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 592af2d1b52SMatthias Schiffer 593af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 594af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 595af2d1b52SMatthias Schiffer 596af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 597af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 598af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) 599af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 600af2d1b52SMatthias Schiffer else 601af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 602af2d1b52SMatthias Schiffer 603af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 604af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 605af2d1b52SMatthias Schiffer 606af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 607af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 608af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 609af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 610af2d1b52SMatthias Schiffer else 611af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 612af2d1b52SMatthias Schiffer 6139b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 6149b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 6159b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 616af2d1b52SMatthias Schiffer } 617af2d1b52SMatthias Schiffer 6186451af02SAlban Bedel static void __init ath79_clocks_init_dt(struct device_node *np) 6196451af02SAlban Bedel { 6203bdf1071SAntony Pavlov struct clk *ref_clk; 6213bdf1071SAntony Pavlov void __iomem *pll_base; 6223bdf1071SAntony Pavlov 6233bdf1071SAntony Pavlov ref_clk = of_clk_get(np, 0); 6248e641752SFelix Fietkau if (!IS_ERR(ref_clk)) 6258e641752SFelix Fietkau clks[ATH79_CLK_REF] = ref_clk; 6263bdf1071SAntony Pavlov 6273bdf1071SAntony Pavlov pll_base = of_iomap(np, 0); 6283bdf1071SAntony Pavlov if (!pll_base) { 6297f27b5b8SRob Herring pr_err("%pOF: can't map pll registers\n", np); 6303bdf1071SAntony Pavlov goto err_clk; 6313bdf1071SAntony Pavlov } 6323bdf1071SAntony Pavlov 633e7eea04dSFelix Fietkau if (of_device_is_compatible(np, "qca,ar7100-pll")) 634e7eea04dSFelix Fietkau ar71xx_clocks_init(pll_base); 635e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,ar7240-pll") || 636e7eea04dSFelix Fietkau of_device_is_compatible(np, "qca,ar9130-pll")) 6378e641752SFelix Fietkau ar724x_clocks_init(pll_base); 6385ae5c452SAntony Pavlov else if (of_device_is_compatible(np, "qca,ar9330-pll")) 6398e641752SFelix Fietkau ar933x_clocks_init(pll_base); 640e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,ar9340-pll")) 641e7eea04dSFelix Fietkau ar934x_clocks_init(pll_base); 642e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9530-pll")) 643e7eea04dSFelix Fietkau qca953x_clocks_init(pll_base); 644e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9550-pll")) 645e7eea04dSFelix Fietkau qca955x_clocks_init(pll_base); 646e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9560-pll")) 647e7eea04dSFelix Fietkau qca956x_clocks_init(pll_base); 6483bdf1071SAntony Pavlov 6496810ed32SFelix Fietkau if (!clks[ATH79_CLK_MDIO]) 6506810ed32SFelix Fietkau clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF]; 6516810ed32SFelix Fietkau 6523bdf1071SAntony Pavlov if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 6537f27b5b8SRob Herring pr_err("%pOF: could not register clk provider\n", np); 654b3d91db3SArvind Yadav goto err_iounmap; 6553bdf1071SAntony Pavlov } 6563bdf1071SAntony Pavlov 6573bdf1071SAntony Pavlov return; 6583bdf1071SAntony Pavlov 659b3d91db3SArvind Yadav err_iounmap: 660b3d91db3SArvind Yadav iounmap(pll_base); 661b3d91db3SArvind Yadav 6623bdf1071SAntony Pavlov err_clk: 6633bdf1071SAntony Pavlov clk_put(ref_clk); 6643bdf1071SAntony Pavlov } 665e7eea04dSFelix Fietkau 666e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); 667e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); 668e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); 669e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); 670e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); 671e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); 672e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); 673e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); 674