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", 45*6810ed32SFelix Fietkau [ATH79_CLK_MDIO] = "mdio", 469b56e0d0SFelix Fietkau }; 479b56e0d0SFelix Fietkau 489b56e0d0SFelix Fietkau static const char * __init ath79_clk_name(int type) 492c4f1ac5SGabor Juhos { 509b56e0d0SFelix Fietkau BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); 519b56e0d0SFelix Fietkau return clk_names[type]; 529b56e0d0SFelix Fietkau } 532c4f1ac5SGabor Juhos 549b56e0d0SFelix Fietkau static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) 559b56e0d0SFelix Fietkau { 5620d6f0c3SChristophe JAILLET if (IS_ERR(clk)) 579b56e0d0SFelix Fietkau panic("failed to allocate %s clock structure", clk_names[type]); 582c4f1ac5SGabor Juhos 599b56e0d0SFelix Fietkau clks[type] = clk; 609b56e0d0SFelix Fietkau clk_register_clkdev(clk, name, NULL); 619b56e0d0SFelix Fietkau } 626451af02SAlban Bedel 639b56e0d0SFelix Fietkau static struct clk * __init ath79_set_clk(int type, unsigned long rate) 649b56e0d0SFelix Fietkau { 659b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 669b56e0d0SFelix Fietkau struct clk *clk; 679b56e0d0SFelix Fietkau 689b56e0d0SFelix Fietkau clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); 699b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 709b56e0d0SFelix Fietkau return clk; 719b56e0d0SFelix Fietkau } 729b56e0d0SFelix Fietkau 739b56e0d0SFelix Fietkau static struct clk * __init ath79_set_ff_clk(int type, const char *parent, 749b56e0d0SFelix Fietkau unsigned int mult, unsigned int div) 759b56e0d0SFelix Fietkau { 769b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 779b56e0d0SFelix Fietkau struct clk *clk; 789b56e0d0SFelix Fietkau 799b56e0d0SFelix Fietkau clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); 809b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 816451af02SAlban Bedel return clk; 822c4f1ac5SGabor Juhos } 83d4a67d9dSGabor Juhos 848e641752SFelix Fietkau static unsigned long __init ath79_setup_ref_clk(unsigned long rate) 858e641752SFelix Fietkau { 868e641752SFelix Fietkau struct clk *clk = clks[ATH79_CLK_REF]; 878e641752SFelix Fietkau 888e641752SFelix Fietkau if (clk) 898e641752SFelix Fietkau rate = clk_get_rate(clk); 908e641752SFelix Fietkau else 918e641752SFelix Fietkau clk = ath79_set_clk(ATH79_CLK_REF, rate); 928e641752SFelix Fietkau 938e641752SFelix Fietkau return rate; 948e641752SFelix Fietkau } 958e641752SFelix Fietkau 969aca5cb5SFelix Fietkau static void __init ar71xx_clocks_init(void __iomem *pll_base) 97d4a67d9dSGabor Juhos { 986612a688SGabor Juhos unsigned long ref_rate; 996612a688SGabor Juhos unsigned long cpu_rate; 1006612a688SGabor Juhos unsigned long ddr_rate; 1016612a688SGabor Juhos unsigned long ahb_rate; 102d4a67d9dSGabor Juhos u32 pll; 103d4a67d9dSGabor Juhos u32 freq; 104d4a67d9dSGabor Juhos u32 div; 105d4a67d9dSGabor Juhos 1068e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); 107d4a67d9dSGabor Juhos 1089aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); 109d4a67d9dSGabor Juhos 110626a0695SAlban Bedel div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; 1116612a688SGabor Juhos freq = div * ref_rate; 112d4a67d9dSGabor Juhos 113d4a67d9dSGabor Juhos div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 1146612a688SGabor Juhos cpu_rate = freq / div; 115d4a67d9dSGabor Juhos 116d4a67d9dSGabor Juhos div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 1176612a688SGabor Juhos ddr_rate = freq / div; 118d4a67d9dSGabor Juhos 119d4a67d9dSGabor Juhos div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 1206612a688SGabor Juhos ahb_rate = cpu_rate / div; 1216612a688SGabor Juhos 1229b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 1239b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 1249b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 125d4a67d9dSGabor Juhos } 126d4a67d9dSGabor Juhos 1278e641752SFelix Fietkau static void __init ar724x_clocks_init(void __iomem *pll_base) 1283bdf1071SAntony Pavlov { 1293bdf1071SAntony Pavlov u32 mult, div, ddr_div, ahb_div; 1308e641752SFelix Fietkau u32 pll; 1318e641752SFelix Fietkau 1328e641752SFelix Fietkau ath79_setup_ref_clk(AR71XX_BASE_FREQ); 1333bdf1071SAntony Pavlov 1343bdf1071SAntony Pavlov pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 1353bdf1071SAntony Pavlov 1363bdf1071SAntony Pavlov mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 1373bdf1071SAntony Pavlov div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 1383bdf1071SAntony Pavlov 1393bdf1071SAntony Pavlov ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 1403bdf1071SAntony Pavlov ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 1413bdf1071SAntony Pavlov 1429b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); 1439b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); 1449b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); 1453bdf1071SAntony Pavlov } 1463bdf1071SAntony Pavlov 1478e641752SFelix Fietkau static void __init ar933x_clocks_init(void __iomem *pll_base) 148d4a67d9dSGabor Juhos { 1498e641752SFelix Fietkau unsigned long ref_rate; 1505ae5c452SAntony Pavlov u32 clock_ctrl; 1515ae5c452SAntony Pavlov u32 ref_div; 1525ae5c452SAntony Pavlov u32 ninit_mul; 1535ae5c452SAntony Pavlov u32 out_div; 1545ae5c452SAntony Pavlov 1555ae5c452SAntony Pavlov u32 cpu_div; 1565ae5c452SAntony Pavlov u32 ddr_div; 1575ae5c452SAntony Pavlov u32 ahb_div; 1588e641752SFelix Fietkau u32 t; 1598e641752SFelix Fietkau 1608e641752SFelix Fietkau t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 1618e641752SFelix Fietkau if (t & AR933X_BOOTSTRAP_REF_CLK_40) 1628e641752SFelix Fietkau ref_rate = (40 * 1000 * 1000); 1638e641752SFelix Fietkau else 1648e641752SFelix Fietkau ref_rate = (25 * 1000 * 1000); 1658e641752SFelix Fietkau 1668e641752SFelix Fietkau ath79_setup_ref_clk(ref_rate); 1675ae5c452SAntony Pavlov 1685ae5c452SAntony Pavlov clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 1695ae5c452SAntony Pavlov if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 1705ae5c452SAntony Pavlov ref_div = 1; 1715ae5c452SAntony Pavlov ninit_mul = 1; 1725ae5c452SAntony Pavlov out_div = 1; 1735ae5c452SAntony Pavlov 1745ae5c452SAntony Pavlov cpu_div = 1; 1755ae5c452SAntony Pavlov ddr_div = 1; 1765ae5c452SAntony Pavlov ahb_div = 1; 1775ae5c452SAntony Pavlov } else { 1785ae5c452SAntony Pavlov u32 cpu_config; 1795ae5c452SAntony Pavlov u32 t; 1805ae5c452SAntony Pavlov 1815ae5c452SAntony Pavlov cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); 1825ae5c452SAntony Pavlov 1835ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 1845ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 1855ae5c452SAntony Pavlov ref_div = t; 1865ae5c452SAntony Pavlov 1875ae5c452SAntony Pavlov ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 1885ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_NINT_MASK; 1895ae5c452SAntony Pavlov 1905ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 1915ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 1925ae5c452SAntony Pavlov if (t == 0) 1935ae5c452SAntony Pavlov t = 1; 1945ae5c452SAntony Pavlov 1955ae5c452SAntony Pavlov out_div = (1 << t); 1965ae5c452SAntony Pavlov 1975ae5c452SAntony Pavlov cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 1985ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 1995ae5c452SAntony Pavlov 2005ae5c452SAntony Pavlov ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 2015ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 2025ae5c452SAntony Pavlov 2035ae5c452SAntony Pavlov ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 2045ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 2055ae5c452SAntony Pavlov } 2065ae5c452SAntony Pavlov 2079b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, 2089b56e0d0SFelix Fietkau ref_div * out_div * cpu_div); 2099b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, 2109b56e0d0SFelix Fietkau ref_div * out_div * ddr_div); 2119b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, 2129b56e0d0SFelix Fietkau ref_div * out_div * ahb_div); 2135ae5c452SAntony Pavlov } 2145ae5c452SAntony Pavlov 21597541ccfSGabor Juhos static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 21697541ccfSGabor Juhos u32 frac, u32 out_div) 21797541ccfSGabor Juhos { 21897541ccfSGabor Juhos u64 t; 21997541ccfSGabor Juhos u32 ret; 22097541ccfSGabor Juhos 221837f036cSGabor Juhos t = ref; 22297541ccfSGabor Juhos t *= nint; 22397541ccfSGabor Juhos do_div(t, ref_div); 22497541ccfSGabor Juhos ret = t; 22597541ccfSGabor Juhos 226837f036cSGabor Juhos t = ref; 22797541ccfSGabor Juhos t *= nfrac; 22897541ccfSGabor Juhos do_div(t, ref_div * frac); 22997541ccfSGabor Juhos ret += t; 23097541ccfSGabor Juhos 23197541ccfSGabor Juhos ret /= (1 << out_div); 23297541ccfSGabor Juhos return ret; 23397541ccfSGabor Juhos } 23497541ccfSGabor Juhos 2359aca5cb5SFelix Fietkau static void __init ar934x_clocks_init(void __iomem *pll_base) 2368889612bSGabor Juhos { 2376612a688SGabor Juhos unsigned long ref_rate; 2386612a688SGabor Juhos unsigned long cpu_rate; 2396612a688SGabor Juhos unsigned long ddr_rate; 2406612a688SGabor Juhos unsigned long ahb_rate; 24197541ccfSGabor Juhos u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 2428889612bSGabor Juhos u32 cpu_pll, ddr_pll; 2438889612bSGabor Juhos u32 bootstrap; 24497541ccfSGabor Juhos void __iomem *dpll_base; 24597541ccfSGabor Juhos 24697541ccfSGabor Juhos dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 2478889612bSGabor Juhos 2488889612bSGabor Juhos bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 2498889612bSGabor Juhos if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 2506612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 2518889612bSGabor Juhos else 2526612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 2538889612bSGabor Juhos 2548e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 2558e641752SFelix Fietkau 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 { 2689aca5cb5SFelix 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 { 2959aca5cb5SFelix 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 3109aca5cb5SFelix 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_CPU, cpu_rate); 3439b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 3449b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 3458889612bSGabor Juhos 346*6810ed32SFelix Fietkau clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); 347*6810ed32SFelix Fietkau if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) 348*6810ed32SFelix Fietkau ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); 349*6810ed32SFelix Fietkau 35097541ccfSGabor Juhos iounmap(dpll_base); 3518889612bSGabor Juhos } 3528889612bSGabor Juhos 3539aca5cb5SFelix Fietkau static void __init qca953x_clocks_init(void __iomem *pll_base) 354af2d1b52SMatthias Schiffer { 355af2d1b52SMatthias Schiffer unsigned long ref_rate; 356af2d1b52SMatthias Schiffer unsigned long cpu_rate; 357af2d1b52SMatthias Schiffer unsigned long ddr_rate; 358af2d1b52SMatthias Schiffer unsigned long ahb_rate; 359af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 360af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 361af2d1b52SMatthias Schiffer u32 bootstrap; 362af2d1b52SMatthias Schiffer 363af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); 364af2d1b52SMatthias Schiffer if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) 365af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 366af2d1b52SMatthias Schiffer else 367af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 368af2d1b52SMatthias Schiffer 3698e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 3708e641752SFelix Fietkau 3719aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); 372af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 373af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 374af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 375af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; 376af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & 377af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NINT_MASK; 378af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 379af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; 380af2d1b52SMatthias Schiffer 381af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 382af2d1b52SMatthias Schiffer cpu_pll += frac * (ref_rate >> 6) / ref_div; 383af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 384af2d1b52SMatthias Schiffer 3859aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); 386af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 387af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 388af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 389af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; 390af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & 391af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NINT_MASK; 392af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 393af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; 394af2d1b52SMatthias Schiffer 395af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 396af2d1b52SMatthias Schiffer ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 397af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 398af2d1b52SMatthias Schiffer 3999aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); 400af2d1b52SMatthias Schiffer 401af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 402af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 403af2d1b52SMatthias Schiffer 404af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 405af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 406af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 407af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 408af2d1b52SMatthias Schiffer else 409af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 410af2d1b52SMatthias Schiffer 411af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 412af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 413af2d1b52SMatthias Schiffer 414af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 415af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 416af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 417af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 418af2d1b52SMatthias Schiffer else 419af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 420af2d1b52SMatthias Schiffer 421af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 422af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 423af2d1b52SMatthias Schiffer 424af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 425af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 426af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 427af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 428af2d1b52SMatthias Schiffer else 429af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 430af2d1b52SMatthias Schiffer 4319b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 4329b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 4339b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 434af2d1b52SMatthias Schiffer } 435af2d1b52SMatthias Schiffer 4369aca5cb5SFelix Fietkau static void __init qca955x_clocks_init(void __iomem *pll_base) 43741583c05SGabor Juhos { 4386612a688SGabor Juhos unsigned long ref_rate; 4396612a688SGabor Juhos unsigned long cpu_rate; 4406612a688SGabor Juhos unsigned long ddr_rate; 4416612a688SGabor Juhos unsigned long ahb_rate; 44241583c05SGabor Juhos u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 44341583c05SGabor Juhos u32 cpu_pll, ddr_pll; 44441583c05SGabor Juhos u32 bootstrap; 44541583c05SGabor Juhos 44641583c05SGabor Juhos bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 44741583c05SGabor Juhos if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 4486612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 44941583c05SGabor Juhos else 4506612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 45141583c05SGabor Juhos 4528e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 4538e641752SFelix Fietkau 4549aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); 45541583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 45641583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 45741583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 45841583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 45941583c05SGabor Juhos nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 46041583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NINT_MASK; 46141583c05SGabor Juhos frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 46241583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 46341583c05SGabor Juhos 4646612a688SGabor Juhos cpu_pll = nint * ref_rate / ref_div; 4656612a688SGabor Juhos cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 46641583c05SGabor Juhos cpu_pll /= (1 << out_div); 46741583c05SGabor Juhos 4689aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); 46941583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 47041583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 47141583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 47241583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 47341583c05SGabor Juhos nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 47441583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NINT_MASK; 47541583c05SGabor Juhos frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 47641583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 47741583c05SGabor Juhos 4786612a688SGabor Juhos ddr_pll = nint * ref_rate / ref_div; 4796612a688SGabor Juhos ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 48041583c05SGabor Juhos ddr_pll /= (1 << out_div); 48141583c05SGabor Juhos 4829aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); 48341583c05SGabor Juhos 48441583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 48541583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 48641583c05SGabor Juhos 48741583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 4886612a688SGabor Juhos cpu_rate = ref_rate; 48941583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 4906612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 49141583c05SGabor Juhos else 4926612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 49341583c05SGabor Juhos 49441583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 49541583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 49641583c05SGabor Juhos 49741583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 4986612a688SGabor Juhos ddr_rate = ref_rate; 49941583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 5006612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 50141583c05SGabor Juhos else 5026612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 50341583c05SGabor Juhos 50441583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 50541583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 50641583c05SGabor Juhos 50741583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 5086612a688SGabor Juhos ahb_rate = ref_rate; 50941583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 5106612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 51141583c05SGabor Juhos else 5126612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 5136612a688SGabor Juhos 5149b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 5159b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 5169b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 51741583c05SGabor Juhos } 51841583c05SGabor Juhos 5199aca5cb5SFelix Fietkau static void __init qca956x_clocks_init(void __iomem *pll_base) 520af2d1b52SMatthias Schiffer { 521af2d1b52SMatthias Schiffer unsigned long ref_rate; 522af2d1b52SMatthias Schiffer unsigned long cpu_rate; 523af2d1b52SMatthias Schiffer unsigned long ddr_rate; 524af2d1b52SMatthias Schiffer unsigned long ahb_rate; 525af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; 526af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 527af2d1b52SMatthias Schiffer u32 bootstrap; 528af2d1b52SMatthias Schiffer 529af2d1b52SMatthias Schiffer /* 530af2d1b52SMatthias Schiffer * QCA956x timer init workaround has to be applied right before setting 531af2d1b52SMatthias Schiffer * up the clock. Else, there will be no jiffies 532af2d1b52SMatthias Schiffer */ 533af2d1b52SMatthias Schiffer u32 misc; 534af2d1b52SMatthias Schiffer 535af2d1b52SMatthias Schiffer misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); 536af2d1b52SMatthias Schiffer misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; 537af2d1b52SMatthias Schiffer ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); 538af2d1b52SMatthias Schiffer 539af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); 540af2d1b52SMatthias Schiffer if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) 541af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 542af2d1b52SMatthias Schiffer else 543af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 544af2d1b52SMatthias Schiffer 5458e641752SFelix Fietkau ref_rate = ath79_setup_ref_clk(ref_rate); 5468e641752SFelix Fietkau 5479aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); 548af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 549af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 550af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 551af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 552af2d1b52SMatthias Schiffer 5539aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); 554af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 555af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 556af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 557af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; 558af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & 559af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; 560af2d1b52SMatthias Schiffer 561af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 562af2d1b52SMatthias Schiffer cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 563af2d1b52SMatthias Schiffer cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 564af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 565af2d1b52SMatthias Schiffer 5669aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); 567af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 568af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 569af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 570af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 5719aca5cb5SFelix Fietkau pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); 572af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 573af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 574af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 575af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; 576af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & 577af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; 578af2d1b52SMatthias Schiffer 579af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 580af2d1b52SMatthias Schiffer ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 581af2d1b52SMatthias Schiffer ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 582af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 583af2d1b52SMatthias Schiffer 5849aca5cb5SFelix Fietkau clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); 585af2d1b52SMatthias Schiffer 586af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 587af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 588af2d1b52SMatthias Schiffer 589af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 590af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 591af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) 592af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 593af2d1b52SMatthias Schiffer else 594af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 595af2d1b52SMatthias Schiffer 596af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 597af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 598af2d1b52SMatthias Schiffer 599af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 600af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 601af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) 602af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 603af2d1b52SMatthias Schiffer else 604af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 605af2d1b52SMatthias Schiffer 606af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 607af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 608af2d1b52SMatthias Schiffer 609af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 610af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 611af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 612af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 613af2d1b52SMatthias Schiffer else 614af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 615af2d1b52SMatthias Schiffer 6169b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 6179b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 6189b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 619af2d1b52SMatthias Schiffer } 620af2d1b52SMatthias Schiffer 621d4a67d9dSGabor Juhos void __init ath79_clocks_init(void) 622d4a67d9dSGabor Juhos { 6234a0e89b9SFelix Fietkau const char *wdt; 6244a0e89b9SFelix Fietkau const char *uart; 6254a0e89b9SFelix Fietkau 626d4a67d9dSGabor Juhos if (soc_is_ar71xx()) 6279aca5cb5SFelix Fietkau ar71xx_clocks_init(ath79_pll_base); 628f4c87b7aSAlban Bedel else if (soc_is_ar724x() || soc_is_ar913x()) 6299aca5cb5SFelix Fietkau ar724x_clocks_init(ath79_pll_base); 63004225e1dSGabor Juhos else if (soc_is_ar933x()) 6319aca5cb5SFelix Fietkau ar933x_clocks_init(ath79_pll_base); 6328889612bSGabor Juhos else if (soc_is_ar934x()) 6339aca5cb5SFelix Fietkau ar934x_clocks_init(ath79_pll_base); 634af2d1b52SMatthias Schiffer else if (soc_is_qca953x()) 6359aca5cb5SFelix Fietkau qca953x_clocks_init(ath79_pll_base); 63641583c05SGabor Juhos else if (soc_is_qca955x()) 6379aca5cb5SFelix Fietkau qca955x_clocks_init(ath79_pll_base); 638af2d1b52SMatthias Schiffer else if (soc_is_qca956x() || soc_is_tp9343()) 6399aca5cb5SFelix Fietkau qca956x_clocks_init(ath79_pll_base); 640d4a67d9dSGabor Juhos else 641d4a67d9dSGabor Juhos BUG(); 6424a0e89b9SFelix Fietkau 6434a0e89b9SFelix Fietkau if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x()) { 6444a0e89b9SFelix Fietkau wdt = "ahb"; 6454a0e89b9SFelix Fietkau uart = "ahb"; 6464a0e89b9SFelix Fietkau } else if (soc_is_ar933x()) { 6474a0e89b9SFelix Fietkau wdt = "ahb"; 6484a0e89b9SFelix Fietkau uart = "ref"; 6494a0e89b9SFelix Fietkau } else { 6504a0e89b9SFelix Fietkau wdt = "ref"; 6514a0e89b9SFelix Fietkau uart = "ref"; 6524a0e89b9SFelix Fietkau } 6534a0e89b9SFelix Fietkau 6544a0e89b9SFelix Fietkau clk_add_alias("wdt", NULL, wdt, NULL); 6554a0e89b9SFelix Fietkau clk_add_alias("uart", NULL, uart, NULL); 656d4a67d9dSGabor Juhos } 657d4a67d9dSGabor Juhos 65823107802SGabor Juhos unsigned long __init 65923107802SGabor Juhos ath79_get_sys_clk_rate(const char *id) 66023107802SGabor Juhos { 66123107802SGabor Juhos struct clk *clk; 66223107802SGabor Juhos unsigned long rate; 66323107802SGabor Juhos 66423107802SGabor Juhos clk = clk_get(NULL, id); 66523107802SGabor Juhos if (IS_ERR(clk)) 66623107802SGabor Juhos panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); 66723107802SGabor Juhos 66823107802SGabor Juhos rate = clk_get_rate(clk); 66923107802SGabor Juhos clk_put(clk); 67023107802SGabor Juhos 67123107802SGabor Juhos return rate; 67223107802SGabor Juhos } 6736451af02SAlban Bedel 6746451af02SAlban Bedel #ifdef CONFIG_OF 6756451af02SAlban Bedel static void __init ath79_clocks_init_dt(struct device_node *np) 6766451af02SAlban Bedel { 6773bdf1071SAntony Pavlov struct clk *ref_clk; 6783bdf1071SAntony Pavlov void __iomem *pll_base; 6793bdf1071SAntony Pavlov 6803bdf1071SAntony Pavlov ref_clk = of_clk_get(np, 0); 6818e641752SFelix Fietkau if (!IS_ERR(ref_clk)) 6828e641752SFelix Fietkau clks[ATH79_CLK_REF] = ref_clk; 6833bdf1071SAntony Pavlov 6843bdf1071SAntony Pavlov pll_base = of_iomap(np, 0); 6853bdf1071SAntony Pavlov if (!pll_base) { 6867f27b5b8SRob Herring pr_err("%pOF: can't map pll registers\n", np); 6873bdf1071SAntony Pavlov goto err_clk; 6883bdf1071SAntony Pavlov } 6893bdf1071SAntony Pavlov 690e7eea04dSFelix Fietkau if (of_device_is_compatible(np, "qca,ar7100-pll")) 691e7eea04dSFelix Fietkau ar71xx_clocks_init(pll_base); 692e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,ar7240-pll") || 693e7eea04dSFelix Fietkau of_device_is_compatible(np, "qca,ar9130-pll")) 6948e641752SFelix Fietkau ar724x_clocks_init(pll_base); 6955ae5c452SAntony Pavlov else if (of_device_is_compatible(np, "qca,ar9330-pll")) 6968e641752SFelix Fietkau ar933x_clocks_init(pll_base); 697e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,ar9340-pll")) 698e7eea04dSFelix Fietkau ar934x_clocks_init(pll_base); 699e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9530-pll")) 700e7eea04dSFelix Fietkau qca953x_clocks_init(pll_base); 701e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9550-pll")) 702e7eea04dSFelix Fietkau qca955x_clocks_init(pll_base); 703e7eea04dSFelix Fietkau else if (of_device_is_compatible(np, "qca,qca9560-pll")) 704e7eea04dSFelix Fietkau qca956x_clocks_init(pll_base); 7053bdf1071SAntony Pavlov 706*6810ed32SFelix Fietkau if (!clks[ATH79_CLK_MDIO]) 707*6810ed32SFelix Fietkau clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF]; 708*6810ed32SFelix Fietkau 7093bdf1071SAntony Pavlov if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 7107f27b5b8SRob Herring pr_err("%pOF: could not register clk provider\n", np); 711b3d91db3SArvind Yadav goto err_iounmap; 7123bdf1071SAntony Pavlov } 7133bdf1071SAntony Pavlov 7143bdf1071SAntony Pavlov return; 7153bdf1071SAntony Pavlov 716b3d91db3SArvind Yadav err_iounmap: 717b3d91db3SArvind Yadav iounmap(pll_base); 718b3d91db3SArvind Yadav 7193bdf1071SAntony Pavlov err_clk: 7203bdf1071SAntony Pavlov clk_put(ref_clk); 7213bdf1071SAntony Pavlov } 722e7eea04dSFelix Fietkau 723e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); 724e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); 725e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); 726e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); 727e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); 728e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); 729e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); 730e7eea04dSFelix Fietkau CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); 731e7eea04dSFelix Fietkau 7326451af02SAlban Bedel #endif 733