aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntony Pavlov <antonynpavlov@gmail.com>2016-03-16 23:34:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-05-13 08:01:45 -0400
commit3bdf1071ba7de08c55a5cce54964ded7c0c8540d (patch)
tree8fa1452be032fd8c72d8adfcf6a55349a0d940f3
parentaf5ad0de22480a452049e0e942b10af77ef60530 (diff)
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>
-rw-r--r--arch/mips/ath79/clock.c96
-rw-r--r--arch/mips/ath79/setup.c36
-rw-r--r--arch/mips/boot/dts/qca/ar9132.dtsi1
3 files changed, 108 insertions, 25 deletions
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index c3a94ead06ab..79fb8b44ba09 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -18,6 +18,8 @@
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/clkdev.h> 19#include <linux/clkdev.h>
20#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
21#include <dt-bindings/clock/ath79-clk.h> 23#include <dt-bindings/clock/ath79-clk.h>
22 24
23#include <asm/div64.h> 25#include <asm/div64.h>
@@ -25,6 +27,7 @@
25#include <asm/mach-ath79/ath79.h> 27#include <asm/mach-ath79/ath79.h>
26#include <asm/mach-ath79/ar71xx_regs.h> 28#include <asm/mach-ath79/ar71xx_regs.h>
27#include "common.h" 29#include "common.h"
30#include "machtypes.h"
28 31
29#define AR71XX_BASE_FREQ 40000000 32#define AR71XX_BASE_FREQ 40000000
30#define AR724X_BASE_FREQ 40000000 33#define AR724X_BASE_FREQ 40000000
@@ -87,37 +90,48 @@ static void __init ar71xx_clocks_init(void)
87 clk_add_alias("uart", NULL, "ahb", NULL); 90 clk_add_alias("uart", NULL, "ahb", NULL);
88} 91}
89 92
90static void __init ar724x_clocks_init(void) 93static struct clk * __init ath79_reg_ffclk(const char *name,
94 const char *parent_name, unsigned int mult, unsigned int div)
91{ 95{
92 unsigned long ref_rate; 96 struct clk *clk;
93 unsigned long cpu_rate;
94 unsigned long ddr_rate;
95 unsigned long ahb_rate;
96 u32 pll;
97 u32 freq;
98 u32 div;
99 97
100 ref_rate = AR724X_BASE_FREQ; 98 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
101 pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); 99 if (!clk)
100 panic("failed to allocate %s clock structure", name);
102 101
103 div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); 102 return clk;
104 freq = div * ref_rate; 103}
104
105static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
106{
107 u32 pll;
108 u32 mult, div, ddr_div, ahb_div;
105 109
110 pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
111
112 mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
106 div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; 113 div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
107 freq /= div;
108 114
109 cpu_rate = freq; 115 ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
116 ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
110 117
111 div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 118 clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div);
112 ddr_rate = freq / div; 119 clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div);
120 clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div);
121}
113 122
114 div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 123static void __init ar724x_clocks_init(void)
115 ahb_rate = cpu_rate / div; 124{
125 struct clk *ref_clk;
116 126
117 ath79_add_sys_clkdev("ref", ref_rate); 127 ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
118 clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); 128
119 clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); 129 ar724x_clk_init(ref_clk, ath79_pll_base);
120 clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); 130
131 /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
132 clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
133 clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
134 clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
121 135
122 clk_add_alias("wdt", NULL, "ahb", NULL); 136 clk_add_alias("wdt", NULL, "ahb", NULL);
123 clk_add_alias("uart", NULL, "ahb", NULL); 137 clk_add_alias("uart", NULL, "ahb", NULL);
@@ -420,8 +434,6 @@ void __init ath79_clocks_init(void)
420 qca955x_clocks_init(); 434 qca955x_clocks_init();
421 else 435 else
422 BUG(); 436 BUG();
423
424 of_clk_init(NULL);
425} 437}
426 438
427unsigned long __init 439unsigned long __init
@@ -448,8 +460,42 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
448 460
449CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); 461CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
450CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); 462CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
451CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt);
452CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt); 463CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
453CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); 464CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
454CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); 465CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
466
467static void __init ath79_clocks_init_dt_ng(struct device_node *np)
468{
469 struct clk *ref_clk;
470 void __iomem *pll_base;
471 const char *dnfn = of_node_full_name(np);
472
473 ref_clk = of_clk_get(np, 0);
474 if (IS_ERR(ref_clk)) {
475 pr_err("%s: of_clk_get failed\n", dnfn);
476 goto err;
477 }
478
479 pll_base = of_iomap(np, 0);
480 if (!pll_base) {
481 pr_err("%s: can't map pll registers\n", dnfn);
482 goto err_clk;
483 }
484
485 ar724x_clk_init(ref_clk, pll_base);
486
487 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
488 pr_err("%s: could not register clk provider\n", dnfn);
489 goto err_clk;
490 }
491
492 return;
493
494err_clk:
495 clk_put(ref_clk);
496
497err:
498 return;
499}
500CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng);
455#endif 501#endif
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 01808e85e263..01af43281bc7 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -17,6 +17,7 @@
17#include <linux/bootmem.h> 17#include <linux/bootmem.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/clk-provider.h>
20#include <linux/of_platform.h> 21#include <linux/of_platform.h>
21#include <linux/of_fdt.h> 22#include <linux/of_fdt.h>
22 23
@@ -222,6 +223,36 @@ void __init plat_mem_setup(void)
222 pm_power_off = ath79_halt; 223 pm_power_off = ath79_halt;
223} 224}
224 225
226static void __init ath79_of_plat_time_init(void)
227{
228 struct device_node *np;
229 struct clk *clk;
230 unsigned long cpu_clk_rate;
231
232 of_clk_init(NULL);
233
234 np = of_get_cpu_node(0, NULL);
235 if (!np) {
236 pr_err("Failed to get CPU node\n");
237 return;
238 }
239
240 clk = of_clk_get(np, 0);
241 if (IS_ERR(clk)) {
242 pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
243 return;
244 }
245
246 cpu_clk_rate = clk_get_rate(clk);
247
248 pr_info("CPU clock: %lu.%03lu MHz\n",
249 cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000);
250
251 mips_hpt_frequency = cpu_clk_rate / 2;
252
253 clk_put(clk);
254}
255
225void __init plat_time_init(void) 256void __init plat_time_init(void)
226{ 257{
227 unsigned long cpu_clk_rate; 258 unsigned long cpu_clk_rate;
@@ -229,6 +260,11 @@ void __init plat_time_init(void)
229 unsigned long ddr_clk_rate; 260 unsigned long ddr_clk_rate;
230 unsigned long ref_clk_rate; 261 unsigned long ref_clk_rate;
231 262
263 if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
264 ath79_of_plat_time_init();
265 return;
266 }
267
232 ath79_clocks_init(); 268 ath79_clocks_init();
233 269
234 cpu_clk_rate = ath79_get_sys_clk_rate("cpu"); 270 cpu_clk_rate = ath79_get_sys_clk_rate("cpu");
diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi
index 2f9a3eee9fe6..302f0a8d2988 100644
--- a/arch/mips/boot/dts/qca/ar9132.dtsi
+++ b/arch/mips/boot/dts/qca/ar9132.dtsi
@@ -13,6 +13,7 @@
13 cpu@0 { 13 cpu@0 {
14 device_type = "cpu"; 14 device_type = "cpu";
15 compatible = "mips,mips24Kc"; 15 compatible = "mips,mips24Kc";
16 clocks = <&pll ATH79_CLK_CPU>;
16 reg = <0>; 17 reg = <0>;
17 }; 18 };
18 }; 19 };