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(&divider->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(&divider->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