1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright 2013 Emilio López |
4 | * |
5 | * Emilio López <emilio@elopez.com.ar> |
6 | */ |
7 | |
8 | #include <linux/clk.h> |
9 | #include <linux/clk-provider.h> |
10 | #include <linux/clkdev.h> |
11 | #include <linux/io.h> |
12 | #include <linux/of.h> |
13 | #include <linux/of_address.h> |
14 | #include <linux/reset-controller.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/spinlock.h> |
17 | #include <linux/log2.h> |
18 | |
19 | #include "clk-factors.h" |
20 | |
21 | static DEFINE_SPINLOCK(clk_lock); |
22 | |
23 | /* Maximum number of parents our clocks have */ |
24 | #define SUNXI_MAX_PARENTS 5 |
25 | |
26 | /* |
27 | * sun4i_get_pll1_factors() - calculates n, k, m, p factors for PLL1 |
28 | * PLL1 rate is calculated as follows |
29 | * rate = (parent_rate * n * (k + 1) >> p) / (m + 1); |
30 | * parent_rate is always 24Mhz |
31 | */ |
32 | |
33 | static void sun4i_get_pll1_factors(struct factors_request *req) |
34 | { |
35 | u8 div; |
36 | |
37 | /* Normalize value to a 6M multiple */ |
38 | div = req->rate / 6000000; |
39 | req->rate = 6000000 * div; |
40 | |
41 | /* m is always zero for pll1 */ |
42 | req->m = 0; |
43 | |
44 | /* k is 1 only on these cases */ |
45 | if (req->rate >= 768000000 || req->rate == 42000000 || |
46 | req->rate == 54000000) |
47 | req->k = 1; |
48 | else |
49 | req->k = 0; |
50 | |
51 | /* p will be 3 for divs under 10 */ |
52 | if (div < 10) |
53 | req->p = 3; |
54 | |
55 | /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ |
56 | else if (div < 20 || (div < 32 && (div & 1))) |
57 | req->p = 2; |
58 | |
59 | /* p will be 1 for even divs under 32, divs under 40 and odd pairs |
60 | * of divs between 40-62 */ |
61 | else if (div < 40 || (div < 64 && (div & 2))) |
62 | req->p = 1; |
63 | |
64 | /* any other entries have p = 0 */ |
65 | else |
66 | req->p = 0; |
67 | |
68 | /* calculate a suitable n based on k and p */ |
69 | div <<= req->p; |
70 | div /= (req->k + 1); |
71 | req->n = div / 4; |
72 | } |
73 | |
74 | /* |
75 | * sun6i_a31_get_pll1_factors() - calculates n, k and m factors for PLL1 |
76 | * PLL1 rate is calculated as follows |
77 | * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); |
78 | * parent_rate should always be 24MHz |
79 | */ |
80 | static void sun6i_a31_get_pll1_factors(struct factors_request *req) |
81 | { |
82 | /* |
83 | * We can operate only on MHz, this will make our life easier |
84 | * later. |
85 | */ |
86 | u32 freq_mhz = req->rate / 1000000; |
87 | u32 parent_freq_mhz = req->parent_rate / 1000000; |
88 | |
89 | /* |
90 | * Round down the frequency to the closest multiple of either |
91 | * 6 or 16 |
92 | */ |
93 | u32 round_freq_6 = rounddown(freq_mhz, 6); |
94 | u32 round_freq_16 = round_down(freq_mhz, 16); |
95 | |
96 | if (round_freq_6 > round_freq_16) |
97 | freq_mhz = round_freq_6; |
98 | else |
99 | freq_mhz = round_freq_16; |
100 | |
101 | req->rate = freq_mhz * 1000000; |
102 | |
103 | /* If the frequency is a multiple of 32 MHz, k is always 3 */ |
104 | if (!(freq_mhz % 32)) |
105 | req->k = 3; |
106 | /* If the frequency is a multiple of 9 MHz, k is always 2 */ |
107 | else if (!(freq_mhz % 9)) |
108 | req->k = 2; |
109 | /* If the frequency is a multiple of 8 MHz, k is always 1 */ |
110 | else if (!(freq_mhz % 8)) |
111 | req->k = 1; |
112 | /* Otherwise, we don't use the k factor */ |
113 | else |
114 | req->k = 0; |
115 | |
116 | /* |
117 | * If the frequency is a multiple of 2 but not a multiple of |
118 | * 3, m is 3. This is the first time we use 6 here, yet we |
119 | * will use it on several other places. |
120 | * We use this number because it's the lowest frequency we can |
121 | * generate (with n = 0, k = 0, m = 3), so every other frequency |
122 | * somehow relates to this frequency. |
123 | */ |
124 | if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) |
125 | req->m = 2; |
126 | /* |
127 | * If the frequency is a multiple of 6MHz, but the factor is |
128 | * odd, m will be 3 |
129 | */ |
130 | else if ((freq_mhz / 6) & 1) |
131 | req->m = 3; |
132 | /* Otherwise, we end up with m = 1 */ |
133 | else |
134 | req->m = 1; |
135 | |
136 | /* Calculate n thanks to the above factors we already got */ |
137 | req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz) |
138 | - 1; |
139 | |
140 | /* |
141 | * If n end up being outbound, and that we can still decrease |
142 | * m, do it. |
143 | */ |
144 | if ((req->n + 1) > 31 && (req->m + 1) > 1) { |
145 | req->n = (req->n + 1) / 2 - 1; |
146 | req->m = (req->m + 1) / 2 - 1; |
147 | } |
148 | } |
149 | |
150 | /* |
151 | * sun8i_a23_get_pll1_factors() - calculates n, k, m, p factors for PLL1 |
152 | * PLL1 rate is calculated as follows |
153 | * rate = (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1); |
154 | * parent_rate is always 24Mhz |
155 | */ |
156 | |
157 | static void sun8i_a23_get_pll1_factors(struct factors_request *req) |
158 | { |
159 | u8 div; |
160 | |
161 | /* Normalize value to a 6M multiple */ |
162 | div = req->rate / 6000000; |
163 | req->rate = 6000000 * div; |
164 | |
165 | /* m is always zero for pll1 */ |
166 | req->m = 0; |
167 | |
168 | /* k is 1 only on these cases */ |
169 | if (req->rate >= 768000000 || req->rate == 42000000 || |
170 | req->rate == 54000000) |
171 | req->k = 1; |
172 | else |
173 | req->k = 0; |
174 | |
175 | /* p will be 2 for divs under 20 and odd divs under 32 */ |
176 | if (div < 20 || (div < 32 && (div & 1))) |
177 | req->p = 2; |
178 | |
179 | /* p will be 1 for even divs under 32, divs under 40 and odd pairs |
180 | * of divs between 40-62 */ |
181 | else if (div < 40 || (div < 64 && (div & 2))) |
182 | req->p = 1; |
183 | |
184 | /* any other entries have p = 0 */ |
185 | else |
186 | req->p = 0; |
187 | |
188 | /* calculate a suitable n based on k and p */ |
189 | div <<= req->p; |
190 | div /= (req->k + 1); |
191 | req->n = div / 4 - 1; |
192 | } |
193 | |
194 | /* |
195 | * sun4i_get_pll5_factors() - calculates n, k factors for PLL5 |
196 | * PLL5 rate is calculated as follows |
197 | * rate = parent_rate * n * (k + 1) |
198 | * parent_rate is always 24Mhz |
199 | */ |
200 | |
201 | static void sun4i_get_pll5_factors(struct factors_request *req) |
202 | { |
203 | u8 div; |
204 | |
205 | /* Normalize value to a parent_rate multiple (24M) */ |
206 | div = req->rate / req->parent_rate; |
207 | req->rate = req->parent_rate * div; |
208 | |
209 | if (div < 31) |
210 | req->k = 0; |
211 | else if (div / 2 < 31) |
212 | req->k = 1; |
213 | else if (div / 3 < 31) |
214 | req->k = 2; |
215 | else |
216 | req->k = 3; |
217 | |
218 | req->n = DIV_ROUND_UP(div, (req->k + 1)); |
219 | } |
220 | |
221 | /* |
222 | * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2 |
223 | * PLL6x2 rate is calculated as follows |
224 | * rate = parent_rate * (n + 1) * (k + 1) |
225 | * parent_rate is always 24Mhz |
226 | */ |
227 | |
228 | static void sun6i_a31_get_pll6_factors(struct factors_request *req) |
229 | { |
230 | u8 div; |
231 | |
232 | /* Normalize value to a parent_rate multiple (24M) */ |
233 | div = req->rate / req->parent_rate; |
234 | req->rate = req->parent_rate * div; |
235 | |
236 | req->k = div / 32; |
237 | if (req->k > 3) |
238 | req->k = 3; |
239 | |
240 | req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1; |
241 | } |
242 | |
243 | /* |
244 | * sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB |
245 | * AHB rate is calculated as follows |
246 | * rate = parent_rate >> p |
247 | */ |
248 | |
249 | static void sun5i_a13_get_ahb_factors(struct factors_request *req) |
250 | { |
251 | u32 div; |
252 | |
253 | /* divide only */ |
254 | if (req->parent_rate < req->rate) |
255 | req->rate = req->parent_rate; |
256 | |
257 | /* |
258 | * user manual says valid speed is 8k ~ 276M, but tests show it |
259 | * can work at speeds up to 300M, just after reparenting to pll6 |
260 | */ |
261 | if (req->rate < 8000) |
262 | req->rate = 8000; |
263 | if (req->rate > 300000000) |
264 | req->rate = 300000000; |
265 | |
266 | div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); |
267 | |
268 | /* p = 0 ~ 3 */ |
269 | if (div > 3) |
270 | div = 3; |
271 | |
272 | req->rate = req->parent_rate >> div; |
273 | |
274 | req->p = div; |
275 | } |
276 | |
277 | #define SUN6I_AHB1_PARENT_PLL6 3 |
278 | |
279 | /* |
280 | * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB |
281 | * AHB rate is calculated as follows |
282 | * rate = parent_rate >> p |
283 | * |
284 | * if parent is pll6, then |
285 | * parent_rate = pll6 rate / (m + 1) |
286 | */ |
287 | |
288 | static void sun6i_get_ahb1_factors(struct factors_request *req) |
289 | { |
290 | u8 div, calcp, calcm = 1; |
291 | |
292 | /* |
293 | * clock can only divide, so we will never be able to achieve |
294 | * frequencies higher than the parent frequency |
295 | */ |
296 | if (req->parent_rate && req->rate > req->parent_rate) |
297 | req->rate = req->parent_rate; |
298 | |
299 | div = DIV_ROUND_UP(req->parent_rate, req->rate); |
300 | |
301 | /* calculate pre-divider if parent is pll6 */ |
302 | if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) { |
303 | if (div < 4) |
304 | calcp = 0; |
305 | else if (div / 2 < 4) |
306 | calcp = 1; |
307 | else if (div / 4 < 4) |
308 | calcp = 2; |
309 | else |
310 | calcp = 3; |
311 | |
312 | calcm = DIV_ROUND_UP(div, 1 << calcp); |
313 | } else { |
314 | calcp = __roundup_pow_of_two(n: div); |
315 | calcp = calcp > 3 ? 3 : calcp; |
316 | } |
317 | |
318 | req->rate = (req->parent_rate / calcm) >> calcp; |
319 | req->p = calcp; |
320 | req->m = calcm - 1; |
321 | } |
322 | |
323 | /* |
324 | * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and |
325 | * parent index |
326 | */ |
327 | static void sun6i_ahb1_recalc(struct factors_request *req) |
328 | { |
329 | req->rate = req->parent_rate; |
330 | |
331 | /* apply pre-divider first if parent is pll6 */ |
332 | if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) |
333 | req->rate /= req->m + 1; |
334 | |
335 | /* clk divider */ |
336 | req->rate >>= req->p; |
337 | } |
338 | |
339 | /* |
340 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 |
341 | * APB1 rate is calculated as follows |
342 | * rate = (parent_rate >> p) / (m + 1); |
343 | */ |
344 | |
345 | static void sun4i_get_apb1_factors(struct factors_request *req) |
346 | { |
347 | u8 calcm, calcp; |
348 | int div; |
349 | |
350 | if (req->parent_rate < req->rate) |
351 | req->rate = req->parent_rate; |
352 | |
353 | div = DIV_ROUND_UP(req->parent_rate, req->rate); |
354 | |
355 | /* Invalid rate! */ |
356 | if (div > 32) |
357 | return; |
358 | |
359 | if (div <= 4) |
360 | calcp = 0; |
361 | else if (div <= 8) |
362 | calcp = 1; |
363 | else if (div <= 16) |
364 | calcp = 2; |
365 | else |
366 | calcp = 3; |
367 | |
368 | calcm = (div >> calcp) - 1; |
369 | |
370 | req->rate = (req->parent_rate >> calcp) / (calcm + 1); |
371 | req->m = calcm; |
372 | req->p = calcp; |
373 | } |
374 | |
375 | |
376 | |
377 | |
378 | /* |
379 | * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B |
380 | * CLK_OUT rate is calculated as follows |
381 | * rate = (parent_rate >> p) / (m + 1); |
382 | */ |
383 | |
384 | static void sun7i_a20_get_out_factors(struct factors_request *req) |
385 | { |
386 | u8 div, calcm, calcp; |
387 | |
388 | /* These clocks can only divide, so we will never be able to achieve |
389 | * frequencies higher than the parent frequency */ |
390 | if (req->rate > req->parent_rate) |
391 | req->rate = req->parent_rate; |
392 | |
393 | div = DIV_ROUND_UP(req->parent_rate, req->rate); |
394 | |
395 | if (div < 32) |
396 | calcp = 0; |
397 | else if (div / 2 < 32) |
398 | calcp = 1; |
399 | else if (div / 4 < 32) |
400 | calcp = 2; |
401 | else |
402 | calcp = 3; |
403 | |
404 | calcm = DIV_ROUND_UP(div, 1 << calcp); |
405 | |
406 | req->rate = (req->parent_rate >> calcp) / calcm; |
407 | req->m = calcm - 1; |
408 | req->p = calcp; |
409 | } |
410 | |
411 | /* |
412 | * sunxi_factors_clk_setup() - Setup function for factor clocks |
413 | */ |
414 | |
415 | static const struct clk_factors_config sun4i_pll1_config = { |
416 | .nshift = 8, |
417 | .nwidth = 5, |
418 | .kshift = 4, |
419 | .kwidth = 2, |
420 | .mshift = 0, |
421 | .mwidth = 2, |
422 | .pshift = 16, |
423 | .pwidth = 2, |
424 | }; |
425 | |
426 | static const struct clk_factors_config sun6i_a31_pll1_config = { |
427 | .nshift = 8, |
428 | .nwidth = 5, |
429 | .kshift = 4, |
430 | .kwidth = 2, |
431 | .mshift = 0, |
432 | .mwidth = 2, |
433 | .n_start = 1, |
434 | }; |
435 | |
436 | static const struct clk_factors_config sun8i_a23_pll1_config = { |
437 | .nshift = 8, |
438 | .nwidth = 5, |
439 | .kshift = 4, |
440 | .kwidth = 2, |
441 | .mshift = 0, |
442 | .mwidth = 2, |
443 | .pshift = 16, |
444 | .pwidth = 2, |
445 | .n_start = 1, |
446 | }; |
447 | |
448 | static const struct clk_factors_config sun4i_pll5_config = { |
449 | .nshift = 8, |
450 | .nwidth = 5, |
451 | .kshift = 4, |
452 | .kwidth = 2, |
453 | }; |
454 | |
455 | static const struct clk_factors_config sun6i_a31_pll6_config = { |
456 | .nshift = 8, |
457 | .nwidth = 5, |
458 | .kshift = 4, |
459 | .kwidth = 2, |
460 | .n_start = 1, |
461 | }; |
462 | |
463 | static const struct clk_factors_config sun5i_a13_ahb_config = { |
464 | .pshift = 4, |
465 | .pwidth = 2, |
466 | }; |
467 | |
468 | static const struct clk_factors_config sun6i_ahb1_config = { |
469 | .mshift = 6, |
470 | .mwidth = 2, |
471 | .pshift = 4, |
472 | .pwidth = 2, |
473 | }; |
474 | |
475 | static const struct clk_factors_config sun4i_apb1_config = { |
476 | .mshift = 0, |
477 | .mwidth = 5, |
478 | .pshift = 16, |
479 | .pwidth = 2, |
480 | }; |
481 | |
482 | /* user manual says "n" but it's really "p" */ |
483 | static const struct clk_factors_config sun7i_a20_out_config = { |
484 | .mshift = 8, |
485 | .mwidth = 5, |
486 | .pshift = 20, |
487 | .pwidth = 2, |
488 | }; |
489 | |
490 | static const struct factors_data sun4i_pll1_data __initconst = { |
491 | .enable = 31, |
492 | .table = &sun4i_pll1_config, |
493 | .getter = sun4i_get_pll1_factors, |
494 | }; |
495 | |
496 | static const struct factors_data sun6i_a31_pll1_data __initconst = { |
497 | .enable = 31, |
498 | .table = &sun6i_a31_pll1_config, |
499 | .getter = sun6i_a31_get_pll1_factors, |
500 | }; |
501 | |
502 | static const struct factors_data sun8i_a23_pll1_data __initconst = { |
503 | .enable = 31, |
504 | .table = &sun8i_a23_pll1_config, |
505 | .getter = sun8i_a23_get_pll1_factors, |
506 | }; |
507 | |
508 | static const struct factors_data sun7i_a20_pll4_data __initconst = { |
509 | .enable = 31, |
510 | .table = &sun4i_pll5_config, |
511 | .getter = sun4i_get_pll5_factors, |
512 | }; |
513 | |
514 | static const struct factors_data sun4i_pll5_data __initconst = { |
515 | .enable = 31, |
516 | .table = &sun4i_pll5_config, |
517 | .getter = sun4i_get_pll5_factors, |
518 | }; |
519 | |
520 | static const struct factors_data sun6i_a31_pll6_data __initconst = { |
521 | .enable = 31, |
522 | .table = &sun6i_a31_pll6_config, |
523 | .getter = sun6i_a31_get_pll6_factors, |
524 | }; |
525 | |
526 | static const struct factors_data sun5i_a13_ahb_data __initconst = { |
527 | .mux = 6, |
528 | .muxmask = BIT(1) | BIT(0), |
529 | .table = &sun5i_a13_ahb_config, |
530 | .getter = sun5i_a13_get_ahb_factors, |
531 | }; |
532 | |
533 | static const struct factors_data sun6i_ahb1_data __initconst = { |
534 | .mux = 12, |
535 | .muxmask = BIT(1) | BIT(0), |
536 | .table = &sun6i_ahb1_config, |
537 | .getter = sun6i_get_ahb1_factors, |
538 | .recalc = sun6i_ahb1_recalc, |
539 | }; |
540 | |
541 | static const struct factors_data sun4i_apb1_data __initconst = { |
542 | .mux = 24, |
543 | .muxmask = BIT(1) | BIT(0), |
544 | .table = &sun4i_apb1_config, |
545 | .getter = sun4i_get_apb1_factors, |
546 | }; |
547 | |
548 | static const struct factors_data sun7i_a20_out_data __initconst = { |
549 | .enable = 31, |
550 | .mux = 24, |
551 | .muxmask = BIT(1) | BIT(0), |
552 | .table = &sun7i_a20_out_config, |
553 | .getter = sun7i_a20_get_out_factors, |
554 | }; |
555 | |
556 | static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, |
557 | const struct factors_data *data) |
558 | { |
559 | void __iomem *reg; |
560 | |
561 | reg = of_iomap(node, index: 0); |
562 | if (!reg) { |
563 | pr_err("Could not get registers for factors-clk: %pOFn\n" , |
564 | node); |
565 | return NULL; |
566 | } |
567 | |
568 | return sunxi_factors_register(node, data, lock: &clk_lock, reg); |
569 | } |
570 | |
571 | static void __init sun4i_pll1_clk_setup(struct device_node *node) |
572 | { |
573 | sunxi_factors_clk_setup(node, data: &sun4i_pll1_data); |
574 | } |
575 | CLK_OF_DECLARE(sun4i_pll1, "allwinner,sun4i-a10-pll1-clk" , |
576 | sun4i_pll1_clk_setup); |
577 | |
578 | static void __init sun6i_pll1_clk_setup(struct device_node *node) |
579 | { |
580 | sunxi_factors_clk_setup(node, data: &sun6i_a31_pll1_data); |
581 | } |
582 | CLK_OF_DECLARE(sun6i_pll1, "allwinner,sun6i-a31-pll1-clk" , |
583 | sun6i_pll1_clk_setup); |
584 | |
585 | static void __init sun8i_pll1_clk_setup(struct device_node *node) |
586 | { |
587 | sunxi_factors_clk_setup(node, data: &sun8i_a23_pll1_data); |
588 | } |
589 | CLK_OF_DECLARE(sun8i_pll1, "allwinner,sun8i-a23-pll1-clk" , |
590 | sun8i_pll1_clk_setup); |
591 | |
592 | static void __init sun7i_pll4_clk_setup(struct device_node *node) |
593 | { |
594 | sunxi_factors_clk_setup(node, data: &sun7i_a20_pll4_data); |
595 | } |
596 | CLK_OF_DECLARE(sun7i_pll4, "allwinner,sun7i-a20-pll4-clk" , |
597 | sun7i_pll4_clk_setup); |
598 | |
599 | static void __init sun5i_ahb_clk_setup(struct device_node *node) |
600 | { |
601 | sunxi_factors_clk_setup(node, data: &sun5i_a13_ahb_data); |
602 | } |
603 | CLK_OF_DECLARE(sun5i_ahb, "allwinner,sun5i-a13-ahb-clk" , |
604 | sun5i_ahb_clk_setup); |
605 | |
606 | static void __init sun6i_ahb1_clk_setup(struct device_node *node) |
607 | { |
608 | sunxi_factors_clk_setup(node, data: &sun6i_ahb1_data); |
609 | } |
610 | CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk" , |
611 | sun6i_ahb1_clk_setup); |
612 | |
613 | static void __init sun4i_apb1_clk_setup(struct device_node *node) |
614 | { |
615 | sunxi_factors_clk_setup(node, data: &sun4i_apb1_data); |
616 | } |
617 | CLK_OF_DECLARE(sun4i_apb1, "allwinner,sun4i-a10-apb1-clk" , |
618 | sun4i_apb1_clk_setup); |
619 | |
620 | static void __init sun7i_out_clk_setup(struct device_node *node) |
621 | { |
622 | sunxi_factors_clk_setup(node, data: &sun7i_a20_out_data); |
623 | } |
624 | CLK_OF_DECLARE(sun7i_out, "allwinner,sun7i-a20-out-clk" , |
625 | sun7i_out_clk_setup); |
626 | |
627 | |
628 | /* |
629 | * sunxi_mux_clk_setup() - Setup function for muxes |
630 | */ |
631 | |
632 | #define SUNXI_MUX_GATE_WIDTH 2 |
633 | |
634 | struct mux_data { |
635 | u8 shift; |
636 | }; |
637 | |
638 | static const struct mux_data sun4i_cpu_mux_data __initconst = { |
639 | .shift = 16, |
640 | }; |
641 | |
642 | static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = { |
643 | .shift = 12, |
644 | }; |
645 | |
646 | static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { |
647 | .shift = 0, |
648 | }; |
649 | |
650 | static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, |
651 | const struct mux_data *data, |
652 | unsigned long flags) |
653 | { |
654 | struct clk *clk; |
655 | const char *clk_name = node->name; |
656 | const char *parents[SUNXI_MAX_PARENTS]; |
657 | void __iomem *reg; |
658 | int i; |
659 | |
660 | reg = of_iomap(node, index: 0); |
661 | if (!reg) { |
662 | pr_err("Could not map registers for mux-clk: %pOF\n" , node); |
663 | return NULL; |
664 | } |
665 | |
666 | i = of_clk_parent_fill(np: node, parents, SUNXI_MAX_PARENTS); |
667 | if (of_property_read_string(np: node, propname: "clock-output-names" , out_string: &clk_name)) { |
668 | pr_err("%s: could not read clock-output-names from \"%pOF\"\n" , |
669 | __func__, node); |
670 | goto out_unmap; |
671 | } |
672 | |
673 | clk = clk_register_mux(NULL, clk_name, parents, i, |
674 | CLK_SET_RATE_PARENT | flags, reg, |
675 | data->shift, SUNXI_MUX_GATE_WIDTH, |
676 | 0, &clk_lock); |
677 | |
678 | if (IS_ERR(ptr: clk)) { |
679 | pr_err("%s: failed to register mux clock %s: %ld\n" , __func__, |
680 | clk_name, PTR_ERR(clk)); |
681 | goto out_unmap; |
682 | } |
683 | |
684 | if (of_clk_add_provider(np: node, clk_src_get: of_clk_src_simple_get, data: clk)) { |
685 | pr_err("%s: failed to add clock provider for %s\n" , |
686 | __func__, clk_name); |
687 | clk_unregister_divider(clk); |
688 | goto out_unmap; |
689 | } |
690 | |
691 | return clk; |
692 | out_unmap: |
693 | iounmap(addr: reg); |
694 | return NULL; |
695 | } |
696 | |
697 | static void __init sun4i_cpu_clk_setup(struct device_node *node) |
698 | { |
699 | /* Protect CPU clock */ |
700 | sunxi_mux_clk_setup(node, data: &sun4i_cpu_mux_data, CLK_IS_CRITICAL); |
701 | } |
702 | CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk" , |
703 | sun4i_cpu_clk_setup); |
704 | |
705 | static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node) |
706 | { |
707 | sunxi_mux_clk_setup(node, data: &sun6i_a31_ahb1_mux_data, flags: 0); |
708 | } |
709 | CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk" , |
710 | sun6i_ahb1_mux_clk_setup); |
711 | |
712 | static void __init sun8i_ahb2_clk_setup(struct device_node *node) |
713 | { |
714 | sunxi_mux_clk_setup(node, data: &sun8i_h3_ahb2_mux_data, flags: 0); |
715 | } |
716 | CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk" , |
717 | sun8i_ahb2_clk_setup); |
718 | |
719 | |
720 | /* |
721 | * sunxi_divider_clk_setup() - Setup function for simple divider clocks |
722 | */ |
723 | |
724 | struct div_data { |
725 | u8 shift; |
726 | u8 pow; |
727 | u8 width; |
728 | const struct clk_div_table *table; |
729 | }; |
730 | |
731 | static const struct div_data sun4i_axi_data __initconst = { |
732 | .shift = 0, |
733 | .pow = 0, |
734 | .width = 2, |
735 | }; |
736 | |
737 | static const struct clk_div_table sun8i_a23_axi_table[] __initconst = { |
738 | { .val = 0, .div = 1 }, |
739 | { .val = 1, .div = 2 }, |
740 | { .val = 2, .div = 3 }, |
741 | { .val = 3, .div = 4 }, |
742 | { .val = 4, .div = 4 }, |
743 | { .val = 5, .div = 4 }, |
744 | { .val = 6, .div = 4 }, |
745 | { .val = 7, .div = 4 }, |
746 | { } /* sentinel */ |
747 | }; |
748 | |
749 | static const struct div_data sun8i_a23_axi_data __initconst = { |
750 | .width = 3, |
751 | .table = sun8i_a23_axi_table, |
752 | }; |
753 | |
754 | static const struct div_data sun4i_ahb_data __initconst = { |
755 | .shift = 4, |
756 | .pow = 1, |
757 | .width = 2, |
758 | }; |
759 | |
760 | static const struct clk_div_table sun4i_apb0_table[] __initconst = { |
761 | { .val = 0, .div = 2 }, |
762 | { .val = 1, .div = 2 }, |
763 | { .val = 2, .div = 4 }, |
764 | { .val = 3, .div = 8 }, |
765 | { } /* sentinel */ |
766 | }; |
767 | |
768 | static const struct div_data sun4i_apb0_data __initconst = { |
769 | .shift = 8, |
770 | .pow = 1, |
771 | .width = 2, |
772 | .table = sun4i_apb0_table, |
773 | }; |
774 | |
775 | static void __init sunxi_divider_clk_setup(struct device_node *node, |
776 | const struct div_data *data) |
777 | { |
778 | struct clk *clk; |
779 | const char *clk_name = node->name; |
780 | const char *clk_parent; |
781 | void __iomem *reg; |
782 | |
783 | reg = of_iomap(node, index: 0); |
784 | if (!reg) { |
785 | pr_err("Could not map registers for mux-clk: %pOF\n" , node); |
786 | return; |
787 | } |
788 | |
789 | clk_parent = of_clk_get_parent_name(np: node, index: 0); |
790 | |
791 | if (of_property_read_string(np: node, propname: "clock-output-names" , out_string: &clk_name)) { |
792 | pr_err("%s: could not read clock-output-names from \"%pOF\"\n" , |
793 | __func__, node); |
794 | goto out_unmap; |
795 | } |
796 | |
797 | clk = clk_register_divider_table(NULL, name: clk_name, parent_name: clk_parent, flags: 0, |
798 | reg, shift: data->shift, width: data->width, |
799 | clk_divider_flags: data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, |
800 | table: data->table, lock: &clk_lock); |
801 | if (IS_ERR(ptr: clk)) { |
802 | pr_err("%s: failed to register divider clock %s: %ld\n" , |
803 | __func__, clk_name, PTR_ERR(clk)); |
804 | goto out_unmap; |
805 | } |
806 | |
807 | if (of_clk_add_provider(np: node, clk_src_get: of_clk_src_simple_get, data: clk)) { |
808 | pr_err("%s: failed to add clock provider for %s\n" , |
809 | __func__, clk_name); |
810 | goto out_unregister; |
811 | } |
812 | |
813 | if (clk_register_clkdev(clk, clk_name, NULL)) { |
814 | of_clk_del_provider(np: node); |
815 | goto out_unregister; |
816 | } |
817 | |
818 | return; |
819 | out_unregister: |
820 | clk_unregister_divider(clk); |
821 | |
822 | out_unmap: |
823 | iounmap(addr: reg); |
824 | } |
825 | |
826 | static void __init sun4i_ahb_clk_setup(struct device_node *node) |
827 | { |
828 | sunxi_divider_clk_setup(node, data: &sun4i_ahb_data); |
829 | } |
830 | CLK_OF_DECLARE(sun4i_ahb, "allwinner,sun4i-a10-ahb-clk" , |
831 | sun4i_ahb_clk_setup); |
832 | |
833 | static void __init sun4i_apb0_clk_setup(struct device_node *node) |
834 | { |
835 | sunxi_divider_clk_setup(node, data: &sun4i_apb0_data); |
836 | } |
837 | CLK_OF_DECLARE(sun4i_apb0, "allwinner,sun4i-a10-apb0-clk" , |
838 | sun4i_apb0_clk_setup); |
839 | |
840 | static void __init sun4i_axi_clk_setup(struct device_node *node) |
841 | { |
842 | sunxi_divider_clk_setup(node, data: &sun4i_axi_data); |
843 | } |
844 | CLK_OF_DECLARE(sun4i_axi, "allwinner,sun4i-a10-axi-clk" , |
845 | sun4i_axi_clk_setup); |
846 | |
847 | static void __init sun8i_axi_clk_setup(struct device_node *node) |
848 | { |
849 | sunxi_divider_clk_setup(node, data: &sun8i_a23_axi_data); |
850 | } |
851 | CLK_OF_DECLARE(sun8i_axi, "allwinner,sun8i-a23-axi-clk" , |
852 | sun8i_axi_clk_setup); |
853 | |
854 | |
855 | |
856 | /* |
857 | * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks |
858 | */ |
859 | |
860 | #define SUNXI_GATES_MAX_SIZE 64 |
861 | |
862 | struct gates_data { |
863 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); |
864 | }; |
865 | |
866 | /* |
867 | * sunxi_divs_clk_setup() helper data |
868 | */ |
869 | |
870 | #define SUNXI_DIVS_MAX_QTY 4 |
871 | #define SUNXI_DIVISOR_WIDTH 2 |
872 | |
873 | struct divs_data { |
874 | const struct factors_data *factors; /* data for the factor clock */ |
875 | int ndivs; /* number of outputs */ |
876 | /* |
877 | * List of outputs. Refer to the diagram for sunxi_divs_clk_setup(): |
878 | * self or base factor clock refers to the output from the pll |
879 | * itself. The remaining refer to fixed or configurable divider |
880 | * outputs. |
881 | */ |
882 | struct { |
883 | u8 self; /* is it the base factor clock? (only one) */ |
884 | u8 fixed; /* is it a fixed divisor? if not... */ |
885 | struct clk_div_table *table; /* is it a table based divisor? */ |
886 | u8 shift; /* otherwise it's a normal divisor with this shift */ |
887 | u8 pow; /* is it power-of-two based? */ |
888 | u8 gate; /* is it independently gateable? */ |
889 | bool critical; |
890 | } div[SUNXI_DIVS_MAX_QTY]; |
891 | }; |
892 | |
893 | static struct clk_div_table pll6_sata_tbl[] = { |
894 | { .val = 0, .div = 6, }, |
895 | { .val = 1, .div = 12, }, |
896 | { .val = 2, .div = 18, }, |
897 | { .val = 3, .div = 24, }, |
898 | { } /* sentinel */ |
899 | }; |
900 | |
901 | static const struct divs_data pll5_divs_data __initconst = { |
902 | .factors = &sun4i_pll5_data, |
903 | .ndivs = 2, |
904 | .div = { |
905 | /* Protect PLL5_DDR */ |
906 | { .shift = 0, .pow = 0, .critical = true }, /* M, DDR */ |
907 | { .shift = 16, .pow = 1, }, /* P, other */ |
908 | /* No output for the base factor clock */ |
909 | } |
910 | }; |
911 | |
912 | static const struct divs_data pll6_divs_data __initconst = { |
913 | .factors = &sun4i_pll5_data, |
914 | .ndivs = 4, |
915 | .div = { |
916 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ |
917 | { .fixed = 2 }, /* P, other */ |
918 | { .self = 1 }, /* base factor clock, 2x */ |
919 | { .fixed = 4 }, /* pll6 / 4, used as ahb input */ |
920 | } |
921 | }; |
922 | |
923 | static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { |
924 | .factors = &sun6i_a31_pll6_data, |
925 | .ndivs = 2, |
926 | .div = { |
927 | { .fixed = 2 }, /* normal output */ |
928 | { .self = 1 }, /* base factor clock, 2x */ |
929 | } |
930 | }; |
931 | |
932 | /* |
933 | * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks |
934 | * |
935 | * These clocks look something like this |
936 | * ________________________ |
937 | * | ___divisor 1---|----> to consumer |
938 | * parent >--| pll___/___divisor 2---|----> to consumer |
939 | * | \_______________|____> to consumer |
940 | * |________________________| |
941 | */ |
942 | |
943 | static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, |
944 | const struct divs_data *data) |
945 | { |
946 | struct clk_onecell_data *clk_data; |
947 | const char *parent; |
948 | const char *clk_name; |
949 | struct clk **clks, *pclk; |
950 | struct clk_hw *gate_hw, *rate_hw; |
951 | const struct clk_ops *rate_ops; |
952 | struct clk_gate *gate = NULL; |
953 | struct clk_fixed_factor *fix_factor; |
954 | struct clk_divider *divider; |
955 | struct factors_data factors = *data->factors; |
956 | char *derived_name = NULL; |
957 | void __iomem *reg; |
958 | int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; |
959 | int flags, clkflags; |
960 | |
961 | /* if number of children known, use it */ |
962 | if (data->ndivs) |
963 | ndivs = data->ndivs; |
964 | |
965 | /* Try to find a name for base factor clock */ |
966 | for (i = 0; i < ndivs; i++) { |
967 | if (data->div[i].self) { |
968 | of_property_read_string_index(np: node, propname: "clock-output-names" , |
969 | index: i, output: &factors.name); |
970 | break; |
971 | } |
972 | } |
973 | /* If we don't have a .self clk use the first output-name up to '_' */ |
974 | if (factors.name == NULL) { |
975 | char *endp; |
976 | |
977 | of_property_read_string_index(np: node, propname: "clock-output-names" , |
978 | index: 0, output: &clk_name); |
979 | endp = strchr(clk_name, '_'); |
980 | if (endp) { |
981 | derived_name = kstrndup(s: clk_name, len: endp - clk_name, |
982 | GFP_KERNEL); |
983 | if (!derived_name) |
984 | return NULL; |
985 | factors.name = derived_name; |
986 | } else { |
987 | factors.name = clk_name; |
988 | } |
989 | } |
990 | |
991 | /* Set up factor clock that we will be dividing */ |
992 | pclk = sunxi_factors_clk_setup(node, data: &factors); |
993 | if (!pclk) |
994 | return NULL; |
995 | |
996 | parent = __clk_get_name(clk: pclk); |
997 | kfree(objp: derived_name); |
998 | |
999 | reg = of_iomap(node, index: 0); |
1000 | if (!reg) { |
1001 | pr_err("Could not map registers for divs-clk: %pOF\n" , node); |
1002 | return NULL; |
1003 | } |
1004 | |
1005 | clk_data = kmalloc(size: sizeof(struct clk_onecell_data), GFP_KERNEL); |
1006 | if (!clk_data) |
1007 | goto out_unmap; |
1008 | |
1009 | clks = kcalloc(n: ndivs, size: sizeof(*clks), GFP_KERNEL); |
1010 | if (!clks) |
1011 | goto free_clkdata; |
1012 | |
1013 | clk_data->clks = clks; |
1014 | |
1015 | /* It's not a good idea to have automatic reparenting changing |
1016 | * our RAM clock! */ |
1017 | clkflags = !strcmp("pll5" , parent) ? 0 : CLK_SET_RATE_PARENT; |
1018 | |
1019 | for (i = 0; i < ndivs; i++) { |
1020 | if (of_property_read_string_index(np: node, propname: "clock-output-names" , |
1021 | index: i, output: &clk_name) != 0) |
1022 | break; |
1023 | |
1024 | /* If this is the base factor clock, only update clks */ |
1025 | if (data->div[i].self) { |
1026 | clk_data->clks[i] = pclk; |
1027 | continue; |
1028 | } |
1029 | |
1030 | gate_hw = NULL; |
1031 | rate_hw = NULL; |
1032 | rate_ops = NULL; |
1033 | |
1034 | /* If this leaf clock can be gated, create a gate */ |
1035 | if (data->div[i].gate) { |
1036 | gate = kzalloc(size: sizeof(*gate), GFP_KERNEL); |
1037 | if (!gate) |
1038 | goto free_clks; |
1039 | |
1040 | gate->reg = reg; |
1041 | gate->bit_idx = data->div[i].gate; |
1042 | gate->lock = &clk_lock; |
1043 | |
1044 | gate_hw = &gate->hw; |
1045 | } |
1046 | |
1047 | /* Leaves can be fixed or configurable divisors */ |
1048 | if (data->div[i].fixed) { |
1049 | fix_factor = kzalloc(size: sizeof(*fix_factor), GFP_KERNEL); |
1050 | if (!fix_factor) |
1051 | goto free_gate; |
1052 | |
1053 | fix_factor->mult = 1; |
1054 | fix_factor->div = data->div[i].fixed; |
1055 | |
1056 | rate_hw = &fix_factor->hw; |
1057 | rate_ops = &clk_fixed_factor_ops; |
1058 | } else { |
1059 | divider = kzalloc(size: sizeof(*divider), GFP_KERNEL); |
1060 | if (!divider) |
1061 | goto free_gate; |
1062 | |
1063 | flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0; |
1064 | |
1065 | divider->reg = reg; |
1066 | divider->shift = data->div[i].shift; |
1067 | divider->width = SUNXI_DIVISOR_WIDTH; |
1068 | divider->flags = flags; |
1069 | divider->lock = &clk_lock; |
1070 | divider->table = data->div[i].table; |
1071 | |
1072 | rate_hw = ÷r->hw; |
1073 | rate_ops = &clk_divider_ops; |
1074 | } |
1075 | |
1076 | /* Wrap the (potential) gate and the divisor on a composite |
1077 | * clock to unify them */ |
1078 | clks[i] = clk_register_composite(NULL, name: clk_name, parent_names: &parent, num_parents: 1, |
1079 | NULL, NULL, |
1080 | rate_hw, rate_ops, |
1081 | gate_hw, gate_ops: &clk_gate_ops, |
1082 | flags: clkflags | |
1083 | (data->div[i].critical ? |
1084 | CLK_IS_CRITICAL : 0)); |
1085 | |
1086 | WARN_ON(IS_ERR(clk_data->clks[i])); |
1087 | } |
1088 | |
1089 | /* Adjust to the real max */ |
1090 | clk_data->clk_num = i; |
1091 | |
1092 | if (of_clk_add_provider(np: node, clk_src_get: of_clk_src_onecell_get, data: clk_data)) { |
1093 | pr_err("%s: failed to add clock provider for %s\n" , |
1094 | __func__, clk_name); |
1095 | goto free_gate; |
1096 | } |
1097 | |
1098 | return clks; |
1099 | free_gate: |
1100 | kfree(objp: gate); |
1101 | free_clks: |
1102 | kfree(objp: clks); |
1103 | free_clkdata: |
1104 | kfree(objp: clk_data); |
1105 | out_unmap: |
1106 | iounmap(addr: reg); |
1107 | return NULL; |
1108 | } |
1109 | |
1110 | static void __init sun4i_pll5_clk_setup(struct device_node *node) |
1111 | { |
1112 | sunxi_divs_clk_setup(node, data: &pll5_divs_data); |
1113 | } |
1114 | CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk" , |
1115 | sun4i_pll5_clk_setup); |
1116 | |
1117 | static void __init sun4i_pll6_clk_setup(struct device_node *node) |
1118 | { |
1119 | sunxi_divs_clk_setup(node, data: &pll6_divs_data); |
1120 | } |
1121 | CLK_OF_DECLARE(sun4i_pll6, "allwinner,sun4i-a10-pll6-clk" , |
1122 | sun4i_pll6_clk_setup); |
1123 | |
1124 | static void __init sun6i_pll6_clk_setup(struct device_node *node) |
1125 | { |
1126 | sunxi_divs_clk_setup(node, data: &sun6i_a31_pll6_divs_data); |
1127 | } |
1128 | CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk" , |
1129 | sun6i_pll6_clk_setup); |
1130 | |
1131 | /* |
1132 | * sun6i display |
1133 | * |
1134 | * rate = parent_rate / (m + 1); |
1135 | */ |
1136 | static void sun6i_display_factors(struct factors_request *req) |
1137 | { |
1138 | u8 m; |
1139 | |
1140 | if (req->rate > req->parent_rate) |
1141 | req->rate = req->parent_rate; |
1142 | |
1143 | m = DIV_ROUND_UP(req->parent_rate, req->rate); |
1144 | |
1145 | req->rate = req->parent_rate / m; |
1146 | req->m = m - 1; |
1147 | } |
1148 | |
1149 | static const struct clk_factors_config sun6i_display_config = { |
1150 | .mshift = 0, |
1151 | .mwidth = 4, |
1152 | }; |
1153 | |
1154 | static const struct factors_data sun6i_display_data __initconst = { |
1155 | .enable = 31, |
1156 | .mux = 24, |
1157 | .muxmask = BIT(2) | BIT(1) | BIT(0), |
1158 | .table = &sun6i_display_config, |
1159 | .getter = sun6i_display_factors, |
1160 | }; |
1161 | |
1162 | static void __init sun6i_display_setup(struct device_node *node) |
1163 | { |
1164 | sunxi_factors_clk_setup(node, data: &sun6i_display_data); |
1165 | } |
1166 | CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-a31-display-clk" , |
1167 | sun6i_display_setup); |
1168 | |