162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Atheros AR71XX/AR724X/AR913X common routines 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 662306a36Sopenharmony_ci * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/kernel.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/err.h> 1562306a36Sopenharmony_ci#include <linux/clk.h> 1662306a36Sopenharmony_ci#include <linux/clkdev.h> 1762306a36Sopenharmony_ci#include <linux/clk-provider.h> 1862306a36Sopenharmony_ci#include <linux/of.h> 1962306a36Sopenharmony_ci#include <linux/of_address.h> 2062306a36Sopenharmony_ci#include <dt-bindings/clock/ath79-clk.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <asm/div64.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include <asm/mach-ath79/ath79.h> 2562306a36Sopenharmony_ci#include <asm/mach-ath79/ar71xx_regs.h> 2662306a36Sopenharmony_ci#include "common.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define AR71XX_BASE_FREQ 40000000 2962306a36Sopenharmony_ci#define AR724X_BASE_FREQ 40000000 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic struct clk *clks[ATH79_CLK_END]; 3262306a36Sopenharmony_cistatic struct clk_onecell_data clk_data = { 3362306a36Sopenharmony_ci .clks = clks, 3462306a36Sopenharmony_ci .clk_num = ARRAY_SIZE(clks), 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic const char * const clk_names[ATH79_CLK_END] = { 3862306a36Sopenharmony_ci [ATH79_CLK_CPU] = "cpu", 3962306a36Sopenharmony_ci [ATH79_CLK_DDR] = "ddr", 4062306a36Sopenharmony_ci [ATH79_CLK_AHB] = "ahb", 4162306a36Sopenharmony_ci [ATH79_CLK_REF] = "ref", 4262306a36Sopenharmony_ci [ATH79_CLK_MDIO] = "mdio", 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic const char * __init ath79_clk_name(int type) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); 4862306a36Sopenharmony_ci return clk_names[type]; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic void __init __ath79_set_clk(int type, const char *name, struct clk *clk) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci if (IS_ERR(clk)) 5462306a36Sopenharmony_ci panic("failed to allocate %s clock structure", clk_names[type]); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci clks[type] = clk; 5762306a36Sopenharmony_ci clk_register_clkdev(clk, name, NULL); 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic struct clk * __init ath79_set_clk(int type, unsigned long rate) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci const char *name = ath79_clk_name(type); 6362306a36Sopenharmony_ci struct clk *clk; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); 6662306a36Sopenharmony_ci __ath79_set_clk(type, name, clk); 6762306a36Sopenharmony_ci return clk; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic struct clk * __init ath79_set_ff_clk(int type, const char *parent, 7162306a36Sopenharmony_ci unsigned int mult, unsigned int div) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci const char *name = ath79_clk_name(type); 7462306a36Sopenharmony_ci struct clk *clk; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); 7762306a36Sopenharmony_ci __ath79_set_clk(type, name, clk); 7862306a36Sopenharmony_ci return clk; 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic unsigned long __init ath79_setup_ref_clk(unsigned long rate) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci struct clk *clk = clks[ATH79_CLK_REF]; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci if (clk) 8662306a36Sopenharmony_ci rate = clk_get_rate(clk); 8762306a36Sopenharmony_ci else 8862306a36Sopenharmony_ci clk = ath79_set_clk(ATH79_CLK_REF, rate); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci return rate; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic void __init ar71xx_clocks_init(void __iomem *pll_base) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci unsigned long ref_rate; 9662306a36Sopenharmony_ci unsigned long cpu_rate; 9762306a36Sopenharmony_ci unsigned long ddr_rate; 9862306a36Sopenharmony_ci unsigned long ahb_rate; 9962306a36Sopenharmony_ci u32 pll; 10062306a36Sopenharmony_ci u32 freq; 10162306a36Sopenharmony_ci u32 div; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; 10862306a36Sopenharmony_ci freq = div * ref_rate; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 11162306a36Sopenharmony_ci cpu_rate = freq / div; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 11462306a36Sopenharmony_ci ddr_rate = freq / div; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 11762306a36Sopenharmony_ci ahb_rate = cpu_rate / div; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 12062306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 12162306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic void __init ar724x_clocks_init(void __iomem *pll_base) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci u32 mult, div, ddr_div, ahb_div; 12762306a36Sopenharmony_ci u32 pll; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci ath79_setup_ref_clk(AR71XX_BASE_FREQ); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 13462306a36Sopenharmony_ci div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 13762306a36Sopenharmony_ci ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); 14062306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); 14162306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic void __init ar933x_clocks_init(void __iomem *pll_base) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci unsigned long ref_rate; 14762306a36Sopenharmony_ci u32 clock_ctrl; 14862306a36Sopenharmony_ci u32 ref_div; 14962306a36Sopenharmony_ci u32 ninit_mul; 15062306a36Sopenharmony_ci u32 out_div; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci u32 cpu_div; 15362306a36Sopenharmony_ci u32 ddr_div; 15462306a36Sopenharmony_ci u32 ahb_div; 15562306a36Sopenharmony_ci u32 t; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 15862306a36Sopenharmony_ci if (t & AR933X_BOOTSTRAP_REF_CLK_40) 15962306a36Sopenharmony_ci ref_rate = (40 * 1000 * 1000); 16062306a36Sopenharmony_ci else 16162306a36Sopenharmony_ci ref_rate = (25 * 1000 * 1000); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci ath79_setup_ref_clk(ref_rate); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 16662306a36Sopenharmony_ci if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 16762306a36Sopenharmony_ci ref_div = 1; 16862306a36Sopenharmony_ci ninit_mul = 1; 16962306a36Sopenharmony_ci out_div = 1; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci cpu_div = 1; 17262306a36Sopenharmony_ci ddr_div = 1; 17362306a36Sopenharmony_ci ahb_div = 1; 17462306a36Sopenharmony_ci } else { 17562306a36Sopenharmony_ci u32 cpu_config; 17662306a36Sopenharmony_ci u32 t; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 18162306a36Sopenharmony_ci AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 18262306a36Sopenharmony_ci ref_div = t; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 18562306a36Sopenharmony_ci AR933X_PLL_CPU_CONFIG_NINT_MASK; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 18862306a36Sopenharmony_ci AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 18962306a36Sopenharmony_ci if (t == 0) 19062306a36Sopenharmony_ci t = 1; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci out_div = (1 << t); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 19562306a36Sopenharmony_ci AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 19862306a36Sopenharmony_ci AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 20162306a36Sopenharmony_ci AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 20262306a36Sopenharmony_ci } 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, 20562306a36Sopenharmony_ci ref_div * out_div * cpu_div); 20662306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, 20762306a36Sopenharmony_ci ref_div * out_div * ddr_div); 20862306a36Sopenharmony_ci ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, 20962306a36Sopenharmony_ci ref_div * out_div * ahb_div); 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistatic u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 21362306a36Sopenharmony_ci u32 frac, u32 out_div) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci u64 t; 21662306a36Sopenharmony_ci u32 ret; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci t = ref; 21962306a36Sopenharmony_ci t *= nint; 22062306a36Sopenharmony_ci do_div(t, ref_div); 22162306a36Sopenharmony_ci ret = t; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci t = ref; 22462306a36Sopenharmony_ci t *= nfrac; 22562306a36Sopenharmony_ci do_div(t, ref_div * frac); 22662306a36Sopenharmony_ci ret += t; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci ret /= (1 << out_div); 22962306a36Sopenharmony_ci return ret; 23062306a36Sopenharmony_ci} 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistatic void __init ar934x_clocks_init(void __iomem *pll_base) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci unsigned long ref_rate; 23562306a36Sopenharmony_ci unsigned long cpu_rate; 23662306a36Sopenharmony_ci unsigned long ddr_rate; 23762306a36Sopenharmony_ci unsigned long ahb_rate; 23862306a36Sopenharmony_ci u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 23962306a36Sopenharmony_ci u32 cpu_pll, ddr_pll; 24062306a36Sopenharmony_ci u32 bootstrap; 24162306a36Sopenharmony_ci void __iomem *dpll_base; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 24662306a36Sopenharmony_ci if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 24762306a36Sopenharmony_ci ref_rate = 40 * 1000 * 1000; 24862306a36Sopenharmony_ci else 24962306a36Sopenharmony_ci ref_rate = 25 * 1000 * 1000; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci ref_rate = ath79_setup_ref_clk(ref_rate); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 25462306a36Sopenharmony_ci if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 25562306a36Sopenharmony_ci out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 25662306a36Sopenharmony_ci AR934X_SRIF_DPLL2_OUTDIV_MASK; 25762306a36Sopenharmony_ci pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); 25862306a36Sopenharmony_ci nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 25962306a36Sopenharmony_ci AR934X_SRIF_DPLL1_NINT_MASK; 26062306a36Sopenharmony_ci nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 26162306a36Sopenharmony_ci ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 26262306a36Sopenharmony_ci AR934X_SRIF_DPLL1_REFDIV_MASK; 26362306a36Sopenharmony_ci frac = 1 << 18; 26462306a36Sopenharmony_ci } else { 26562306a36Sopenharmony_ci pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); 26662306a36Sopenharmony_ci out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 26762306a36Sopenharmony_ci AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 26862306a36Sopenharmony_ci ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 26962306a36Sopenharmony_ci AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 27062306a36Sopenharmony_ci nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 27162306a36Sopenharmony_ci AR934X_PLL_CPU_CONFIG_NINT_MASK; 27262306a36Sopenharmony_ci nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 27362306a36Sopenharmony_ci AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 27462306a36Sopenharmony_ci frac = 1 << 6; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 27862306a36Sopenharmony_ci nfrac, frac, out_div); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); 28162306a36Sopenharmony_ci if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 28262306a36Sopenharmony_ci out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 28362306a36Sopenharmony_ci AR934X_SRIF_DPLL2_OUTDIV_MASK; 28462306a36Sopenharmony_ci pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); 28562306a36Sopenharmony_ci nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 28662306a36Sopenharmony_ci AR934X_SRIF_DPLL1_NINT_MASK; 28762306a36Sopenharmony_ci nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 28862306a36Sopenharmony_ci ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 28962306a36Sopenharmony_ci AR934X_SRIF_DPLL1_REFDIV_MASK; 29062306a36Sopenharmony_ci frac = 1 << 18; 29162306a36Sopenharmony_ci } else { 29262306a36Sopenharmony_ci pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); 29362306a36Sopenharmony_ci out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 29462306a36Sopenharmony_ci AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 29562306a36Sopenharmony_ci ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 29662306a36Sopenharmony_ci AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 29762306a36Sopenharmony_ci nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 29862306a36Sopenharmony_ci AR934X_PLL_DDR_CONFIG_NINT_MASK; 29962306a36Sopenharmony_ci nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 30062306a36Sopenharmony_ci AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 30162306a36Sopenharmony_ci frac = 1 << 10; 30262306a36Sopenharmony_ci } 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 30562306a36Sopenharmony_ci nfrac, frac, out_div); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 31062306a36Sopenharmony_ci AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 31362306a36Sopenharmony_ci cpu_rate = ref_rate; 31462306a36Sopenharmony_ci else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 31562306a36Sopenharmony_ci cpu_rate = cpu_pll / (postdiv + 1); 31662306a36Sopenharmony_ci else 31762306a36Sopenharmony_ci cpu_rate = ddr_pll / (postdiv + 1); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 32062306a36Sopenharmony_ci AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 32362306a36Sopenharmony_ci ddr_rate = ref_rate; 32462306a36Sopenharmony_ci else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 32562306a36Sopenharmony_ci ddr_rate = ddr_pll / (postdiv + 1); 32662306a36Sopenharmony_ci else 32762306a36Sopenharmony_ci ddr_rate = cpu_pll / (postdiv + 1); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 33062306a36Sopenharmony_ci AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 33362306a36Sopenharmony_ci ahb_rate = ref_rate; 33462306a36Sopenharmony_ci else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 33562306a36Sopenharmony_ci ahb_rate = ddr_pll / (postdiv + 1); 33662306a36Sopenharmony_ci else 33762306a36Sopenharmony_ci ahb_rate = cpu_pll / (postdiv + 1); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 34062306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 34162306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); 34462306a36Sopenharmony_ci if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) 34562306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci iounmap(dpll_base); 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistatic void __init qca953x_clocks_init(void __iomem *pll_base) 35162306a36Sopenharmony_ci{ 35262306a36Sopenharmony_ci unsigned long ref_rate; 35362306a36Sopenharmony_ci unsigned long cpu_rate; 35462306a36Sopenharmony_ci unsigned long ddr_rate; 35562306a36Sopenharmony_ci unsigned long ahb_rate; 35662306a36Sopenharmony_ci u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 35762306a36Sopenharmony_ci u32 cpu_pll, ddr_pll; 35862306a36Sopenharmony_ci u32 bootstrap; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); 36162306a36Sopenharmony_ci if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) 36262306a36Sopenharmony_ci ref_rate = 40 * 1000 * 1000; 36362306a36Sopenharmony_ci else 36462306a36Sopenharmony_ci ref_rate = 25 * 1000 * 1000; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci ref_rate = ath79_setup_ref_clk(ref_rate); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); 36962306a36Sopenharmony_ci out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 37062306a36Sopenharmony_ci QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 37162306a36Sopenharmony_ci ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 37262306a36Sopenharmony_ci QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; 37362306a36Sopenharmony_ci nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & 37462306a36Sopenharmony_ci QCA953X_PLL_CPU_CONFIG_NINT_MASK; 37562306a36Sopenharmony_ci frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 37662306a36Sopenharmony_ci QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci cpu_pll = nint * ref_rate / ref_div; 37962306a36Sopenharmony_ci cpu_pll += frac * (ref_rate >> 6) / ref_div; 38062306a36Sopenharmony_ci cpu_pll /= (1 << out_div); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); 38362306a36Sopenharmony_ci out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 38462306a36Sopenharmony_ci QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 38562306a36Sopenharmony_ci ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 38662306a36Sopenharmony_ci QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; 38762306a36Sopenharmony_ci nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & 38862306a36Sopenharmony_ci QCA953X_PLL_DDR_CONFIG_NINT_MASK; 38962306a36Sopenharmony_ci frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 39062306a36Sopenharmony_ci QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci ddr_pll = nint * ref_rate / ref_div; 39362306a36Sopenharmony_ci ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 39462306a36Sopenharmony_ci ddr_pll /= (1 << out_div); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 39962306a36Sopenharmony_ci QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 40262306a36Sopenharmony_ci cpu_rate = ref_rate; 40362306a36Sopenharmony_ci else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 40462306a36Sopenharmony_ci cpu_rate = cpu_pll / (postdiv + 1); 40562306a36Sopenharmony_ci else 40662306a36Sopenharmony_ci cpu_rate = ddr_pll / (postdiv + 1); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 40962306a36Sopenharmony_ci QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 41262306a36Sopenharmony_ci ddr_rate = ref_rate; 41362306a36Sopenharmony_ci else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 41462306a36Sopenharmony_ci ddr_rate = ddr_pll / (postdiv + 1); 41562306a36Sopenharmony_ci else 41662306a36Sopenharmony_ci ddr_rate = cpu_pll / (postdiv + 1); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 41962306a36Sopenharmony_ci QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 42262306a36Sopenharmony_ci ahb_rate = ref_rate; 42362306a36Sopenharmony_ci else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 42462306a36Sopenharmony_ci ahb_rate = ddr_pll / (postdiv + 1); 42562306a36Sopenharmony_ci else 42662306a36Sopenharmony_ci ahb_rate = cpu_pll / (postdiv + 1); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 42962306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 43062306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 43162306a36Sopenharmony_ci} 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_cistatic void __init qca955x_clocks_init(void __iomem *pll_base) 43462306a36Sopenharmony_ci{ 43562306a36Sopenharmony_ci unsigned long ref_rate; 43662306a36Sopenharmony_ci unsigned long cpu_rate; 43762306a36Sopenharmony_ci unsigned long ddr_rate; 43862306a36Sopenharmony_ci unsigned long ahb_rate; 43962306a36Sopenharmony_ci u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 44062306a36Sopenharmony_ci u32 cpu_pll, ddr_pll; 44162306a36Sopenharmony_ci u32 bootstrap; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 44462306a36Sopenharmony_ci if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 44562306a36Sopenharmony_ci ref_rate = 40 * 1000 * 1000; 44662306a36Sopenharmony_ci else 44762306a36Sopenharmony_ci ref_rate = 25 * 1000 * 1000; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci ref_rate = ath79_setup_ref_clk(ref_rate); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); 45262306a36Sopenharmony_ci out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 45362306a36Sopenharmony_ci QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 45462306a36Sopenharmony_ci ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 45562306a36Sopenharmony_ci QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 45662306a36Sopenharmony_ci nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 45762306a36Sopenharmony_ci QCA955X_PLL_CPU_CONFIG_NINT_MASK; 45862306a36Sopenharmony_ci frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 45962306a36Sopenharmony_ci QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci cpu_pll = nint * ref_rate / ref_div; 46262306a36Sopenharmony_ci cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 46362306a36Sopenharmony_ci cpu_pll /= (1 << out_div); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); 46662306a36Sopenharmony_ci out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 46762306a36Sopenharmony_ci QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 46862306a36Sopenharmony_ci ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 46962306a36Sopenharmony_ci QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 47062306a36Sopenharmony_ci nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 47162306a36Sopenharmony_ci QCA955X_PLL_DDR_CONFIG_NINT_MASK; 47262306a36Sopenharmony_ci frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 47362306a36Sopenharmony_ci QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci ddr_pll = nint * ref_rate / ref_div; 47662306a36Sopenharmony_ci ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 47762306a36Sopenharmony_ci ddr_pll /= (1 << out_div); 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 48262306a36Sopenharmony_ci QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 48562306a36Sopenharmony_ci cpu_rate = ref_rate; 48662306a36Sopenharmony_ci else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 48762306a36Sopenharmony_ci cpu_rate = ddr_pll / (postdiv + 1); 48862306a36Sopenharmony_ci else 48962306a36Sopenharmony_ci cpu_rate = cpu_pll / (postdiv + 1); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 49262306a36Sopenharmony_ci QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 49562306a36Sopenharmony_ci ddr_rate = ref_rate; 49662306a36Sopenharmony_ci else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 49762306a36Sopenharmony_ci ddr_rate = cpu_pll / (postdiv + 1); 49862306a36Sopenharmony_ci else 49962306a36Sopenharmony_ci ddr_rate = ddr_pll / (postdiv + 1); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 50262306a36Sopenharmony_ci QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 50562306a36Sopenharmony_ci ahb_rate = ref_rate; 50662306a36Sopenharmony_ci else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 50762306a36Sopenharmony_ci ahb_rate = ddr_pll / (postdiv + 1); 50862306a36Sopenharmony_ci else 50962306a36Sopenharmony_ci ahb_rate = cpu_pll / (postdiv + 1); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 51262306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 51362306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic void __init qca956x_clocks_init(void __iomem *pll_base) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci unsigned long ref_rate; 51962306a36Sopenharmony_ci unsigned long cpu_rate; 52062306a36Sopenharmony_ci unsigned long ddr_rate; 52162306a36Sopenharmony_ci unsigned long ahb_rate; 52262306a36Sopenharmony_ci u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; 52362306a36Sopenharmony_ci u32 cpu_pll, ddr_pll; 52462306a36Sopenharmony_ci u32 bootstrap; 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci /* 52762306a36Sopenharmony_ci * QCA956x timer init workaround has to be applied right before setting 52862306a36Sopenharmony_ci * up the clock. Else, there will be no jiffies 52962306a36Sopenharmony_ci */ 53062306a36Sopenharmony_ci u32 misc; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); 53362306a36Sopenharmony_ci misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; 53462306a36Sopenharmony_ci ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); 53762306a36Sopenharmony_ci if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) 53862306a36Sopenharmony_ci ref_rate = 40 * 1000 * 1000; 53962306a36Sopenharmony_ci else 54062306a36Sopenharmony_ci ref_rate = 25 * 1000 * 1000; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci ref_rate = ath79_setup_ref_clk(ref_rate); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); 54562306a36Sopenharmony_ci out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 54662306a36Sopenharmony_ci QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 54762306a36Sopenharmony_ci ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 54862306a36Sopenharmony_ci QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); 55162306a36Sopenharmony_ci nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 55262306a36Sopenharmony_ci QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 55362306a36Sopenharmony_ci hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 55462306a36Sopenharmony_ci QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; 55562306a36Sopenharmony_ci lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & 55662306a36Sopenharmony_ci QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci cpu_pll = nint * ref_rate / ref_div; 55962306a36Sopenharmony_ci cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 56062306a36Sopenharmony_ci cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 56162306a36Sopenharmony_ci cpu_pll /= (1 << out_div); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); 56462306a36Sopenharmony_ci out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 56562306a36Sopenharmony_ci QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 56662306a36Sopenharmony_ci ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 56762306a36Sopenharmony_ci QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 56862306a36Sopenharmony_ci pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); 56962306a36Sopenharmony_ci nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 57062306a36Sopenharmony_ci QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 57162306a36Sopenharmony_ci hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 57262306a36Sopenharmony_ci QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; 57362306a36Sopenharmony_ci lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & 57462306a36Sopenharmony_ci QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci ddr_pll = nint * ref_rate / ref_div; 57762306a36Sopenharmony_ci ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); 57862306a36Sopenharmony_ci ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 57962306a36Sopenharmony_ci ddr_pll /= (1 << out_div); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 58462306a36Sopenharmony_ci QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 58762306a36Sopenharmony_ci cpu_rate = ref_rate; 58862306a36Sopenharmony_ci else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) 58962306a36Sopenharmony_ci cpu_rate = ddr_pll / (postdiv + 1); 59062306a36Sopenharmony_ci else 59162306a36Sopenharmony_ci cpu_rate = cpu_pll / (postdiv + 1); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 59462306a36Sopenharmony_ci QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 59762306a36Sopenharmony_ci ddr_rate = ref_rate; 59862306a36Sopenharmony_ci else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) 59962306a36Sopenharmony_ci ddr_rate = cpu_pll / (postdiv + 1); 60062306a36Sopenharmony_ci else 60162306a36Sopenharmony_ci ddr_rate = ddr_pll / (postdiv + 1); 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 60462306a36Sopenharmony_ci QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 60762306a36Sopenharmony_ci ahb_rate = ref_rate; 60862306a36Sopenharmony_ci else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 60962306a36Sopenharmony_ci ahb_rate = ddr_pll / (postdiv + 1); 61062306a36Sopenharmony_ci else 61162306a36Sopenharmony_ci ahb_rate = cpu_pll / (postdiv + 1); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_CPU, cpu_rate); 61462306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_DDR, ddr_rate); 61562306a36Sopenharmony_ci ath79_set_clk(ATH79_CLK_AHB, ahb_rate); 61662306a36Sopenharmony_ci} 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_cistatic void __init ath79_clocks_init_dt(struct device_node *np) 61962306a36Sopenharmony_ci{ 62062306a36Sopenharmony_ci struct clk *ref_clk; 62162306a36Sopenharmony_ci void __iomem *pll_base; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci ref_clk = of_clk_get(np, 0); 62462306a36Sopenharmony_ci if (!IS_ERR(ref_clk)) 62562306a36Sopenharmony_ci clks[ATH79_CLK_REF] = ref_clk; 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci pll_base = of_iomap(np, 0); 62862306a36Sopenharmony_ci if (!pll_base) { 62962306a36Sopenharmony_ci pr_err("%pOF: can't map pll registers\n", np); 63062306a36Sopenharmony_ci goto err_clk; 63162306a36Sopenharmony_ci } 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci if (of_device_is_compatible(np, "qca,ar7100-pll")) 63462306a36Sopenharmony_ci ar71xx_clocks_init(pll_base); 63562306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,ar7240-pll") || 63662306a36Sopenharmony_ci of_device_is_compatible(np, "qca,ar9130-pll")) 63762306a36Sopenharmony_ci ar724x_clocks_init(pll_base); 63862306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,ar9330-pll")) 63962306a36Sopenharmony_ci ar933x_clocks_init(pll_base); 64062306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,ar9340-pll")) 64162306a36Sopenharmony_ci ar934x_clocks_init(pll_base); 64262306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,qca9530-pll")) 64362306a36Sopenharmony_ci qca953x_clocks_init(pll_base); 64462306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,qca9550-pll")) 64562306a36Sopenharmony_ci qca955x_clocks_init(pll_base); 64662306a36Sopenharmony_ci else if (of_device_is_compatible(np, "qca,qca9560-pll")) 64762306a36Sopenharmony_ci qca956x_clocks_init(pll_base); 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci if (!clks[ATH79_CLK_MDIO]) 65062306a36Sopenharmony_ci clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF]; 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 65362306a36Sopenharmony_ci pr_err("%pOF: could not register clk provider\n", np); 65462306a36Sopenharmony_ci goto err_iounmap; 65562306a36Sopenharmony_ci } 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci return; 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_cierr_iounmap: 66062306a36Sopenharmony_ci iounmap(pll_base); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_cierr_clk: 66362306a36Sopenharmony_ci clk_put(ref_clk); 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ciCLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); 66762306a36Sopenharmony_ciCLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); 66862306a36Sopenharmony_ciCLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); 66962306a36Sopenharmony_ciCLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); 67062306a36Sopenharmony_ciCLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); 67162306a36Sopenharmony_ciCLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); 67262306a36Sopenharmony_ciCLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); 67362306a36Sopenharmony_ciCLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); 674