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 40*9b56e0d0SFelix Fietkau static const char * const clk_names[ATH79_CLK_END] = { 41*9b56e0d0SFelix Fietkau [ATH79_CLK_CPU] = "cpu", 42*9b56e0d0SFelix Fietkau [ATH79_CLK_DDR] = "ddr", 43*9b56e0d0SFelix Fietkau [ATH79_CLK_AHB] = "ahb", 44*9b56e0d0SFelix Fietkau [ATH79_CLK_REF] = "ref", 45*9b56e0d0SFelix Fietkau }; 46*9b56e0d0SFelix Fietkau 47*9b56e0d0SFelix Fietkau static const char * __init ath79_clk_name(int type) 482c4f1ac5SGabor Juhos { 49*9b56e0d0SFelix Fietkau BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); 50*9b56e0d0SFelix Fietkau return clk_names[type]; 51*9b56e0d0SFelix Fietkau } 522c4f1ac5SGabor Juhos 53*9b56e0d0SFelix Fietkau static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) 54*9b56e0d0SFelix Fietkau { 5520d6f0c3SChristophe JAILLET if (IS_ERR(clk)) 56*9b56e0d0SFelix Fietkau panic("failed to allocate %s clock structure", clk_names[type]); 572c4f1ac5SGabor Juhos 58*9b56e0d0SFelix Fietkau clks[type] = clk; 59*9b56e0d0SFelix Fietkau clk_register_clkdev(clk, name, NULL); 60*9b56e0d0SFelix Fietkau } 616451af02SAlban Bedel 62*9b56e0d0SFelix Fietkau static struct clk * __init ath79_set_clk(int type, unsigned long rate) 63*9b56e0d0SFelix Fietkau { 64*9b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 65*9b56e0d0SFelix Fietkau struct clk *clk; 66*9b56e0d0SFelix Fietkau 67*9b56e0d0SFelix Fietkau clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); 68*9b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 69*9b56e0d0SFelix Fietkau return clk; 70*9b56e0d0SFelix Fietkau } 71*9b56e0d0SFelix Fietkau 72*9b56e0d0SFelix Fietkau static struct clk * __init ath79_set_ff_clk(int type, const char *parent, 73*9b56e0d0SFelix Fietkau unsigned int mult, unsigned int div) 74*9b56e0d0SFelix Fietkau { 75*9b56e0d0SFelix Fietkau const char *name = ath79_clk_name(type); 76*9b56e0d0SFelix Fietkau struct clk *clk; 77*9b56e0d0SFelix Fietkau 78*9b56e0d0SFelix Fietkau clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); 79*9b56e0d0SFelix Fietkau __ath79_set_clk(type, name, clk); 806451af02SAlban Bedel return clk; 812c4f1ac5SGabor Juhos } 82d4a67d9dSGabor Juhos 83d4a67d9dSGabor Juhos static void __init ar71xx_clocks_init(void) 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 95d4a67d9dSGabor Juhos pll = ath79_pll_rr(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 109*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 110*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 111*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 112*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 113d4a67d9dSGabor Juhos 1142c4f1ac5SGabor Juhos clk_add_alias("wdt", NULL, "ahb", NULL); 1152c4f1ac5SGabor Juhos clk_add_alias("uart", NULL, "ahb", NULL); 116d4a67d9dSGabor Juhos } 117d4a67d9dSGabor Juhos 1183bdf1071SAntony Pavlov static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) 1193bdf1071SAntony Pavlov { 1203bdf1071SAntony Pavlov u32 pll; 1213bdf1071SAntony Pavlov u32 mult, div, ddr_div, ahb_div; 1223bdf1071SAntony Pavlov 1233bdf1071SAntony Pavlov pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 1243bdf1071SAntony Pavlov 1253bdf1071SAntony Pavlov mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 1263bdf1071SAntony Pavlov div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 1273bdf1071SAntony Pavlov 1283bdf1071SAntony Pavlov ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 1293bdf1071SAntony Pavlov ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 1303bdf1071SAntony Pavlov 131*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); 132*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); 133*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); 1343bdf1071SAntony Pavlov } 1353bdf1071SAntony Pavlov 136d4a67d9dSGabor Juhos static void __init ar724x_clocks_init(void) 137d4a67d9dSGabor Juhos { 1383bdf1071SAntony Pavlov struct clk *ref_clk; 139d4a67d9dSGabor Juhos 140*9b56e0d0SFelix Fietkau ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); 141d4a67d9dSGabor Juhos 1423bdf1071SAntony Pavlov ar724x_clk_init(ref_clk, ath79_pll_base); 143d4a67d9dSGabor Juhos 1442c4f1ac5SGabor Juhos clk_add_alias("wdt", NULL, "ahb", NULL); 1452c4f1ac5SGabor Juhos clk_add_alias("uart", NULL, "ahb", NULL); 146d4a67d9dSGabor Juhos } 147d4a67d9dSGabor Juhos 1485ae5c452SAntony Pavlov static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) 1495ae5c452SAntony Pavlov { 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; 1585ae5c452SAntony Pavlov 1595ae5c452SAntony Pavlov clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 1605ae5c452SAntony Pavlov if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 1615ae5c452SAntony Pavlov ref_div = 1; 1625ae5c452SAntony Pavlov ninit_mul = 1; 1635ae5c452SAntony Pavlov out_div = 1; 1645ae5c452SAntony Pavlov 1655ae5c452SAntony Pavlov cpu_div = 1; 1665ae5c452SAntony Pavlov ddr_div = 1; 1675ae5c452SAntony Pavlov ahb_div = 1; 1685ae5c452SAntony Pavlov } else { 1695ae5c452SAntony Pavlov u32 cpu_config; 1705ae5c452SAntony Pavlov u32 t; 1715ae5c452SAntony Pavlov 1725ae5c452SAntony Pavlov cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); 1735ae5c452SAntony Pavlov 1745ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 1755ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 1765ae5c452SAntony Pavlov ref_div = t; 1775ae5c452SAntony Pavlov 1785ae5c452SAntony Pavlov ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 1795ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_NINT_MASK; 1805ae5c452SAntony Pavlov 1815ae5c452SAntony Pavlov t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 1825ae5c452SAntony Pavlov AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 1835ae5c452SAntony Pavlov if (t == 0) 1845ae5c452SAntony Pavlov t = 1; 1855ae5c452SAntony Pavlov 1865ae5c452SAntony Pavlov out_div = (1 << t); 1875ae5c452SAntony Pavlov 1885ae5c452SAntony Pavlov cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 1895ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 1905ae5c452SAntony Pavlov 1915ae5c452SAntony Pavlov ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 1925ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 1935ae5c452SAntony Pavlov 1945ae5c452SAntony Pavlov ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 1955ae5c452SAntony Pavlov AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 1965ae5c452SAntony Pavlov } 1975ae5c452SAntony Pavlov 198*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, 199*9b56e0d0SFelix Fietkau ref_div * out_div * cpu_div); 200*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, 201*9b56e0d0SFelix Fietkau ref_div * out_div * ddr_div); 202*9b56e0d0SFelix Fietkau ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, 203*9b56e0d0SFelix Fietkau ref_div * out_div * ahb_div); 2045ae5c452SAntony Pavlov } 2055ae5c452SAntony Pavlov 20604225e1dSGabor Juhos static void __init ar933x_clocks_init(void) 20704225e1dSGabor Juhos { 2085ae5c452SAntony Pavlov struct clk *ref_clk; 2096612a688SGabor Juhos unsigned long ref_rate; 21004225e1dSGabor Juhos u32 t; 21104225e1dSGabor Juhos 21204225e1dSGabor Juhos t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 21304225e1dSGabor Juhos if (t & AR933X_BOOTSTRAP_REF_CLK_40) 2146612a688SGabor Juhos ref_rate = (40 * 1000 * 1000); 21504225e1dSGabor Juhos else 2166612a688SGabor Juhos ref_rate = (25 * 1000 * 1000); 21704225e1dSGabor Juhos 218*9b56e0d0SFelix Fietkau ref_clk = ath79_set_clk(ATH79_CLK_REF, ref_rate); 21904225e1dSGabor Juhos 2205ae5c452SAntony Pavlov ar9330_clk_init(ref_clk, ath79_pll_base); 22104225e1dSGabor Juhos 2222c4f1ac5SGabor Juhos clk_add_alias("wdt", NULL, "ahb", NULL); 2232c4f1ac5SGabor Juhos clk_add_alias("uart", NULL, "ref", NULL); 22404225e1dSGabor Juhos } 22504225e1dSGabor Juhos 22697541ccfSGabor Juhos static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 22797541ccfSGabor Juhos u32 frac, u32 out_div) 22897541ccfSGabor Juhos { 22997541ccfSGabor Juhos u64 t; 23097541ccfSGabor Juhos u32 ret; 23197541ccfSGabor Juhos 232837f036cSGabor Juhos t = ref; 23397541ccfSGabor Juhos t *= nint; 23497541ccfSGabor Juhos do_div(t, ref_div); 23597541ccfSGabor Juhos ret = t; 23697541ccfSGabor Juhos 237837f036cSGabor Juhos t = ref; 23897541ccfSGabor Juhos t *= nfrac; 23997541ccfSGabor Juhos do_div(t, ref_div * frac); 24097541ccfSGabor Juhos ret += t; 24197541ccfSGabor Juhos 24297541ccfSGabor Juhos ret /= (1 << out_div); 24397541ccfSGabor Juhos return ret; 24497541ccfSGabor Juhos } 24597541ccfSGabor Juhos 2468889612bSGabor Juhos static void __init ar934x_clocks_init(void) 2478889612bSGabor Juhos { 2486612a688SGabor Juhos unsigned long ref_rate; 2496612a688SGabor Juhos unsigned long cpu_rate; 2506612a688SGabor Juhos unsigned long ddr_rate; 2516612a688SGabor Juhos unsigned long ahb_rate; 25297541ccfSGabor Juhos u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 2538889612bSGabor Juhos u32 cpu_pll, ddr_pll; 2548889612bSGabor Juhos u32 bootstrap; 25597541ccfSGabor Juhos void __iomem *dpll_base; 25697541ccfSGabor Juhos 25797541ccfSGabor Juhos dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 2588889612bSGabor Juhos 2598889612bSGabor Juhos bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 2608889612bSGabor Juhos if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 2616612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 2628889612bSGabor Juhos else 2636612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 2648889612bSGabor Juhos 26597541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 26697541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 26797541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 26897541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 26997541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); 27097541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 27197541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 27297541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 27397541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 27497541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 27597541ccfSGabor Juhos frac = 1 << 18; 27697541ccfSGabor Juhos } else { 2778889612bSGabor Juhos pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); 2788889612bSGabor Juhos out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 2798889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 2808889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 2818889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 2828889612bSGabor Juhos nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 2838889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NINT_MASK; 28497541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 2858889612bSGabor Juhos AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 28697541ccfSGabor Juhos frac = 1 << 6; 28797541ccfSGabor Juhos } 2888889612bSGabor Juhos 2896612a688SGabor Juhos cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 29097541ccfSGabor Juhos nfrac, frac, out_div); 2918889612bSGabor Juhos 29297541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); 29397541ccfSGabor Juhos if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 29497541ccfSGabor Juhos out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 29597541ccfSGabor Juhos AR934X_SRIF_DPLL2_OUTDIV_MASK; 29697541ccfSGabor Juhos pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); 29797541ccfSGabor Juhos nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 29897541ccfSGabor Juhos AR934X_SRIF_DPLL1_NINT_MASK; 29997541ccfSGabor Juhos nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 30097541ccfSGabor Juhos ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 30197541ccfSGabor Juhos AR934X_SRIF_DPLL1_REFDIV_MASK; 30297541ccfSGabor Juhos frac = 1 << 18; 30397541ccfSGabor Juhos } else { 3048889612bSGabor Juhos pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); 3058889612bSGabor Juhos out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 3068889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 3078889612bSGabor Juhos ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 3088889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 3098889612bSGabor Juhos nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 3108889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NINT_MASK; 31197541ccfSGabor Juhos nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 3128889612bSGabor Juhos AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 31397541ccfSGabor Juhos frac = 1 << 10; 31497541ccfSGabor Juhos } 3158889612bSGabor Juhos 3166612a688SGabor Juhos ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 31797541ccfSGabor Juhos nfrac, frac, out_div); 3188889612bSGabor Juhos 3198889612bSGabor Juhos clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 3208889612bSGabor Juhos 3218889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 3228889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 3238889612bSGabor Juhos 3248889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 3256612a688SGabor Juhos cpu_rate = ref_rate; 3268889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 3276612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 3288889612bSGabor Juhos else 3296612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 3308889612bSGabor Juhos 3318889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 3328889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 3338889612bSGabor Juhos 3348889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 3356612a688SGabor Juhos ddr_rate = ref_rate; 3368889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 3376612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 3388889612bSGabor Juhos else 3396612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 3408889612bSGabor Juhos 3418889612bSGabor Juhos postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 3428889612bSGabor Juhos AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 3438889612bSGabor Juhos 3448889612bSGabor Juhos if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 3456612a688SGabor Juhos ahb_rate = ref_rate; 3468889612bSGabor Juhos else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 3476612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 3488889612bSGabor Juhos else 3496612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 3506612a688SGabor Juhos 351*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 352*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 353*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 354*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 3558889612bSGabor Juhos 3562c4f1ac5SGabor Juhos clk_add_alias("wdt", NULL, "ref", NULL); 3572c4f1ac5SGabor Juhos clk_add_alias("uart", NULL, "ref", NULL); 35897541ccfSGabor Juhos 35997541ccfSGabor Juhos iounmap(dpll_base); 3608889612bSGabor Juhos } 3618889612bSGabor Juhos 362af2d1b52SMatthias Schiffer static void __init qca953x_clocks_init(void) 363af2d1b52SMatthias Schiffer { 364af2d1b52SMatthias Schiffer unsigned long ref_rate; 365af2d1b52SMatthias Schiffer unsigned long cpu_rate; 366af2d1b52SMatthias Schiffer unsigned long ddr_rate; 367af2d1b52SMatthias Schiffer unsigned long ahb_rate; 368af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 369af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 370af2d1b52SMatthias Schiffer u32 bootstrap; 371af2d1b52SMatthias Schiffer 372af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); 373af2d1b52SMatthias Schiffer if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) 374af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 375af2d1b52SMatthias Schiffer else 376af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 377af2d1b52SMatthias Schiffer 378af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); 379af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 380af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 381af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 382af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; 383af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & 384af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NINT_MASK; 385af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 386af2d1b52SMatthias Schiffer QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; 387af2d1b52SMatthias Schiffer 388af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 389af2d1b52SMatthias Schiffer cpu_pll += frac * (ref_rate >> 6) / ref_div; 390af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 391af2d1b52SMatthias Schiffer 392af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); 393af2d1b52SMatthias Schiffer out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 394af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 395af2d1b52SMatthias Schiffer ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 396af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; 397af2d1b52SMatthias Schiffer nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & 398af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NINT_MASK; 399af2d1b52SMatthias Schiffer frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 400af2d1b52SMatthias Schiffer QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; 401af2d1b52SMatthias Schiffer 402af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 403af2d1b52SMatthias Schiffer ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 404af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 405af2d1b52SMatthias Schiffer 406af2d1b52SMatthias Schiffer clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); 407af2d1b52SMatthias Schiffer 408af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 409af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 410af2d1b52SMatthias Schiffer 411af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 412af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 413af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 414af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 415af2d1b52SMatthias Schiffer else 416af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 417af2d1b52SMatthias Schiffer 418af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 419af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 420af2d1b52SMatthias Schiffer 421af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 422af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 423af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 424af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 425af2d1b52SMatthias Schiffer else 426af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 427af2d1b52SMatthias Schiffer 428af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 429af2d1b52SMatthias Schiffer QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 430af2d1b52SMatthias Schiffer 431af2d1b52SMatthias Schiffer if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 432af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 433af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 434af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 435af2d1b52SMatthias Schiffer else 436af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 437af2d1b52SMatthias Schiffer 438*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 439*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 440*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 441*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 442af2d1b52SMatthias Schiffer 443af2d1b52SMatthias Schiffer clk_add_alias("wdt", NULL, "ref", NULL); 444af2d1b52SMatthias Schiffer clk_add_alias("uart", NULL, "ref", NULL); 445af2d1b52SMatthias Schiffer } 446af2d1b52SMatthias Schiffer 44741583c05SGabor Juhos static void __init qca955x_clocks_init(void) 44841583c05SGabor Juhos { 4496612a688SGabor Juhos unsigned long ref_rate; 4506612a688SGabor Juhos unsigned long cpu_rate; 4516612a688SGabor Juhos unsigned long ddr_rate; 4526612a688SGabor Juhos unsigned long ahb_rate; 45341583c05SGabor Juhos u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 45441583c05SGabor Juhos u32 cpu_pll, ddr_pll; 45541583c05SGabor Juhos u32 bootstrap; 45641583c05SGabor Juhos 45741583c05SGabor Juhos bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 45841583c05SGabor Juhos if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 4596612a688SGabor Juhos ref_rate = 40 * 1000 * 1000; 46041583c05SGabor Juhos else 4616612a688SGabor Juhos ref_rate = 25 * 1000 * 1000; 46241583c05SGabor Juhos 46341583c05SGabor Juhos pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); 46441583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 46541583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 46641583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 46741583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 46841583c05SGabor Juhos nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 46941583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NINT_MASK; 47041583c05SGabor Juhos frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 47141583c05SGabor Juhos QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 47241583c05SGabor Juhos 4736612a688SGabor Juhos cpu_pll = nint * ref_rate / ref_div; 4746612a688SGabor Juhos cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 47541583c05SGabor Juhos cpu_pll /= (1 << out_div); 47641583c05SGabor Juhos 47741583c05SGabor Juhos pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); 47841583c05SGabor Juhos out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 47941583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 48041583c05SGabor Juhos ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 48141583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 48241583c05SGabor Juhos nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 48341583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NINT_MASK; 48441583c05SGabor Juhos frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 48541583c05SGabor Juhos QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 48641583c05SGabor Juhos 4876612a688SGabor Juhos ddr_pll = nint * ref_rate / ref_div; 4886612a688SGabor Juhos ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 48941583c05SGabor Juhos ddr_pll /= (1 << out_div); 49041583c05SGabor Juhos 49141583c05SGabor Juhos clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); 49241583c05SGabor Juhos 49341583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 49441583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 49541583c05SGabor Juhos 49641583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 4976612a688SGabor Juhos cpu_rate = ref_rate; 49841583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 4996612a688SGabor Juhos cpu_rate = ddr_pll / (postdiv + 1); 50041583c05SGabor Juhos else 5016612a688SGabor Juhos cpu_rate = cpu_pll / (postdiv + 1); 50241583c05SGabor Juhos 50341583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 50441583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 50541583c05SGabor Juhos 50641583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 5076612a688SGabor Juhos ddr_rate = ref_rate; 50841583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 5096612a688SGabor Juhos ddr_rate = cpu_pll / (postdiv + 1); 51041583c05SGabor Juhos else 5116612a688SGabor Juhos ddr_rate = ddr_pll / (postdiv + 1); 51241583c05SGabor Juhos 51341583c05SGabor Juhos postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 51441583c05SGabor Juhos QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 51541583c05SGabor Juhos 51641583c05SGabor Juhos if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 5176612a688SGabor Juhos ahb_rate = ref_rate; 51841583c05SGabor Juhos else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 5196612a688SGabor Juhos ahb_rate = ddr_pll / (postdiv + 1); 52041583c05SGabor Juhos else 5216612a688SGabor Juhos ahb_rate = cpu_pll / (postdiv + 1); 5226612a688SGabor Juhos 523*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 524*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 525*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 526*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 52741583c05SGabor Juhos 5282c4f1ac5SGabor Juhos clk_add_alias("wdt", NULL, "ref", NULL); 5292c4f1ac5SGabor Juhos clk_add_alias("uart", NULL, "ref", NULL); 53041583c05SGabor Juhos } 53141583c05SGabor Juhos 532af2d1b52SMatthias Schiffer static void __init qca956x_clocks_init(void) 533af2d1b52SMatthias Schiffer { 534af2d1b52SMatthias Schiffer unsigned long ref_rate; 535af2d1b52SMatthias Schiffer unsigned long cpu_rate; 536af2d1b52SMatthias Schiffer unsigned long ddr_rate; 537af2d1b52SMatthias Schiffer unsigned long ahb_rate; 538af2d1b52SMatthias Schiffer u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; 539af2d1b52SMatthias Schiffer u32 cpu_pll, ddr_pll; 540af2d1b52SMatthias Schiffer u32 bootstrap; 541af2d1b52SMatthias Schiffer 542af2d1b52SMatthias Schiffer /* 543af2d1b52SMatthias Schiffer * QCA956x timer init workaround has to be applied right before setting 544af2d1b52SMatthias Schiffer * up the clock. Else, there will be no jiffies 545af2d1b52SMatthias Schiffer */ 546af2d1b52SMatthias Schiffer u32 misc; 547af2d1b52SMatthias Schiffer 548af2d1b52SMatthias Schiffer misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); 549af2d1b52SMatthias Schiffer misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; 550af2d1b52SMatthias Schiffer ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); 551af2d1b52SMatthias Schiffer 552af2d1b52SMatthias Schiffer bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); 553af2d1b52SMatthias Schiffer if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) 554af2d1b52SMatthias Schiffer ref_rate = 40 * 1000 * 1000; 555af2d1b52SMatthias Schiffer else 556af2d1b52SMatthias Schiffer ref_rate = 25 * 1000 * 1000; 557af2d1b52SMatthias Schiffer 558af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); 559af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 560af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 561af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 562af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 563af2d1b52SMatthias Schiffer 564af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); 565af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 566af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 567af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 568af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; 569af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & 570af2d1b52SMatthias Schiffer QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; 571af2d1b52SMatthias Schiffer 572af2d1b52SMatthias Schiffer cpu_pll = nint * ref_rate / ref_div; 573af2d1b52SMatthias Schiffer cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 574af2d1b52SMatthias Schiffer cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 575af2d1b52SMatthias Schiffer cpu_pll /= (1 << out_div); 576af2d1b52SMatthias Schiffer 577af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); 578af2d1b52SMatthias Schiffer out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 579af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 580af2d1b52SMatthias Schiffer ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 581af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 582af2d1b52SMatthias Schiffer pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); 583af2d1b52SMatthias Schiffer nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 584af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 585af2d1b52SMatthias Schiffer hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 586af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; 587af2d1b52SMatthias Schiffer lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & 588af2d1b52SMatthias Schiffer QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; 589af2d1b52SMatthias Schiffer 590af2d1b52SMatthias Schiffer ddr_pll = nint * ref_rate / ref_div; 591af2d1b52SMatthias Schiffer ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 592af2d1b52SMatthias Schiffer ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 593af2d1b52SMatthias Schiffer ddr_pll /= (1 << out_div); 594af2d1b52SMatthias Schiffer 595af2d1b52SMatthias Schiffer clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); 596af2d1b52SMatthias Schiffer 597af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 598af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 599af2d1b52SMatthias Schiffer 600af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 601af2d1b52SMatthias Schiffer cpu_rate = ref_rate; 602af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) 603af2d1b52SMatthias Schiffer cpu_rate = ddr_pll / (postdiv + 1); 604af2d1b52SMatthias Schiffer else 605af2d1b52SMatthias Schiffer cpu_rate = cpu_pll / (postdiv + 1); 606af2d1b52SMatthias Schiffer 607af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 608af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 609af2d1b52SMatthias Schiffer 610af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 611af2d1b52SMatthias Schiffer ddr_rate = ref_rate; 612af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) 613af2d1b52SMatthias Schiffer ddr_rate = cpu_pll / (postdiv + 1); 614af2d1b52SMatthias Schiffer else 615af2d1b52SMatthias Schiffer ddr_rate = ddr_pll / (postdiv + 1); 616af2d1b52SMatthias Schiffer 617af2d1b52SMatthias Schiffer postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 618af2d1b52SMatthias Schiffer QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 619af2d1b52SMatthias Schiffer 620af2d1b52SMatthias Schiffer if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 621af2d1b52SMatthias Schiffer ahb_rate = ref_rate; 622af2d1b52SMatthias Schiffer else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 623af2d1b52SMatthias Schiffer ahb_rate = ddr_pll / (postdiv + 1); 624af2d1b52SMatthias Schiffer else 625af2d1b52SMatthias Schiffer ahb_rate = cpu_pll / (postdiv + 1); 626af2d1b52SMatthias Schiffer 627*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_REF, ref_rate); 628*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 629*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 630*9b56e0d0SFelix Fietkau ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 631af2d1b52SMatthias Schiffer 632af2d1b52SMatthias Schiffer clk_add_alias("wdt", NULL, "ref", NULL); 633af2d1b52SMatthias Schiffer clk_add_alias("uart", NULL, "ref", NULL); 634af2d1b52SMatthias Schiffer } 635af2d1b52SMatthias Schiffer 636d4a67d9dSGabor Juhos void __init ath79_clocks_init(void) 637d4a67d9dSGabor Juhos { 638d4a67d9dSGabor Juhos if (soc_is_ar71xx()) 639d4a67d9dSGabor Juhos ar71xx_clocks_init(); 640f4c87b7aSAlban Bedel else if (soc_is_ar724x() || soc_is_ar913x()) 641d4a67d9dSGabor Juhos ar724x_clocks_init(); 64204225e1dSGabor Juhos else if (soc_is_ar933x()) 64304225e1dSGabor Juhos ar933x_clocks_init(); 6448889612bSGabor Juhos else if (soc_is_ar934x()) 6458889612bSGabor Juhos ar934x_clocks_init(); 646af2d1b52SMatthias Schiffer else if (soc_is_qca953x()) 647af2d1b52SMatthias Schiffer qca953x_clocks_init(); 64841583c05SGabor Juhos else if (soc_is_qca955x()) 64941583c05SGabor Juhos qca955x_clocks_init(); 650af2d1b52SMatthias Schiffer else if (soc_is_qca956x() || soc_is_tp9343()) 651af2d1b52SMatthias Schiffer qca956x_clocks_init(); 652d4a67d9dSGabor Juhos else 653d4a67d9dSGabor Juhos BUG(); 654d4a67d9dSGabor Juhos } 655d4a67d9dSGabor Juhos 65623107802SGabor Juhos unsigned long __init 65723107802SGabor Juhos ath79_get_sys_clk_rate(const char *id) 65823107802SGabor Juhos { 65923107802SGabor Juhos struct clk *clk; 66023107802SGabor Juhos unsigned long rate; 66123107802SGabor Juhos 66223107802SGabor Juhos clk = clk_get(NULL, id); 66323107802SGabor Juhos if (IS_ERR(clk)) 66423107802SGabor Juhos panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); 66523107802SGabor Juhos 66623107802SGabor Juhos rate = clk_get_rate(clk); 66723107802SGabor Juhos clk_put(clk); 66823107802SGabor Juhos 66923107802SGabor Juhos return rate; 67023107802SGabor Juhos } 6716451af02SAlban Bedel 6726451af02SAlban Bedel #ifdef CONFIG_OF 6736451af02SAlban Bedel static void __init ath79_clocks_init_dt(struct device_node *np) 6746451af02SAlban Bedel { 6756451af02SAlban Bedel of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 6766451af02SAlban Bedel } 6776451af02SAlban Bedel 6786451af02SAlban Bedel CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); 6796451af02SAlban Bedel CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); 6806451af02SAlban Bedel CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); 6816451af02SAlban Bedel CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); 6823bdf1071SAntony Pavlov 6833bdf1071SAntony Pavlov static void __init ath79_clocks_init_dt_ng(struct device_node *np) 6843bdf1071SAntony Pavlov { 6853bdf1071SAntony Pavlov struct clk *ref_clk; 6863bdf1071SAntony Pavlov void __iomem *pll_base; 6873bdf1071SAntony Pavlov 6883bdf1071SAntony Pavlov ref_clk = of_clk_get(np, 0); 6893bdf1071SAntony Pavlov if (IS_ERR(ref_clk)) { 6907f27b5b8SRob Herring pr_err("%pOF: of_clk_get failed\n", np); 6913bdf1071SAntony Pavlov goto err; 6923bdf1071SAntony Pavlov } 6933bdf1071SAntony Pavlov 6943bdf1071SAntony Pavlov pll_base = of_iomap(np, 0); 6953bdf1071SAntony Pavlov if (!pll_base) { 6967f27b5b8SRob Herring pr_err("%pOF: can't map pll registers\n", np); 6973bdf1071SAntony Pavlov goto err_clk; 6983bdf1071SAntony Pavlov } 6993bdf1071SAntony Pavlov 7005ae5c452SAntony Pavlov if (of_device_is_compatible(np, "qca,ar9130-pll")) 7013bdf1071SAntony Pavlov ar724x_clk_init(ref_clk, pll_base); 7025ae5c452SAntony Pavlov else if (of_device_is_compatible(np, "qca,ar9330-pll")) 7035ae5c452SAntony Pavlov ar9330_clk_init(ref_clk, pll_base); 7045ae5c452SAntony Pavlov else { 7057f27b5b8SRob Herring pr_err("%pOF: could not find any appropriate clk_init()\n", np); 706b3d91db3SArvind Yadav goto err_iounmap; 7075ae5c452SAntony Pavlov } 7083bdf1071SAntony Pavlov 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 7223bdf1071SAntony Pavlov err: 7233bdf1071SAntony Pavlov return; 7243bdf1071SAntony Pavlov } 7253bdf1071SAntony Pavlov CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); 7265ae5c452SAntony Pavlov CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); 7276451af02SAlban Bedel #endif 728