Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / mips / ath79 / clock.c
1 /*
2  *  Atheros AR71XX/AR724X/AR913X common routines
3  *
4  *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5  *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
6  *
7  *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/err.h>
18 #include <linux/clk.h>
19 #include <linux/clkdev.h>
20
21 #include <asm/div64.h>
22
23 #include <asm/mach-ath79/ath79.h>
24 #include <asm/mach-ath79/ar71xx_regs.h>
25 #include "common.h"
26
27 #define AR71XX_BASE_FREQ        40000000
28 #define AR724X_BASE_FREQ        5000000
29 #define AR913X_BASE_FREQ        5000000
30
31 struct clk {
32         unsigned long rate;
33 };
34
35 static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
36 {
37         struct clk *clk;
38         int err;
39
40         clk = kzalloc(sizeof(*clk), GFP_KERNEL);
41         if (!clk)
42                 panic("failed to allocate %s clock structure", id);
43
44         clk->rate = rate;
45
46         err = clk_register_clkdev(clk, id, NULL);
47         if (err)
48                 panic("unable to register %s clock device", id);
49 }
50
51 static void __init ar71xx_clocks_init(void)
52 {
53         unsigned long ref_rate;
54         unsigned long cpu_rate;
55         unsigned long ddr_rate;
56         unsigned long ahb_rate;
57         u32 pll;
58         u32 freq;
59         u32 div;
60
61         ref_rate = AR71XX_BASE_FREQ;
62
63         pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
64
65         div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
66         freq = div * ref_rate;
67
68         div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
69         cpu_rate = freq / div;
70
71         div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
72         ddr_rate = freq / div;
73
74         div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
75         ahb_rate = cpu_rate / div;
76
77         ath79_add_sys_clkdev("ref", ref_rate);
78         ath79_add_sys_clkdev("cpu", cpu_rate);
79         ath79_add_sys_clkdev("ddr", ddr_rate);
80         ath79_add_sys_clkdev("ahb", ahb_rate);
81
82         clk_add_alias("wdt", NULL, "ahb", NULL);
83         clk_add_alias("uart", NULL, "ahb", NULL);
84 }
85
86 static void __init ar724x_clocks_init(void)
87 {
88         unsigned long ref_rate;
89         unsigned long cpu_rate;
90         unsigned long ddr_rate;
91         unsigned long ahb_rate;
92         u32 pll;
93         u32 freq;
94         u32 div;
95
96         ref_rate = AR724X_BASE_FREQ;
97         pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
98
99         div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
100         freq = div * ref_rate;
101
102         div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
103         freq *= div;
104
105         cpu_rate = freq;
106
107         div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
108         ddr_rate = freq / div;
109
110         div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
111         ahb_rate = cpu_rate / div;
112
113         ath79_add_sys_clkdev("ref", ref_rate);
114         ath79_add_sys_clkdev("cpu", cpu_rate);
115         ath79_add_sys_clkdev("ddr", ddr_rate);
116         ath79_add_sys_clkdev("ahb", ahb_rate);
117
118         clk_add_alias("wdt", NULL, "ahb", NULL);
119         clk_add_alias("uart", NULL, "ahb", NULL);
120 }
121
122 static void __init ar913x_clocks_init(void)
123 {
124         unsigned long ref_rate;
125         unsigned long cpu_rate;
126         unsigned long ddr_rate;
127         unsigned long ahb_rate;
128         u32 pll;
129         u32 freq;
130         u32 div;
131
132         ref_rate = AR913X_BASE_FREQ;
133         pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
134
135         div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
136         freq = div * ref_rate;
137
138         cpu_rate = freq;
139
140         div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
141         ddr_rate = freq / div;
142
143         div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
144         ahb_rate = cpu_rate / div;
145
146         ath79_add_sys_clkdev("ref", ref_rate);
147         ath79_add_sys_clkdev("cpu", cpu_rate);
148         ath79_add_sys_clkdev("ddr", ddr_rate);
149         ath79_add_sys_clkdev("ahb", ahb_rate);
150
151         clk_add_alias("wdt", NULL, "ahb", NULL);
152         clk_add_alias("uart", NULL, "ahb", NULL);
153 }
154
155 static void __init ar933x_clocks_init(void)
156 {
157         unsigned long ref_rate;
158         unsigned long cpu_rate;
159         unsigned long ddr_rate;
160         unsigned long ahb_rate;
161         u32 clock_ctrl;
162         u32 cpu_config;
163         u32 freq;
164         u32 t;
165
166         t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
167         if (t & AR933X_BOOTSTRAP_REF_CLK_40)
168                 ref_rate = (40 * 1000 * 1000);
169         else
170                 ref_rate = (25 * 1000 * 1000);
171
172         clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
173         if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
174                 cpu_rate = ref_rate;
175                 ahb_rate = ref_rate;
176                 ddr_rate = ref_rate;
177         } else {
178                 cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
179
180                 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
181                     AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
182                 freq = ref_rate / t;
183
184                 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
185                     AR933X_PLL_CPU_CONFIG_NINT_MASK;
186                 freq *= t;
187
188                 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
189                     AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
190                 if (t == 0)
191                         t = 1;
192
193                 freq >>= t;
194
195                 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
196                      AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
197                 cpu_rate = freq / t;
198
199                 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
200                       AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
201                 ddr_rate = freq / t;
202
203                 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
204                      AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
205                 ahb_rate = freq / t;
206         }
207
208         ath79_add_sys_clkdev("ref", ref_rate);
209         ath79_add_sys_clkdev("cpu", cpu_rate);
210         ath79_add_sys_clkdev("ddr", ddr_rate);
211         ath79_add_sys_clkdev("ahb", ahb_rate);
212
213         clk_add_alias("wdt", NULL, "ahb", NULL);
214         clk_add_alias("uart", NULL, "ref", NULL);
215 }
216
217 static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
218                                       u32 frac, u32 out_div)
219 {
220         u64 t;
221         u32 ret;
222
223         t = ref;
224         t *= nint;
225         do_div(t, ref_div);
226         ret = t;
227
228         t = ref;
229         t *= nfrac;
230         do_div(t, ref_div * frac);
231         ret += t;
232
233         ret /= (1 << out_div);
234         return ret;
235 }
236
237 static void __init ar934x_clocks_init(void)
238 {
239         unsigned long ref_rate;
240         unsigned long cpu_rate;
241         unsigned long ddr_rate;
242         unsigned long ahb_rate;
243         u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
244         u32 cpu_pll, ddr_pll;
245         u32 bootstrap;
246         void __iomem *dpll_base;
247
248         dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
249
250         bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
251         if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
252                 ref_rate = 40 * 1000 * 1000;
253         else
254                 ref_rate = 25 * 1000 * 1000;
255
256         pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
257         if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
258                 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
259                           AR934X_SRIF_DPLL2_OUTDIV_MASK;
260                 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
261                 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
262                        AR934X_SRIF_DPLL1_NINT_MASK;
263                 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
264                 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
265                           AR934X_SRIF_DPLL1_REFDIV_MASK;
266                 frac = 1 << 18;
267         } else {
268                 pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
269                 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
270                         AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
271                 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
272                           AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
273                 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
274                        AR934X_PLL_CPU_CONFIG_NINT_MASK;
275                 nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
276                         AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
277                 frac = 1 << 6;
278         }
279
280         cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
281                                       nfrac, frac, out_div);
282
283         pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
284         if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
285                 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
286                           AR934X_SRIF_DPLL2_OUTDIV_MASK;
287                 pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
288                 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
289                        AR934X_SRIF_DPLL1_NINT_MASK;
290                 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
291                 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
292                           AR934X_SRIF_DPLL1_REFDIV_MASK;
293                 frac = 1 << 18;
294         } else {
295                 pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
296                 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
297                           AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
298                 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
299                            AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
300                 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
301                        AR934X_PLL_DDR_CONFIG_NINT_MASK;
302                 nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
303                         AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
304                 frac = 1 << 10;
305         }
306
307         ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
308                                       nfrac, frac, out_div);
309
310         clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
311
312         postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
313                   AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
314
315         if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
316                 cpu_rate = ref_rate;
317         else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
318                 cpu_rate = cpu_pll / (postdiv + 1);
319         else
320                 cpu_rate = ddr_pll / (postdiv + 1);
321
322         postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
323                   AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
324
325         if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
326                 ddr_rate = ref_rate;
327         else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
328                 ddr_rate = ddr_pll / (postdiv + 1);
329         else
330                 ddr_rate = cpu_pll / (postdiv + 1);
331
332         postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
333                   AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
334
335         if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
336                 ahb_rate = ref_rate;
337         else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
338                 ahb_rate = ddr_pll / (postdiv + 1);
339         else
340                 ahb_rate = cpu_pll / (postdiv + 1);
341
342         ath79_add_sys_clkdev("ref", ref_rate);
343         ath79_add_sys_clkdev("cpu", cpu_rate);
344         ath79_add_sys_clkdev("ddr", ddr_rate);
345         ath79_add_sys_clkdev("ahb", ahb_rate);
346
347         clk_add_alias("wdt", NULL, "ref", NULL);
348         clk_add_alias("uart", NULL, "ref", NULL);
349
350         iounmap(dpll_base);
351 }
352
353 static void __init qca955x_clocks_init(void)
354 {
355         unsigned long ref_rate;
356         unsigned long cpu_rate;
357         unsigned long ddr_rate;
358         unsigned long ahb_rate;
359         u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
360         u32 cpu_pll, ddr_pll;
361         u32 bootstrap;
362
363         bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
364         if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
365                 ref_rate = 40 * 1000 * 1000;
366         else
367                 ref_rate = 25 * 1000 * 1000;
368
369         pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
370         out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
371                   QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
372         ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
373                   QCA955X_PLL_CPU_CONFIG_REFDIV_MASK;
374         nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) &
375                QCA955X_PLL_CPU_CONFIG_NINT_MASK;
376         frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
377                QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
378
379         cpu_pll = nint * ref_rate / ref_div;
380         cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
381         cpu_pll /= (1 << out_div);
382
383         pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
384         out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
385                   QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
386         ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
387                   QCA955X_PLL_DDR_CONFIG_REFDIV_MASK;
388         nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) &
389                QCA955X_PLL_DDR_CONFIG_NINT_MASK;
390         frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
391                QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
392
393         ddr_pll = nint * ref_rate / ref_div;
394         ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
395         ddr_pll /= (1 << out_div);
396
397         clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
398
399         postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
400                   QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
401
402         if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
403                 cpu_rate = ref_rate;
404         else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
405                 cpu_rate = ddr_pll / (postdiv + 1);
406         else
407                 cpu_rate = cpu_pll / (postdiv + 1);
408
409         postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
410                   QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
411
412         if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
413                 ddr_rate = ref_rate;
414         else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
415                 ddr_rate = cpu_pll / (postdiv + 1);
416         else
417                 ddr_rate = ddr_pll / (postdiv + 1);
418
419         postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
420                   QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
421
422         if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
423                 ahb_rate = ref_rate;
424         else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
425                 ahb_rate = ddr_pll / (postdiv + 1);
426         else
427                 ahb_rate = cpu_pll / (postdiv + 1);
428
429         ath79_add_sys_clkdev("ref", ref_rate);
430         ath79_add_sys_clkdev("cpu", cpu_rate);
431         ath79_add_sys_clkdev("ddr", ddr_rate);
432         ath79_add_sys_clkdev("ahb", ahb_rate);
433
434         clk_add_alias("wdt", NULL, "ref", NULL);
435         clk_add_alias("uart", NULL, "ref", NULL);
436 }
437
438 void __init ath79_clocks_init(void)
439 {
440         if (soc_is_ar71xx())
441                 ar71xx_clocks_init();
442         else if (soc_is_ar724x())
443                 ar724x_clocks_init();
444         else if (soc_is_ar913x())
445                 ar913x_clocks_init();
446         else if (soc_is_ar933x())
447                 ar933x_clocks_init();
448         else if (soc_is_ar934x())
449                 ar934x_clocks_init();
450         else if (soc_is_qca955x())
451                 qca955x_clocks_init();
452         else
453                 BUG();
454 }
455
456 unsigned long __init
457 ath79_get_sys_clk_rate(const char *id)
458 {
459         struct clk *clk;
460         unsigned long rate;
461
462         clk = clk_get(NULL, id);
463         if (IS_ERR(clk))
464                 panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
465
466         rate = clk_get_rate(clk);
467         clk_put(clk);
468
469         return rate;
470 }
471
472 /*
473  * Linux clock API
474  */
475 int clk_enable(struct clk *clk)
476 {
477         return 0;
478 }
479 EXPORT_SYMBOL(clk_enable);
480
481 void clk_disable(struct clk *clk)
482 {
483 }
484 EXPORT_SYMBOL(clk_disable);
485
486 unsigned long clk_get_rate(struct clk *clk)
487 {
488         return clk->rate;
489 }
490 EXPORT_SYMBOL(clk_get_rate);