Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: ath79: update devicetree clock support for AR9132

Current ath79 clock.c code does not read reference clock and
pll setup from devicetree. E.g. you can set any clock rate value
in board DTS but it will have no effect on the real clk calculation.

This patch fixes some AR9132 devicetree clock support defects:

* clk initialization function ath79_clocks_init_dt_ng()
is introduced; it actually gets pll block base register
address and reference clock from devicetree;
* pll register parsing code is moved to the separate
ar724x_clk_init() function; this function
can be called from platform code or from devicetree code.

Also mips_hpt_frequency value is set from dt, so the appropriate
clock parameter is added to the cpu@0 devicetree node.

The same approach can be used for adding AR9331 devicetree support.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Cc: Gabor Juhos <juhosg@openwrt.org>
Cc: Alban Bedel <albeu@free.fr>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: linux-clk@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/12876/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Antony Pavlov and committed by
Ralf Baechle
3bdf1071 af5ad0de

+112 -29
+75 -29
arch/mips/ath79/clock.c
··· 18 18 #include <linux/clk.h> 19 19 #include <linux/clkdev.h> 20 20 #include <linux/clk-provider.h> 21 + #include <linux/of.h> 22 + #include <linux/of_address.h> 21 23 #include <dt-bindings/clock/ath79-clk.h> 22 24 23 25 #include <asm/div64.h> ··· 27 25 #include <asm/mach-ath79/ath79.h> 28 26 #include <asm/mach-ath79/ar71xx_regs.h> 29 27 #include "common.h" 28 + #include "machtypes.h" 30 29 31 30 #define AR71XX_BASE_FREQ 40000000 32 31 #define AR724X_BASE_FREQ 40000000 ··· 90 87 clk_add_alias("uart", NULL, "ahb", NULL); 91 88 } 92 89 90 + static struct clk * __init ath79_reg_ffclk(const char *name, 91 + const char *parent_name, unsigned int mult, unsigned int div) 92 + { 93 + struct clk *clk; 94 + 95 + clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); 96 + if (!clk) 97 + panic("failed to allocate %s clock structure", name); 98 + 99 + return clk; 100 + } 101 + 102 + static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) 103 + { 104 + u32 pll; 105 + u32 mult, div, ddr_div, ahb_div; 106 + 107 + pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 108 + 109 + mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 110 + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 111 + 112 + ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 113 + ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 114 + 115 + clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div); 116 + clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div); 117 + clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div); 118 + } 119 + 93 120 static void __init ar724x_clocks_init(void) 94 121 { 95 - unsigned long ref_rate; 96 - unsigned long cpu_rate; 97 - unsigned long ddr_rate; 98 - unsigned long ahb_rate; 99 - u32 pll; 100 - u32 freq; 101 - u32 div; 122 + struct clk *ref_clk; 102 123 103 - ref_rate = AR724X_BASE_FREQ; 104 - pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); 124 + ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ); 105 125 106 - div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 107 - freq = div * ref_rate; 126 + ar724x_clk_init(ref_clk, ath79_pll_base); 108 127 109 - div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 110 - freq /= div; 111 - 112 - cpu_rate = freq; 113 - 114 - div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 115 - ddr_rate = freq / div; 116 - 117 - div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 118 - ahb_rate = cpu_rate / div; 119 - 120 - ath79_add_sys_clkdev("ref", ref_rate); 121 - clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); 122 - clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); 123 - clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); 128 + /* just make happy plat_time_init() from arch/mips/ath79/setup.c */ 129 + clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); 130 + clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); 131 + clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); 124 132 125 133 clk_add_alias("wdt", NULL, "ahb", NULL); 126 134 clk_add_alias("uart", NULL, "ahb", NULL); ··· 434 420 qca955x_clocks_init(); 435 421 else 436 422 BUG(); 437 - 438 - of_clk_init(NULL); 439 423 } 440 424 441 425 unsigned long __init ··· 460 448 461 449 CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); 462 450 CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); 463 - CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt); 464 451 CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt); 465 452 CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); 466 453 CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); 454 + 455 + static void __init ath79_clocks_init_dt_ng(struct device_node *np) 456 + { 457 + struct clk *ref_clk; 458 + void __iomem *pll_base; 459 + const char *dnfn = of_node_full_name(np); 460 + 461 + ref_clk = of_clk_get(np, 0); 462 + if (IS_ERR(ref_clk)) { 463 + pr_err("%s: of_clk_get failed\n", dnfn); 464 + goto err; 465 + } 466 + 467 + pll_base = of_iomap(np, 0); 468 + if (!pll_base) { 469 + pr_err("%s: can't map pll registers\n", dnfn); 470 + goto err_clk; 471 + } 472 + 473 + ar724x_clk_init(ref_clk, pll_base); 474 + 475 + if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 476 + pr_err("%s: could not register clk provider\n", dnfn); 477 + goto err_clk; 478 + } 479 + 480 + return; 481 + 482 + err_clk: 483 + clk_put(ref_clk); 484 + 485 + err: 486 + return; 487 + } 488 + CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); 467 489 #endif
+36
arch/mips/ath79/setup.c
··· 17 17 #include <linux/bootmem.h> 18 18 #include <linux/err.h> 19 19 #include <linux/clk.h> 20 + #include <linux/clk-provider.h> 20 21 #include <linux/of_platform.h> 21 22 #include <linux/of_fdt.h> 22 23 ··· 223 222 pm_power_off = ath79_halt; 224 223 } 225 224 225 + static void __init ath79_of_plat_time_init(void) 226 + { 227 + struct device_node *np; 228 + struct clk *clk; 229 + unsigned long cpu_clk_rate; 230 + 231 + of_clk_init(NULL); 232 + 233 + np = of_get_cpu_node(0, NULL); 234 + if (!np) { 235 + pr_err("Failed to get CPU node\n"); 236 + return; 237 + } 238 + 239 + clk = of_clk_get(np, 0); 240 + if (IS_ERR(clk)) { 241 + pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); 242 + return; 243 + } 244 + 245 + cpu_clk_rate = clk_get_rate(clk); 246 + 247 + pr_info("CPU clock: %lu.%03lu MHz\n", 248 + cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000); 249 + 250 + mips_hpt_frequency = cpu_clk_rate / 2; 251 + 252 + clk_put(clk); 253 + } 254 + 226 255 void __init plat_time_init(void) 227 256 { 228 257 unsigned long cpu_clk_rate; 229 258 unsigned long ahb_clk_rate; 230 259 unsigned long ddr_clk_rate; 231 260 unsigned long ref_clk_rate; 261 + 262 + if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) { 263 + ath79_of_plat_time_init(); 264 + return; 265 + } 232 266 233 267 ath79_clocks_init(); 234 268
+1
arch/mips/boot/dts/qca/ar9132.dtsi
··· 13 13 cpu@0 { 14 14 device_type = "cpu"; 15 15 compatible = "mips,mips24Kc"; 16 + clocks = <&pll ATH79_CLK_CPU>; 16 17 reg = <0>; 17 18 }; 18 19 };