1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
4 * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
5 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
6 *
7 * Adjustable divider clock implementation
8 */
9 #include "ccu.h"
10 #include <stdlib.h>
11 /*
12 * DOC: basic adjustable divider clock that cannot gate
13 *
14 * Traits of this clock:
15 * prepare - clk_prepare only ensures that parents are prepared
16 * enable - clk_enable only ensures that parents are enabled
17 * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor)
18 * parent - fixed parent. No clk_set_parent support
19 */
20
clk_div_readl(struct clk_divider * divider)21 static inline u32 clk_div_readl(struct clk_divider *divider)
22 {
23 return readl(divider->reg);
24 }
25
clk_div_writel(struct clk_divider * divider,u32 val)26 static inline void clk_div_writel(struct clk_divider *divider, u32 val)
27 {
28 writel(val, divider->reg);
29 }
30
_get_table_maxdiv(const struct clk_div_table * table,u8 width)31 static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
32 u8 width)
33 {
34 unsigned int maxdiv = 0, mask = clk_div_mask(width);
35 const struct clk_div_table *clkt;
36
37 for (clkt = table; clkt->div; clkt++)
38 if (clkt->div > maxdiv && clkt->val <= mask)
39 {
40 maxdiv = clkt->div;
41 }
42 return maxdiv;
43 }
44
_get_table_mindiv(const struct clk_div_table * table)45 static unsigned int _get_table_mindiv(const struct clk_div_table *table)
46 {
47 unsigned int mindiv = UINT_MAX;
48 const struct clk_div_table *clkt;
49
50 for (clkt = table; clkt->div; clkt++)
51 if (clkt->div < mindiv)
52 {
53 mindiv = clkt->div;
54 }
55 return mindiv;
56 }
57
_get_maxdiv(const struct clk_div_table * table,u8 width,unsigned long flags)58 static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
59 unsigned long flags)
60 {
61 if (flags & CLK_DIVIDER_ONE_BASED)
62 {
63 return clk_div_mask(width);
64 }
65 if (flags & CLK_DIVIDER_POWER_OF_TWO)
66 {
67 return 1 << clk_div_mask(width);
68 }
69 if (table)
70 {
71 return _get_table_maxdiv(table, width);
72 }
73 return clk_div_mask(width) + 1;
74 }
75
_get_table_div(const struct clk_div_table * table,unsigned int val)76 static unsigned int _get_table_div(const struct clk_div_table *table,
77 unsigned int val)
78 {
79 const struct clk_div_table *clkt;
80
81 for (clkt = table; clkt->div; clkt++)
82 if (clkt->val == val)
83 {
84 return clkt->div;
85 }
86 return 0;
87 }
88
_get_div(const struct clk_div_table * table,unsigned int val,unsigned long flags,u8 width)89 static unsigned int _get_div(const struct clk_div_table *table,
90 unsigned int val, unsigned long flags, u8 width)
91 {
92 if (flags & CLK_DIVIDER_ONE_BASED)
93 {
94 return val;
95 }
96 if (flags & CLK_DIVIDER_POWER_OF_TWO)
97 {
98 return 1 << val;
99 }
100 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
101 {
102 return val ? val : clk_div_mask(width) + 1;
103 }
104 if (table)
105 {
106 return _get_table_div(table, val);
107 }
108 return val + 1;
109 }
110
_get_table_val(const struct clk_div_table * table,unsigned int div)111 static unsigned int _get_table_val(const struct clk_div_table *table,
112 unsigned int div)
113 {
114 const struct clk_div_table *clkt;
115
116 for (clkt = table; clkt->div; clkt++)
117 if (clkt->div == div)
118 {
119 return clkt->val;
120 }
121 return 0;
122 }
123
__ffs(uint32_t value)124 static inline int __ffs(uint32_t value)
125 {
126 uint32_t offset;
127
128 for (offset = 0; offset < sizeof(value) * 8; offset++)
129 {
130 if (value & (1 << offset))
131 {
132 return offset;
133 }
134 }
135 return -1;
136 }
137
_get_val(const struct clk_div_table * table,unsigned int div,unsigned long flags,u8 width)138 static unsigned int _get_val(const struct clk_div_table *table,
139 unsigned int div, unsigned long flags, u8 width)
140 {
141 if (flags & CLK_DIVIDER_ONE_BASED)
142 {
143 return div;
144 }
145 if (flags & CLK_DIVIDER_POWER_OF_TWO)
146 {
147 return __ffs(div);
148 }
149 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
150 {
151 return (div == clk_div_mask(width) + 1) ? 0 : div;
152 }
153 if (table)
154 {
155 return _get_table_val(table, div);
156 }
157 return div - 1;
158 }
159
divider_recalc_rate(struct clk_hw * hw,unsigned long parent_rate,unsigned int val,const struct clk_div_table * table,unsigned long flags,unsigned long width)160 unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
161 unsigned int val,
162 const struct clk_div_table *table,
163 unsigned long flags, unsigned long width)
164 {
165 unsigned int div;
166
167 div = _get_div(table, val, flags, width);
168 if (!div)
169 {
170 return parent_rate;
171 }
172
173 return DIV_ROUND_UP_ULL((u64)parent_rate, div);
174 }
175
clk_divider_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)176 static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
177 unsigned long parent_rate)
178 {
179 struct clk_divider *divider = to_clk_divider(hw);
180 unsigned int val;
181
182 val = clk_div_readl(divider) >> divider->shift;
183 val &= clk_div_mask(divider->width);
184
185 return divider_recalc_rate(hw, parent_rate, val, divider->table,
186 divider->flags, divider->width);
187 }
188
_is_valid_table_div(const struct clk_div_table * table,unsigned int div)189 static bool _is_valid_table_div(const struct clk_div_table *table,
190 unsigned int div)
191 {
192 const struct clk_div_table *clkt;
193
194 for (clkt = table; clkt->div; clkt++)
195 if (clkt->div == div)
196 {
197 return true;
198 }
199 return false;
200 }
201
is_power_of_2(unsigned long n)202 static int is_power_of_2(unsigned long n)
203 {
204 return (n != 0 && ((n & (n - 1)) == 0));
205 }
206
_is_valid_div(const struct clk_div_table * table,unsigned int div,unsigned long flags)207 static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
208 unsigned long flags)
209 {
210 if (flags & CLK_DIVIDER_POWER_OF_TWO)
211 {
212 return is_power_of_2(div);
213 }
214 if (table)
215 {
216 return _is_valid_table_div(table, div);
217 }
218 return true;
219 }
220
_round_up_table(const struct clk_div_table * table,int div)221 static int _round_up_table(const struct clk_div_table *table, int div)
222 {
223 const struct clk_div_table *clkt;
224 int up = INT_MAX;
225
226 for (clkt = table; clkt->div; clkt++)
227 {
228 if (clkt->div == div)
229 {
230 return clkt->div;
231 }
232 else if (clkt->div < div)
233 {
234 continue;
235 }
236
237 if ((clkt->div - div) < (up - div))
238 {
239 up = clkt->div;
240 }
241 }
242
243 return up;
244 }
245
_round_down_table(const struct clk_div_table * table,int div)246 static int _round_down_table(const struct clk_div_table *table, int div)
247 {
248 const struct clk_div_table *clkt;
249 int down = _get_table_mindiv(table);
250
251 for (clkt = table; clkt->div; clkt++)
252 {
253 if (clkt->div == div)
254 {
255 return clkt->div;
256 }
257 else if (clkt->div > div)
258 {
259 continue;
260 }
261
262 if ((div - clkt->div) < (div - down))
263 {
264 down = clkt->div;
265 }
266 }
267
268 return down;
269 }
270
fls(int val)271 int fls(int val)
272 {
273 int bit = 32;
274
275 if (!val)
276 return 0;
277 if (!(val & 0xffff0000u))
278 {
279 val <<= 16;
280 bit -= 16;
281 }
282 if (!(val & 0xff000000u))
283 {
284 val <<= 8;
285 bit -= 8;
286 }
287 if (!(val & 0xf0000000u))
288 {
289 val <<= 4;
290 bit -= 4;
291 }
292 if (!(val & 0xc0000000u))
293 {
294 val <<= 2;
295 bit -= 2;
296 }
297 if (!(val & 0x80000000u))
298 {
299 bit -= 1;
300 }
301
302 return bit;
303 }
304
__roundup_pow_of_two(unsigned int x)305 static int __roundup_pow_of_two(unsigned int x)
306 {
307 return 1UL << fls(x - 1);
308 }
309
__rounddown_pow_of_two(unsigned int x)310 static int __rounddown_pow_of_two(unsigned int x)
311 {
312 return (1UL << fls(x - 1)) / 2;
313 }
314
_div_round_up(const struct clk_div_table * table,unsigned long parent_rate,unsigned long rate,unsigned long flags)315 static int _div_round_up(const struct clk_div_table *table,
316 unsigned long parent_rate, unsigned long rate,
317 unsigned long flags)
318 {
319 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
320
321 if (flags & CLK_DIVIDER_POWER_OF_TWO)
322 {
323 div = __roundup_pow_of_two(div);
324 }
325 if (table)
326 {
327 div = _round_up_table(table, div);
328 }
329
330 return div;
331 }
332
_div_round_closest(const struct clk_div_table * table,unsigned long parent_rate,unsigned long rate,unsigned long flags)333 static int _div_round_closest(const struct clk_div_table *table,
334 unsigned long parent_rate, unsigned long rate,
335 unsigned long flags)
336 {
337 int up, down;
338 unsigned long up_rate, down_rate;
339
340 up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
341 down = parent_rate / rate;
342
343 if (flags & CLK_DIVIDER_POWER_OF_TWO)
344 {
345 up = __roundup_pow_of_two(up);
346 down = __rounddown_pow_of_two(down);
347 }
348 else if (table)
349 {
350 up = _round_up_table(table, up);
351 down = _round_down_table(table, down);
352 }
353
354 up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
355 down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
356
357 return (rate - up_rate) <= (down_rate - rate) ? up : down;
358 }
359
_div_round(const struct clk_div_table * table,unsigned long parent_rate,unsigned long rate,unsigned long flags)360 static int _div_round(const struct clk_div_table *table,
361 unsigned long parent_rate, unsigned long rate,
362 unsigned long flags)
363 {
364 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
365 {
366 return _div_round_closest(table, parent_rate, rate, flags);
367 }
368
369 return _div_round_up(table, parent_rate, rate, flags);
370 }
371
_is_best_div(unsigned long rate,unsigned long now,unsigned long best,unsigned long flags)372 static bool _is_best_div(unsigned long rate, unsigned long now,
373 unsigned long best, unsigned long flags)
374 {
375 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
376 {
377 return abs(rate - now) < abs(rate - best);
378 }
379
380 return now <= rate && now > best;
381 }
382
_next_div(const struct clk_div_table * table,int div,unsigned long flags)383 static int _next_div(const struct clk_div_table *table, int div,
384 unsigned long flags)
385 {
386 div++;
387
388 if (flags & CLK_DIVIDER_POWER_OF_TWO)
389 {
390 return __roundup_pow_of_two(div);
391 }
392 if (table)
393 {
394 return _round_up_table(table, div);
395 }
396
397 return div;
398 }
399
clk_divider_bestdiv(struct clk_hw * hw,struct clk_hw * parent,unsigned long rate,unsigned long * best_parent_rate,const struct clk_div_table * table,u8 width,unsigned long flags)400 static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
401 unsigned long rate,
402 unsigned long *best_parent_rate,
403 const struct clk_div_table *table, u8 width,
404 unsigned long flags)
405 {
406 int i, bestdiv = 0;
407 unsigned long parent_rate, best = 0, now, maxdiv;
408 unsigned long parent_rate_saved = *best_parent_rate;
409
410 if (!rate)
411 {
412 rate = 1;
413 }
414
415 maxdiv = _get_maxdiv(table, width, flags);
416
417 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
418 {
419 parent_rate = *best_parent_rate;
420 bestdiv = _div_round(table, parent_rate, rate, flags);
421 bestdiv = bestdiv == 0 ? 1 : bestdiv;
422 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
423 return bestdiv;
424 }
425
426 /*
427 * The maximum divider we can use without overflowing
428 * unsigned long in rate * i below
429 */
430 maxdiv = min(ULONG_MAX / rate, maxdiv);
431
432 for (i = _next_div(table, 0, flags); i <= maxdiv;
433 i = _next_div(table, i, flags))
434 {
435 if (rate * i == parent_rate_saved)
436 {
437 /*
438 * It's the most ideal case if the requested rate can be
439 * divided from parent clock without needing to change
440 * parent rate, so return the divider immediately.
441 */
442 *best_parent_rate = parent_rate_saved;
443 return i;
444 }
445 parent_rate = clk_hw_round_rate(parent, rate * i);
446 now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
447 if (_is_best_div(rate, now, best, flags))
448 {
449 bestdiv = i;
450 best = now;
451 *best_parent_rate = parent_rate;
452 }
453 }
454
455 if (!bestdiv)
456 {
457 bestdiv = _get_maxdiv(table, width, flags);
458 *best_parent_rate = clk_hw_round_rate(parent, 1);
459 }
460
461 return bestdiv;
462 }
463
divider_round_rate_parent(struct clk_hw * hw,struct clk_hw * parent,unsigned long rate,unsigned long * prate,const struct clk_div_table * table,u8 width,unsigned long flags)464 long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
465 unsigned long rate, unsigned long *prate,
466 const struct clk_div_table *table,
467 u8 width, unsigned long flags)
468 {
469 int div;
470
471 div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags);
472
473 return DIV_ROUND_UP_ULL((u64) * prate, div);
474 }
475
divider_ro_round_rate_parent(struct clk_hw * hw,struct clk_hw * parent,unsigned long rate,unsigned long * prate,const struct clk_div_table * table,u8 width,unsigned long flags,unsigned int val)476 long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
477 unsigned long rate, unsigned long *prate,
478 const struct clk_div_table *table, u8 width,
479 unsigned long flags, unsigned int val)
480 {
481 int div;
482
483 div = _get_div(table, val, flags, width);
484
485 /* Even a read-only clock can propagate a rate change */
486 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)
487 {
488 if (!parent)
489 {
490 return -1;
491 }
492
493 *prate = clk_hw_round_rate(parent, rate * div);
494 }
495
496 return DIV_ROUND_UP_ULL((u64) * prate, div);
497 }
498
clk_divider_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)499 static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
500 unsigned long *prate)
501 {
502 struct clk_divider *divider = to_clk_divider(hw);
503
504 /* if read only, just return current value */
505 if (divider->flags & CLK_DIVIDER_READ_ONLY)
506 {
507 u32 val;
508
509 val = clk_div_readl(divider) >> divider->shift;
510 val &= clk_div_mask(divider->width);
511
512 return divider_ro_round_rate(hw, rate, prate, divider->table,
513 divider->width, divider->flags,
514 val);
515 }
516
517 return divider_round_rate(hw, rate, prate, divider->table,
518 divider->width, divider->flags);
519 }
520
divider_get_val(unsigned long rate,unsigned long parent_rate,const struct clk_div_table * table,u8 width,unsigned long flags)521 int divider_get_val(unsigned long rate, unsigned long parent_rate,
522 const struct clk_div_table *table, u8 width,
523 unsigned long flags)
524 {
525 unsigned int div, value;
526
527 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
528
529 if (!_is_valid_div(table, div, flags))
530 {
531 return -1;
532 }
533
534 value = _get_val(table, div, flags, width);
535
536 return min(value, clk_div_mask(width));
537 }
538
clk_divider_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)539 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
540 unsigned long parent_rate)
541 {
542 struct clk_divider *divider = to_clk_divider(hw);
543 int value;
544 u32 val;
545 u32 __cspr;
546
547 value = divider_get_val(rate, parent_rate, divider->table,
548 divider->width, divider->flags);
549 if (value < 0)
550 {
551 return value;
552 }
553
554 __cspr = hal_spin_lock_irqsave(÷r->lock);
555
556 if (divider->flags & CLK_DIVIDER_HIWORD_MASK)
557 {
558 val = clk_div_mask(divider->width) << (divider->shift + 16);
559 }
560 else
561 {
562 val = clk_div_readl(divider);
563 val &= ~(clk_div_mask(divider->width) << divider->shift);
564 }
565 val |= (u32)value << divider->shift;
566 clk_div_writel(divider, val);
567
568 hal_spin_unlock_irqrestore(÷r->lock, __cspr);
569
570 return 0;
571 }
572
573 const struct clk_ops clk_divider_ops =
574 {
575 .recalc_rate = clk_divider_recalc_rate,
576 .round_rate = clk_divider_round_rate,
577 .set_rate = clk_divider_set_rate,
578 };
579
580 const struct clk_ops clk_divider_ro_ops =
581 {
582 .recalc_rate = clk_divider_recalc_rate,
583 .round_rate = clk_divider_round_rate,
584 };
585
_register_divider(const char * name,const char * parent_name,unsigned long flags,u32 reg,u8 shift,u8 width,u8 clk_divider_flags,const struct clk_div_table * table,hal_spinlock_t lock)586 static struct clk_hw *_register_divider(const char *name,
587 const char *parent_name, unsigned long flags,
588 u32 reg, u8 shift, u8 width,
589 u8 clk_divider_flags, const struct clk_div_table *table,
590 hal_spinlock_t lock)
591 {
592 struct clk_divider *div;
593 struct clk_hw *hw;
594 struct clk_init_data init;
595 int ret;
596
597 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK)
598 {
599 if (width + shift > 16)
600 {
601 return NULL;
602 }
603 }
604
605 div = malloc(sizeof(*div));
606 if (!div)
607 {
608 return NULL;
609 }
610
611 init.name = name;
612 if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
613 {
614 init.ops = &clk_divider_ro_ops;
615 }
616 else
617 {
618 init.ops = &clk_divider_ops;
619 }
620 init.flags = flags;
621 init.parent_names = (parent_name ? &parent_name : NULL);
622 init.num_parents = (parent_name ? 1 : 0);
623
624 /* struct clk_divider assignments */
625 div->reg = reg;
626 div->shift = shift;
627 div->width = width;
628 div->flags = clk_divider_flags;
629 div->lock = lock;
630 div->hw.init = &init;
631 div->table = table;
632
633 /* register the clock */
634 hw = &(div->hw);
635 ret = clk_hw_register(hw);
636 if (ret)
637 {
638 free(div);
639 hw = NULL;
640 }
641
642 return hw;
643 }
644
645 /**
646 * clk_hw_register_divider - register a divider clock with the clock framework
647 * @name: name of this clock
648 * @parent_name: name of clock's parent
649 * @flags: framework-specific flags
650 * @reg: register address to adjust divider
651 * @shift: number of bits to shift the bitfield
652 * @width: width of the bitfield
653 * @clk_divider_flags: divider-specific flags for this clock
654 * @lock: shared register lock for this clock
655 */
clk_hw_register_divider(const char * name,const char * parent_name,unsigned long flags,u32 reg,u8 shift,u8 width,u8 clk_divider_flags,hal_spinlock_t lock)656 struct clk_hw *clk_hw_register_divider(const char *name,
657 const char *parent_name, unsigned long flags,
658 u32 reg, u8 shift, u8 width,
659 u8 clk_divider_flags, hal_spinlock_t lock)
660 {
661 return _register_divider(name, parent_name, flags, reg, shift,
662 width, clk_divider_flags, NULL, lock);
663 }
664
665 /**
666 * clk_hw_register_divider_table - register a table based divider clock with
667 * the clock framework
668 * @name: name of this clock
669 * @parent_name: name of clock's parent
670 * @flags: framework-specific flags
671 * @reg: register address to adjust divider
672 * @shift: number of bits to shift the bitfield
673 * @width: width of the bitfield
674 * @clk_divider_flags: divider-specific flags for this clock
675 * @table: array of divider/value pairs ending with a div set to 0
676 * @lock: shared register lock for this clock
677 */
clk_hw_register_divider_table(const char * name,const char * parent_name,unsigned long flags,u32 reg,u8 shift,u8 width,u8 clk_divider_flags,const struct clk_div_table * table,hal_spinlock_t lock)678 struct clk_hw *clk_hw_register_divider_table(const char *name,
679 const char *parent_name, unsigned long flags,
680 u32 reg, u8 shift, u8 width,
681 u8 clk_divider_flags, const struct clk_div_table *table,
682 hal_spinlock_t lock)
683 {
684 return _register_divider(name, parent_name, flags, reg, shift,
685 width, clk_divider_flags, table, lock);
686 }
687
688 /**
689 * clk_hw_unregister_divider - unregister a clk divider
690 * @hw: hardware-specific clock data to unregister
691 */
clk_hw_unregister_divider(struct clk_hw * hw)692 void clk_hw_unregister_divider(struct clk_hw *hw)
693 {
694 struct clk_divider *div;
695
696 div = to_clk_divider(hw);
697
698 clk_hw_unregister(hw);
699 free(div);
700 }
701