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