forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/clk/ingenic/cgu.c
....@@ -1,18 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Ingenic SoC CGU driver
34 *
45 * Copyright (c) 2013-2015 Imagination Technologies
56 * Author: Paul Burton <paul.burton@mips.com>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License as
9
- * published by the Free Software Foundation; either version 2 of
10
- * the License, or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
167 */
178
189 #include <linux/bitops.h>
....@@ -20,14 +11,24 @@
2011 #include <linux/clk-provider.h>
2112 #include <linux/clkdev.h>
2213 #include <linux/delay.h>
14
+#include <linux/io.h>
15
+#include <linux/iopoll.h>
2316 #include <linux/math64.h>
2417 #include <linux/of.h>
2518 #include <linux/of_address.h>
2619 #include <linux/slab.h>
2720 #include <linux/spinlock.h>
21
+#include <linux/time.h>
22
+
2823 #include "cgu.h"
2924
3025 #define MHZ (1000 * 1000)
26
+
27
+static inline const struct ingenic_cgu_clk_info *
28
+to_clk_info(struct ingenic_clk *clk)
29
+{
30
+ return &clk->cgu->clock_info[clk->idx];
31
+}
3132
3233 /**
3334 * ingenic_cgu_gate_get() - get the value of clock gate register bit
....@@ -79,21 +80,17 @@
7980 ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
8081 {
8182 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
83
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
8284 struct ingenic_cgu *cgu = ingenic_clk->cgu;
83
- const struct ingenic_cgu_clk_info *clk_info;
8485 const struct ingenic_cgu_pll_info *pll_info;
8586 unsigned m, n, od_enc, od;
86
- bool bypass, enable;
87
- unsigned long flags;
87
+ bool bypass;
8888 u32 ctl;
8989
90
- clk_info = &cgu->clock_info[ingenic_clk->idx];
9190 BUG_ON(clk_info->type != CGU_CLK_PLL);
9291 pll_info = &clk_info->pll;
9392
94
- spin_lock_irqsave(&cgu->lock, flags);
9593 ctl = readl(cgu->base + pll_info->reg);
96
- spin_unlock_irqrestore(&cgu->lock, flags);
9794
9895 m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
9996 m += pll_info->m_offset;
....@@ -101,9 +98,11 @@
10198 n += pll_info->n_offset;
10299 od_enc = ctl >> pll_info->od_shift;
103100 od_enc &= GENMASK(pll_info->od_bits - 1, 0);
101
+
102
+ ctl = readl(cgu->base + pll_info->bypass_reg);
103
+
104104 bypass = !pll_info->no_bypass_bit &&
105105 !!(ctl & BIT(pll_info->bypass_bit));
106
- enable = !!(ctl & BIT(pll_info->enable_bit));
107106
108107 if (bypass)
109108 return parent_rate;
....@@ -115,7 +114,8 @@
115114 BUG_ON(od == pll_info->od_max);
116115 od++;
117116
118
- return div_u64((u64)parent_rate * m, n * od);
117
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
118
+ n * od);
119119 }
120120
121121 static unsigned long
....@@ -148,19 +148,8 @@
148148 if (pod)
149149 *pod = od;
150150
151
- return div_u64((u64)parent_rate * m, n * od);
152
-}
153
-
154
-static inline const struct ingenic_cgu_clk_info *to_clk_info(
155
- struct ingenic_clk *ingenic_clk)
156
-{
157
- struct ingenic_cgu *cgu = ingenic_clk->cgu;
158
- const struct ingenic_cgu_clk_info *clk_info;
159
-
160
- clk_info = &cgu->clock_info[ingenic_clk->idx];
161
- BUG_ON(clk_info->type != CGU_CLK_PLL);
162
-
163
- return clk_info;
151
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
152
+ n * od);
164153 }
165154
166155 static long
....@@ -173,6 +162,16 @@
173162 return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
174163 }
175164
165
+static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu,
166
+ const struct ingenic_cgu_pll_info *pll_info)
167
+{
168
+ u32 ctl;
169
+
170
+ return readl_poll_timeout(cgu->base + pll_info->reg, ctl,
171
+ ctl & BIT(pll_info->stable_bit),
172
+ 0, 100 * USEC_PER_MSEC);
173
+}
174
+
176175 static int
177176 ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
178177 unsigned long parent_rate)
....@@ -183,6 +182,7 @@
183182 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
184183 unsigned long rate, flags;
185184 unsigned int m, n, od;
185
+ int ret = 0;
186186 u32 ctl;
187187
188188 rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
....@@ -204,9 +204,14 @@
204204 ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
205205
206206 writel(ctl, cgu->base + pll_info->reg);
207
+
208
+ /* If the PLL is enabled, verify that it's stable */
209
+ if (ctl & BIT(pll_info->enable_bit))
210
+ ret = ingenic_pll_check_stable(cgu, pll_info);
211
+
207212 spin_unlock_irqrestore(&cgu->lock, flags);
208213
209
- return 0;
214
+ return ret;
210215 }
211216
212217 static int ingenic_pll_enable(struct clk_hw *hw)
....@@ -215,33 +220,27 @@
215220 struct ingenic_cgu *cgu = ingenic_clk->cgu;
216221 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
217222 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
218
- const unsigned int timeout = 100;
219223 unsigned long flags;
220
- unsigned int i;
224
+ int ret;
221225 u32 ctl;
222226
223227 spin_lock_irqsave(&cgu->lock, flags);
224
- ctl = readl(cgu->base + pll_info->reg);
228
+ ctl = readl(cgu->base + pll_info->bypass_reg);
225229
226230 ctl &= ~BIT(pll_info->bypass_bit);
231
+
232
+ writel(ctl, cgu->base + pll_info->bypass_reg);
233
+
234
+ ctl = readl(cgu->base + pll_info->reg);
235
+
227236 ctl |= BIT(pll_info->enable_bit);
228237
229238 writel(ctl, cgu->base + pll_info->reg);
230239
231
- /* wait for the PLL to stabilise */
232
- for (i = 0; i < timeout; i++) {
233
- ctl = readl(cgu->base + pll_info->reg);
234
- if (ctl & BIT(pll_info->stable_bit))
235
- break;
236
- mdelay(1);
237
- }
238
-
240
+ ret = ingenic_pll_check_stable(cgu, pll_info);
239241 spin_unlock_irqrestore(&cgu->lock, flags);
240242
241
- if (i == timeout)
242
- return -EBUSY;
243
-
244
- return 0;
243
+ return ret;
245244 }
246245
247246 static void ingenic_pll_disable(struct clk_hw *hw)
....@@ -268,12 +267,9 @@
268267 struct ingenic_cgu *cgu = ingenic_clk->cgu;
269268 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
270269 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
271
- unsigned long flags;
272270 u32 ctl;
273271
274
- spin_lock_irqsave(&cgu->lock, flags);
275272 ctl = readl(cgu->base + pll_info->reg);
276
- spin_unlock_irqrestore(&cgu->lock, flags);
277273
278274 return !!(ctl & BIT(pll_info->enable_bit));
279275 }
....@@ -295,12 +291,10 @@
295291 static u8 ingenic_clk_get_parent(struct clk_hw *hw)
296292 {
297293 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
294
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
298295 struct ingenic_cgu *cgu = ingenic_clk->cgu;
299
- const struct ingenic_cgu_clk_info *clk_info;
300296 u32 reg;
301297 u8 i, hw_idx, idx = 0;
302
-
303
- clk_info = &cgu->clock_info[ingenic_clk->idx];
304298
305299 if (clk_info->type & CGU_CLK_MUX) {
306300 reg = readl(cgu->base + clk_info->mux.reg);
....@@ -323,13 +317,11 @@
323317 static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)
324318 {
325319 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
320
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
326321 struct ingenic_cgu *cgu = ingenic_clk->cgu;
327
- const struct ingenic_cgu_clk_info *clk_info;
328322 unsigned long flags;
329323 u8 curr_idx, hw_idx, num_poss;
330324 u32 reg, mask;
331
-
332
- clk_info = &cgu->clock_info[ingenic_clk->idx];
333325
334326 if (clk_info->type & CGU_CLK_MUX) {
335327 /*
....@@ -373,19 +365,20 @@
373365 ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
374366 {
375367 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
368
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
376369 struct ingenic_cgu *cgu = ingenic_clk->cgu;
377
- const struct ingenic_cgu_clk_info *clk_info;
378370 unsigned long rate = parent_rate;
379371 u32 div_reg, div;
380
-
381
- clk_info = &cgu->clock_info[ingenic_clk->idx];
382372
383373 if (clk_info->type & CGU_CLK_DIV) {
384374 div_reg = readl(cgu->base + clk_info->div.reg);
385375 div = (div_reg >> clk_info->div.shift) &
386376 GENMASK(clk_info->div.bits - 1, 0);
387
- div += 1;
388
- div *= clk_info->div.div;
377
+
378
+ if (clk_info->div.div_table)
379
+ div = clk_info->div.div_table[div];
380
+ else
381
+ div = (div + 1) * clk_info->div.div;
389382
390383 rate /= div;
391384 } else if (clk_info->type & CGU_CLK_FIXDIV) {
....@@ -395,25 +388,52 @@
395388 return rate;
396389 }
397390
391
+static unsigned int
392
+ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info,
393
+ unsigned int div)
394
+{
395
+ unsigned int i, best_i = 0, best = (unsigned int)-1;
396
+
397
+ for (i = 0; i < (1 << clk_info->div.bits)
398
+ && clk_info->div.div_table[i]; i++) {
399
+ if (clk_info->div.div_table[i] >= div &&
400
+ clk_info->div.div_table[i] < best) {
401
+ best = clk_info->div.div_table[i];
402
+ best_i = i;
403
+
404
+ if (div == best)
405
+ break;
406
+ }
407
+ }
408
+
409
+ return best_i;
410
+}
411
+
398412 static unsigned
399413 ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
400414 unsigned long parent_rate, unsigned long req_rate)
401415 {
402
- unsigned div;
416
+ unsigned int div, hw_div;
403417
404418 /* calculate the divide */
405419 div = DIV_ROUND_UP(parent_rate, req_rate);
406420
407
- /* and impose hardware constraints */
408
- div = min_t(unsigned, div, 1 << clk_info->div.bits);
409
- div = max_t(unsigned, div, 1);
421
+ if (clk_info->div.div_table) {
422
+ hw_div = ingenic_clk_calc_hw_div(clk_info, div);
423
+
424
+ return clk_info->div.div_table[hw_div];
425
+ }
426
+
427
+ /* Impose hardware constraints */
428
+ div = clamp_t(unsigned int, div, clk_info->div.div,
429
+ clk_info->div.div << clk_info->div.bits);
410430
411431 /*
412432 * If the divider value itself must be divided before being written to
413433 * the divider register, we must ensure we don't have any bits set that
414434 * would be lost as a result of doing so.
415435 */
416
- div /= clk_info->div.div;
436
+ div = DIV_ROUND_UP(div, clk_info->div.div);
417437 div *= clk_info->div.div;
418438
419439 return div;
....@@ -424,18 +444,27 @@
424444 unsigned long *parent_rate)
425445 {
426446 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
427
- struct ingenic_cgu *cgu = ingenic_clk->cgu;
428
- const struct ingenic_cgu_clk_info *clk_info;
447
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
429448 unsigned int div = 1;
430
-
431
- clk_info = &cgu->clock_info[ingenic_clk->idx];
432449
433450 if (clk_info->type & CGU_CLK_DIV)
434451 div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
435452 else if (clk_info->type & CGU_CLK_FIXDIV)
436453 div = clk_info->fixdiv.div;
454
+ else if (clk_hw_can_set_rate_parent(hw))
455
+ *parent_rate = req_rate;
437456
438457 return DIV_ROUND_UP(*parent_rate, div);
458
+}
459
+
460
+static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,
461
+ const struct ingenic_cgu_clk_info *clk_info)
462
+{
463
+ u32 reg;
464
+
465
+ return readl_poll_timeout(cgu->base + clk_info->div.reg, reg,
466
+ !(reg & BIT(clk_info->div.busy_bit)),
467
+ 0, 100 * USEC_PER_MSEC);
439468 }
440469
441470 static int
....@@ -443,15 +472,12 @@
443472 unsigned long parent_rate)
444473 {
445474 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
475
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
446476 struct ingenic_cgu *cgu = ingenic_clk->cgu;
447
- const struct ingenic_cgu_clk_info *clk_info;
448
- const unsigned timeout = 100;
449477 unsigned long rate, flags;
450
- unsigned div, i;
478
+ unsigned int hw_div, div;
451479 u32 reg, mask;
452480 int ret = 0;
453
-
454
- clk_info = &cgu->clock_info[ingenic_clk->idx];
455481
456482 if (clk_info->type & CGU_CLK_DIV) {
457483 div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
....@@ -460,13 +486,18 @@
460486 if (rate != req_rate)
461487 return -EINVAL;
462488
489
+ if (clk_info->div.div_table)
490
+ hw_div = ingenic_clk_calc_hw_div(clk_info, div);
491
+ else
492
+ hw_div = ((div / clk_info->div.div) - 1);
493
+
463494 spin_lock_irqsave(&cgu->lock, flags);
464495 reg = readl(cgu->base + clk_info->div.reg);
465496
466497 /* update the divide */
467498 mask = GENMASK(clk_info->div.bits - 1, 0);
468499 reg &= ~(mask << clk_info->div.shift);
469
- reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift;
500
+ reg |= hw_div << clk_info->div.shift;
470501
471502 /* clear the stop bit */
472503 if (clk_info->div.stop_bit != -1)
....@@ -480,16 +511,8 @@
480511 writel(reg, cgu->base + clk_info->div.reg);
481512
482513 /* wait for the change to take effect */
483
- if (clk_info->div.busy_bit != -1) {
484
- for (i = 0; i < timeout; i++) {
485
- reg = readl(cgu->base + clk_info->div.reg);
486
- if (!(reg & BIT(clk_info->div.busy_bit)))
487
- break;
488
- mdelay(1);
489
- }
490
- if (i == timeout)
491
- ret = -EBUSY;
492
- }
514
+ if (clk_info->div.busy_bit != -1)
515
+ ret = ingenic_clk_check_stable(cgu, clk_info);
493516
494517 spin_unlock_irqrestore(&cgu->lock, flags);
495518 return ret;
....@@ -501,11 +524,9 @@
501524 static int ingenic_clk_enable(struct clk_hw *hw)
502525 {
503526 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
527
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
504528 struct ingenic_cgu *cgu = ingenic_clk->cgu;
505
- const struct ingenic_cgu_clk_info *clk_info;
506529 unsigned long flags;
507
-
508
- clk_info = &cgu->clock_info[ingenic_clk->idx];
509530
510531 if (clk_info->type & CGU_CLK_GATE) {
511532 /* ungate the clock */
....@@ -523,11 +544,9 @@
523544 static void ingenic_clk_disable(struct clk_hw *hw)
524545 {
525546 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
547
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
526548 struct ingenic_cgu *cgu = ingenic_clk->cgu;
527
- const struct ingenic_cgu_clk_info *clk_info;
528549 unsigned long flags;
529
-
530
- clk_info = &cgu->clock_info[ingenic_clk->idx];
531550
532551 if (clk_info->type & CGU_CLK_GATE) {
533552 /* gate the clock */
....@@ -540,18 +559,12 @@
540559 static int ingenic_clk_is_enabled(struct clk_hw *hw)
541560 {
542561 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
562
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
543563 struct ingenic_cgu *cgu = ingenic_clk->cgu;
544
- const struct ingenic_cgu_clk_info *clk_info;
545
- unsigned long flags;
546564 int enabled = 1;
547565
548
- clk_info = &cgu->clock_info[ingenic_clk->idx];
549
-
550
- if (clk_info->type & CGU_CLK_GATE) {
551
- spin_lock_irqsave(&cgu->lock, flags);
566
+ if (clk_info->type & CGU_CLK_GATE)
552567 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
553
- spin_unlock_irqrestore(&cgu->lock, flags);
554
- }
555568
556569 return enabled;
557570 }
....@@ -624,6 +637,13 @@
624637
625638 caps = clk_info->type;
626639
640
+ if (caps & CGU_CLK_DIV) {
641
+ caps &= ~CGU_CLK_DIV;
642
+ } else if (!(caps & CGU_CLK_CUSTOM)) {
643
+ /* pass rate changes to the parent clock */
644
+ clk_init.flags |= CLK_SET_RATE_PARENT;
645
+ }
646
+
627647 if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
628648 clk_init.num_parents = 0;
629649
....@@ -663,7 +683,6 @@
663683 }
664684 } else if (caps & CGU_CLK_PLL) {
665685 clk_init.ops = &ingenic_pll_ops;
666
- clk_init.flags |= CLK_SET_RATE_GATE;
667686
668687 caps &= ~CGU_CLK_PLL;
669688
....@@ -684,13 +703,6 @@
684703 clk_init.flags |= CLK_SET_PARENT_GATE;
685704
686705 caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
687
- }
688
-
689
- if (caps & CGU_CLK_DIV) {
690
- caps &= ~CGU_CLK_DIV;
691
- } else {
692
- /* pass rate changes to the parent clock */
693
- clk_init.flags |= CLK_SET_RATE_PARENT;
694706 }
695707
696708 if (caps) {