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