]>
Commit | Line | Data |
---|---|---|
d4a67d9d GJ |
1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X common routines | |
3 | * | |
8889612b | 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
d4a67d9d GJ |
5 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> |
6 | * | |
8889612b GJ |
7 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP |
8 | * | |
d4a67d9d GJ |
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> | |
2c4f1ac5 | 19 | #include <linux/clkdev.h> |
d4a67d9d | 20 | |
97541ccf GJ |
21 | #include <asm/div64.h> |
22 | ||
d4a67d9d GJ |
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 | ||
2c4f1ac5 GJ |
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 | } | |
d4a67d9d GJ |
50 | |
51 | static void __init ar71xx_clocks_init(void) | |
52 | { | |
6612a688 GJ |
53 | unsigned long ref_rate; |
54 | unsigned long cpu_rate; | |
55 | unsigned long ddr_rate; | |
56 | unsigned long ahb_rate; | |
d4a67d9d GJ |
57 | u32 pll; |
58 | u32 freq; | |
59 | u32 div; | |
60 | ||
6612a688 | 61 | ref_rate = AR71XX_BASE_FREQ; |
d4a67d9d GJ |
62 | |
63 | pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); | |
64 | ||
65 | div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; | |
6612a688 | 66 | freq = div * ref_rate; |
d4a67d9d GJ |
67 | |
68 | div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; | |
6612a688 | 69 | cpu_rate = freq / div; |
d4a67d9d GJ |
70 | |
71 | div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; | |
6612a688 | 72 | ddr_rate = freq / div; |
d4a67d9d GJ |
73 | |
74 | div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | |
6612a688 GJ |
75 | ahb_rate = cpu_rate / div; |
76 | ||
2c4f1ac5 GJ |
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); | |
d4a67d9d | 81 | |
2c4f1ac5 GJ |
82 | clk_add_alias("wdt", NULL, "ahb", NULL); |
83 | clk_add_alias("uart", NULL, "ahb", NULL); | |
d4a67d9d GJ |
84 | } |
85 | ||
86 | static void __init ar724x_clocks_init(void) | |
87 | { | |
6612a688 GJ |
88 | unsigned long ref_rate; |
89 | unsigned long cpu_rate; | |
90 | unsigned long ddr_rate; | |
91 | unsigned long ahb_rate; | |
d4a67d9d GJ |
92 | u32 pll; |
93 | u32 freq; | |
94 | u32 div; | |
95 | ||
6612a688 | 96 | ref_rate = AR724X_BASE_FREQ; |
d4a67d9d GJ |
97 | pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); |
98 | ||
99 | div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); | |
6612a688 | 100 | freq = div * ref_rate; |
d4a67d9d GJ |
101 | |
102 | div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); | |
103 | freq *= div; | |
104 | ||
6612a688 | 105 | cpu_rate = freq; |
d4a67d9d GJ |
106 | |
107 | div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | |
6612a688 | 108 | ddr_rate = freq / div; |
d4a67d9d GJ |
109 | |
110 | div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | |
6612a688 GJ |
111 | ahb_rate = cpu_rate / div; |
112 | ||
2c4f1ac5 GJ |
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); | |
d4a67d9d | 117 | |
2c4f1ac5 GJ |
118 | clk_add_alias("wdt", NULL, "ahb", NULL); |
119 | clk_add_alias("uart", NULL, "ahb", NULL); | |
d4a67d9d GJ |
120 | } |
121 | ||
122 | static void __init ar913x_clocks_init(void) | |
123 | { | |
6612a688 GJ |
124 | unsigned long ref_rate; |
125 | unsigned long cpu_rate; | |
126 | unsigned long ddr_rate; | |
127 | unsigned long ahb_rate; | |
d4a67d9d GJ |
128 | u32 pll; |
129 | u32 freq; | |
130 | u32 div; | |
131 | ||
6612a688 | 132 | ref_rate = AR913X_BASE_FREQ; |
d4a67d9d GJ |
133 | pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); |
134 | ||
135 | div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); | |
6612a688 | 136 | freq = div * ref_rate; |
d4a67d9d | 137 | |
6612a688 | 138 | cpu_rate = freq; |
d4a67d9d GJ |
139 | |
140 | div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1; | |
6612a688 | 141 | ddr_rate = freq / div; |
d4a67d9d GJ |
142 | |
143 | div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2; | |
6612a688 GJ |
144 | ahb_rate = cpu_rate / div; |
145 | ||
2c4f1ac5 GJ |
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); | |
d4a67d9d | 150 | |
2c4f1ac5 GJ |
151 | clk_add_alias("wdt", NULL, "ahb", NULL); |
152 | clk_add_alias("uart", NULL, "ahb", NULL); | |
d4a67d9d GJ |
153 | } |
154 | ||
04225e1d GJ |
155 | static void __init ar933x_clocks_init(void) |
156 | { | |
6612a688 GJ |
157 | unsigned long ref_rate; |
158 | unsigned long cpu_rate; | |
159 | unsigned long ddr_rate; | |
160 | unsigned long ahb_rate; | |
04225e1d GJ |
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) | |
6612a688 | 168 | ref_rate = (40 * 1000 * 1000); |
04225e1d | 169 | else |
6612a688 | 170 | ref_rate = (25 * 1000 * 1000); |
04225e1d GJ |
171 | |
172 | clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); | |
173 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { | |
6612a688 GJ |
174 | cpu_rate = ref_rate; |
175 | ahb_rate = ref_rate; | |
176 | ddr_rate = ref_rate; | |
04225e1d GJ |
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; | |
6612a688 | 182 | freq = ref_rate / t; |
04225e1d GJ |
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; | |
6612a688 | 197 | cpu_rate = freq / t; |
04225e1d GJ |
198 | |
199 | t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & | |
200 | AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; | |
6612a688 | 201 | ddr_rate = freq / t; |
04225e1d GJ |
202 | |
203 | t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & | |
204 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; | |
6612a688 | 205 | ahb_rate = freq / t; |
04225e1d GJ |
206 | } |
207 | ||
2c4f1ac5 GJ |
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); | |
6612a688 | 212 | |
2c4f1ac5 GJ |
213 | clk_add_alias("wdt", NULL, "ahb", NULL); |
214 | clk_add_alias("uart", NULL, "ref", NULL); | |
04225e1d GJ |
215 | } |
216 | ||
97541ccf GJ |
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 | ||
837f036c | 223 | t = ref; |
97541ccf GJ |
224 | t *= nint; |
225 | do_div(t, ref_div); | |
226 | ret = t; | |
227 | ||
837f036c | 228 | t = ref; |
97541ccf GJ |
229 | t *= nfrac; |
230 | do_div(t, ref_div * frac); | |
231 | ret += t; | |
232 | ||
233 | ret /= (1 << out_div); | |
234 | return ret; | |
235 | } | |
236 | ||
8889612b GJ |
237 | static void __init ar934x_clocks_init(void) |
238 | { | |
6612a688 GJ |
239 | unsigned long ref_rate; |
240 | unsigned long cpu_rate; | |
241 | unsigned long ddr_rate; | |
242 | unsigned long ahb_rate; | |
97541ccf | 243 | u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; |
8889612b GJ |
244 | u32 cpu_pll, ddr_pll; |
245 | u32 bootstrap; | |
97541ccf GJ |
246 | void __iomem *dpll_base; |
247 | ||
248 | dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); | |
8889612b GJ |
249 | |
250 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | |
70342287 | 251 | if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) |
6612a688 | 252 | ref_rate = 40 * 1000 * 1000; |
8889612b | 253 | else |
6612a688 | 254 | ref_rate = 25 * 1000 * 1000; |
8889612b | 255 | |
97541ccf GJ |
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 | ||
6612a688 | 280 | cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, |
97541ccf GJ |
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 | ||
6612a688 | 307 | ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, |
97541ccf | 308 | nfrac, frac, out_div); |
8889612b GJ |
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) | |
6612a688 | 316 | cpu_rate = ref_rate; |
8889612b | 317 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) |
6612a688 | 318 | cpu_rate = cpu_pll / (postdiv + 1); |
8889612b | 319 | else |
6612a688 | 320 | cpu_rate = ddr_pll / (postdiv + 1); |
8889612b GJ |
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) | |
6612a688 | 326 | ddr_rate = ref_rate; |
8889612b | 327 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) |
6612a688 | 328 | ddr_rate = ddr_pll / (postdiv + 1); |
8889612b | 329 | else |
6612a688 | 330 | ddr_rate = cpu_pll / (postdiv + 1); |
8889612b GJ |
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) | |
6612a688 | 336 | ahb_rate = ref_rate; |
8889612b | 337 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) |
6612a688 | 338 | ahb_rate = ddr_pll / (postdiv + 1); |
8889612b | 339 | else |
6612a688 GJ |
340 | ahb_rate = cpu_pll / (postdiv + 1); |
341 | ||
2c4f1ac5 GJ |
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); | |
8889612b | 346 | |
2c4f1ac5 GJ |
347 | clk_add_alias("wdt", NULL, "ref", NULL); |
348 | clk_add_alias("uart", NULL, "ref", NULL); | |
97541ccf GJ |
349 | |
350 | iounmap(dpll_base); | |
8889612b GJ |
351 | } |
352 | ||
41583c05 GJ |
353 | static void __init qca955x_clocks_init(void) |
354 | { | |
6612a688 GJ |
355 | unsigned long ref_rate; |
356 | unsigned long cpu_rate; | |
357 | unsigned long ddr_rate; | |
358 | unsigned long ahb_rate; | |
41583c05 GJ |
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) | |
6612a688 | 365 | ref_rate = 40 * 1000 * 1000; |
41583c05 | 366 | else |
6612a688 | 367 | ref_rate = 25 * 1000 * 1000; |
41583c05 GJ |
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 | ||
6612a688 GJ |
379 | cpu_pll = nint * ref_rate / ref_div; |
380 | cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); | |
41583c05 GJ |
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 | ||
6612a688 GJ |
393 | ddr_pll = nint * ref_rate / ref_div; |
394 | ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); | |
41583c05 GJ |
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) | |
6612a688 | 403 | cpu_rate = ref_rate; |
41583c05 | 404 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) |
6612a688 | 405 | cpu_rate = ddr_pll / (postdiv + 1); |
41583c05 | 406 | else |
6612a688 | 407 | cpu_rate = cpu_pll / (postdiv + 1); |
41583c05 GJ |
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) | |
6612a688 | 413 | ddr_rate = ref_rate; |
41583c05 | 414 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) |
6612a688 | 415 | ddr_rate = cpu_pll / (postdiv + 1); |
41583c05 | 416 | else |
6612a688 | 417 | ddr_rate = ddr_pll / (postdiv + 1); |
41583c05 GJ |
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) | |
6612a688 | 423 | ahb_rate = ref_rate; |
41583c05 | 424 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) |
6612a688 | 425 | ahb_rate = ddr_pll / (postdiv + 1); |
41583c05 | 426 | else |
6612a688 GJ |
427 | ahb_rate = cpu_pll / (postdiv + 1); |
428 | ||
2c4f1ac5 GJ |
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); | |
41583c05 | 433 | |
2c4f1ac5 GJ |
434 | clk_add_alias("wdt", NULL, "ref", NULL); |
435 | clk_add_alias("uart", NULL, "ref", NULL); | |
41583c05 GJ |
436 | } |
437 | ||
d4a67d9d GJ |
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(); | |
04225e1d GJ |
446 | else if (soc_is_ar933x()) |
447 | ar933x_clocks_init(); | |
8889612b GJ |
448 | else if (soc_is_ar934x()) |
449 | ar934x_clocks_init(); | |
41583c05 GJ |
450 | else if (soc_is_qca955x()) |
451 | qca955x_clocks_init(); | |
d4a67d9d GJ |
452 | else |
453 | BUG(); | |
d4a67d9d GJ |
454 | } |
455 | ||
23107802 GJ |
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 | ||
d4a67d9d GJ |
472 | /* |
473 | * Linux clock API | |
474 | */ | |
d4a67d9d GJ |
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); |