• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2014 MundoReader S.L.
4  * Author: Heiko Stuebner <heiko@sntech.de>
5  *
6  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
7  * Author: Xing Zheng <zhengxing@rock-chips.com>
8  */
9 
10 #include <asm/div64.h>
11 #include <linux/slab.h>
12 #include <linux/io.h>
13 #include <linux/delay.h>
14 #include <linux/clk-provider.h>
15 #include <linux/iopoll.h>
16 #include <linux/regmap.h>
17 #include <linux/clk.h>
18 #include <linux/gcd.h>
19 #include <linux/clk/rockchip.h>
20 #include <linux/mfd/syscon.h>
21 #include "clk.h"
22 
23 #define PLL_MODE_MASK 0x3
24 #define PLL_MODE_SLOW 0x0
25 #define PLL_MODE_NORM 0x1
26 #define PLL_MODE_DEEP 0x2
27 #define PLL_RK3328_MODE_MASK 0x1
28 
29 #define BOOTST_FILE_READ 0444
30 
31 struct rockchip_clk_pll {
32     struct clk_hw hw;
33 
34     struct clk_mux pll_mux;
35     const struct clk_ops *pll_mux_ops;
36 
37     struct notifier_block clk_nb;
38 
39     void __iomem *reg_base;
40     int lock_offset;
41     unsigned int lock_shift;
42     enum rockchip_pll_type type;
43     u8 flags;
44     const struct rockchip_pll_rate_table *rate_table;
45     unsigned int rate_count;
46     int sel;
47     unsigned long scaling;
48     spinlock_t *lock;
49 
50     struct rockchip_clk_provider *ctx;
51 
52     bool boost_enabled;
53     u32 boost_backup_pll_usage;
54     unsigned long boost_backup_pll_rate;
55     unsigned long boost_low_rate;
56     unsigned long boost_high_rate;
57     struct regmap *boost;
58 #ifdef CONFIG_DEBUG_FS
59     struct hlist_node debug_node;
60 #endif
61 };
62 
63 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
64 #define to_rockchip_clk_pll_nb(nb) container_of(nb, struct rockchip_clk_pll, clk_nb)
65 
66 static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll);
67 
68 #define MHZ (1000UL * 1000UL)
69 #define KHZ (1000UL)
70 
71 /* CLK_PLL_TYPE_RK3066_AUTO type ops */
72 #define PLL_FREF_MIN (269 * KHZ)
73 #define PLL_FREF_MAX (2200 * MHZ)
74 
75 #define PLL_FVCO_MIN (440 * MHZ)
76 #define PLL_FVCO_MAX (2200 * MHZ)
77 
78 #define PLL_FOUT_MIN (27500 * KHZ)
79 #define PLL_FOUT_MAX (2200 * MHZ)
80 
81 #define PLL_NF_MAX (4096)
82 #define PLL_NR_MAX (64)
83 #define PLL_NO_MAX (16)
84 
85 /* CLK_PLL_TYPE_RK3036/3366/3399_AUTO type ops */
86 #define MIN_FOUTVCO_FREQ (800 * MHZ)
87 #define MAX_FOUTVCO_FREQ (2000 * MHZ)
88 
89 static struct rockchip_pll_rate_table auto_table;
90 #ifdef CONFIG_DEBUG_FS
91 static HLIST_HEAD(clk_boost_list);
92 static DEFINE_MUTEX(clk_boost_lock);
93 #endif
94 
rockchip_pll_clk_adaptive_scaling(struct clk * clk,int sel)95 int rockchip_pll_clk_adaptive_scaling(struct clk *clk, int sel)
96 {
97     struct clk *parent = clk_get_parent(clk);
98     struct rockchip_clk_pll *pll;
99 
100     if (IS_ERR_OR_NULL(parent)) {
101         return -EINVAL;
102     }
103 
104     pll = to_rockchip_clk_pll(__clk_get_hw(parent));
105     if (!pll) {
106         return -EINVAL;
107     }
108 
109     pll->sel = sel;
110 
111     return 0;
112 }
113 EXPORT_SYMBOL(rockchip_pll_clk_adaptive_scaling);
114 
rockchip_pll_clk_rate_to_scale(struct clk * clk,unsigned long rate)115 int rockchip_pll_clk_rate_to_scale(struct clk *clk, unsigned long rate)
116 {
117     const struct rockchip_pll_rate_table *rate_table;
118     struct clk *parent = clk_get_parent(clk);
119     struct rockchip_clk_pll *pll;
120     unsigned int i;
121 
122     if (IS_ERR_OR_NULL(parent)) {
123         return -EINVAL;
124     }
125 
126     pll = to_rockchip_clk_pll(__clk_get_hw(parent));
127     if (!pll) {
128         return -EINVAL;
129     }
130 
131     rate_table = pll->rate_table;
132     for (i = 0; i < pll->rate_count; i++) {
133         if (rate >= rate_table[i].rate) {
134             return i;
135         }
136     }
137 
138     return -EINVAL;
139 }
140 EXPORT_SYMBOL(rockchip_pll_clk_rate_to_scale);
141 
rockchip_pll_clk_scale_to_rate(struct clk * clk,unsigned int scale)142 int rockchip_pll_clk_scale_to_rate(struct clk *clk, unsigned int scale)
143 {
144     const struct rockchip_pll_rate_table *rate_table;
145     struct clk *parent = clk_get_parent(clk);
146     struct rockchip_clk_pll *pll;
147     unsigned int i;
148 
149     if (IS_ERR_OR_NULL(parent)) {
150         return -EINVAL;
151     }
152 
153     pll = to_rockchip_clk_pll(__clk_get_hw(parent));
154     if (!pll) {
155         return -EINVAL;
156     }
157 
158     rate_table = pll->rate_table;
159     for (i = 0; i < pll->rate_count; i++) {
160         if (i == scale) {
161             return rate_table[i].rate;
162         }
163     }
164 
165     return -EINVAL;
166 }
167 EXPORT_SYMBOL(rockchip_pll_clk_scale_to_rate);
168 
rk_pll_rate_table_get(void)169 static struct rockchip_pll_rate_table *rk_pll_rate_table_get(void)
170 {
171     return &auto_table;
172 }
173 
rockchip_pll_clk_set_postdiv(unsigned long fout_hz,u32 * postdiv1,u32 * postdiv2,u32 * foutvco)174 static int rockchip_pll_clk_set_postdiv(unsigned long fout_hz, u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
175 {
176     unsigned long freq;
177 
178     if (fout_hz < MIN_FOUTVCO_FREQ) {
179         for (*postdiv1 = 1; *postdiv1 <= 0x7; (*postdiv1)++) {
180             for (*postdiv2 = 1; *postdiv2 <= 0x7; (*postdiv2)++) {
181                 freq = fout_hz * (*postdiv1) * (*postdiv2);
182                 if (freq >= MIN_FOUTVCO_FREQ && freq <= MAX_FOUTVCO_FREQ) {
183                     *foutvco = freq;
184                     return 0;
185                 }
186             }
187         }
188         pr_err("CANNOT FIND postdiv1/2 to make fout in range from 800M to 2000M,fout = %lu\n", fout_hz);
189     } else {
190         *postdiv1 = 1;
191         *postdiv2 = 1;
192     }
193     return 0;
194 }
195 
rockchip_pll_clk_set_by_auto(struct rockchip_clk_pll * pll,unsigned long fin_hz,unsigned long fout_hz)196 static struct rockchip_pll_rate_table *rockchip_pll_clk_set_by_auto(struct rockchip_clk_pll *pll, unsigned long fin_hz,
197                                                                     unsigned long fout_hz)
198 {
199     struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
200     /* set postdiv1/2 always 1 */
201     u32 foutvco = fout_hz;
202     u64 fin_64, frac_64;
203     u32 f_frac, postdiv1, postdiv2;
204     unsigned long clk_gcd = 0;
205 
206     if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) {
207         return NULL;
208     }
209 
210     rockchip_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
211     rate_table->postdiv1 = postdiv1;
212     rate_table->postdiv2 = postdiv2;
213     rate_table->dsmpd = 1;
214 
215     if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
216         fin_hz /= MHZ;
217         foutvco /= MHZ;
218         clk_gcd = gcd(fin_hz, foutvco);
219         if (clk_gcd == 0) {
220             return -1;
221         }
222         rate_table->refdiv = fin_hz / clk_gcd;
223         rate_table->fbdiv = foutvco / clk_gcd;
224 
225         rate_table->frac = 0;
226 
227         pr_debug(
228             "fin = %lu, fout = %lu, clk_gcd = %lu, refdiv = %u, fbdiv = %u, postdiv1 = %u, postdiv2 = %u, frac = %u\n",
229             fin_hz, fout_hz, clk_gcd, rate_table->refdiv, rate_table->fbdiv, rate_table->postdiv1, rate_table->postdiv2,
230             rate_table->frac);
231     } else {
232         pr_debug("frac div running, fin_hz = %lu, fout_hz = %lu, fin_INT_mhz = %lu, fout_INT_mhz = %lu\n", fin_hz,
233                  fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
234         pr_debug("frac get postdiv1 = %u,  postdiv2 = %u, foutvco = %u\n", rate_table->postdiv1, rate_table->postdiv2,
235                  foutvco);
236         clk_gcd = gcd(fin_hz / MHZ, foutvco / MHZ);
237         rate_table->refdiv = fin_hz / MHZ / clk_gcd;
238         rate_table->fbdiv = foutvco / MHZ / clk_gcd;
239         pr_debug("frac get refdiv = %u,  fbdiv = %u\n", rate_table->refdiv, rate_table->fbdiv);
240 
241         rate_table->frac = 0;
242 
243         f_frac = (foutvco % MHZ);
244         fin_64 = fin_hz;
245         do_div(fin_64, (u64)rate_table->refdiv);
246         frac_64 = (u64)f_frac << 0x18;
247         do_div(frac_64, fin_64);
248         rate_table->frac = (u32)frac_64;
249         if (rate_table->frac > 0) {
250             rate_table->dsmpd = 0;
251         }
252         pr_debug("frac = %x\n", rate_table->frac);
253     }
254     return rate_table;
255 }
256 
rockchip_rk3066_pll_clk_set_by_auto(struct rockchip_clk_pll * pll,unsigned long fin_hz,unsigned long fout_hz)257 static struct rockchip_pll_rate_table *rockchip_rk3066_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
258                                                                            unsigned long fin_hz, unsigned long fout_hz)
259 {
260     struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
261     u32 nr, nf, no, nonr;
262     u32 nr_out, nf_out, no_out;
263     u32 n;
264     u32 numerator, denominator;
265     u64 fref, fvco, fout;
266     unsigned long clk_gcd = 0;
267 
268     nr_out = PLL_NR_MAX + 1;
269     no_out = 0;
270     nf_out = 0;
271 
272     if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) {
273         return NULL;
274     }
275 
276     clk_gcd = gcd(fin_hz, fout_hz);
277     if (clk_gcd == 0) {
278         return NULL;
279     }
280     numerator = fout_hz / clk_gcd;
281     denominator = fin_hz / clk_gcd;
282 
283     for (n = 1;; n++) {
284         nf = numerator * n;
285         nonr = denominator * n;
286         if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX)) {
287             break;
288         }
289 
290         for (no = 1; no <= PLL_NO_MAX; no++) {
291             if (!(no == 1 || !(no % 0x2))) {
292                 continue;
293             }
294 
295             if (nonr % no) {
296                 continue;
297             }
298             nr = nonr / no;
299 
300             if (nr > PLL_NR_MAX) {
301                 continue;
302             }
303 
304             fref = fin_hz / nr;
305             if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX) {
306                 continue;
307             }
308 
309             fvco = fref * nf;
310             if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX) {
311                 continue;
312             }
313 
314             fout = fvco / no;
315             if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX) {
316                 continue;
317             }
318 
319             /* select the best from all available PLL settings */
320             if ((no > no_out) || ((no == no_out) && (nr < nr_out))) {
321                 nr_out = nr;
322                 nf_out = nf;
323                 no_out = no;
324             }
325         }
326     }
327 
328     /* output the best PLL setting */
329     if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
330         rate_table->nr = nr_out;
331         rate_table->nf = nf_out;
332         rate_table->no = no_out;
333     } else {
334         return NULL;
335     }
336 
337     return rate_table;
338 }
339 
rockchip_get_pll_settings(struct rockchip_clk_pll * pll,unsigned long rate)340 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(struct rockchip_clk_pll *pll, unsigned long rate)
341 {
342     const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
343     int i;
344 
345     for (i = 0; i < pll->rate_count; i++) {
346         if (rate == rate_table[i].rate) {
347             if (i < pll->sel) {
348                 pll->scaling = rate;
349                 return &rate_table[pll->sel];
350             }
351             pll->scaling = 0;
352             return &rate_table[i];
353         }
354     }
355     pll->scaling = 0;
356 
357     if (pll->type == pll_rk3066) {
358         return rockchip_rk3066_pll_clk_set_by_auto(pll, 0x18 * MHZ, rate);
359     } else {
360         return rockchip_pll_clk_set_by_auto(pll, 0x18 * MHZ, rate);
361     }
362 }
363 
rockchip_pll_round_rate(struct clk_hw * hw,unsigned long drate,unsigned long * prate)364 static long rockchip_pll_round_rate(struct clk_hw *hw, unsigned long drate, unsigned long *prate)
365 {
366     return drate;
367 }
368 
369 /*
370  * Wait for the pll to reach the locked state.
371  * The calling set_rate function is responsible for making sure the
372  * grf regmap is available.
373  */
rockchip_pll_wait_lock(struct rockchip_clk_pll * pll)374 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
375 {
376     struct regmap *grf = pll->ctx->grf;
377     unsigned int val;
378     int ret;
379 
380     ret = regmap_read_poll_timeout(grf, pll->lock_offset, val, val & BIT(pll->lock_shift), 0, 0x3e8);
381     if (ret) {
382         pr_err("%s: timeout waiting for pll to lock\n", __func__);
383     }
384 
385     return ret;
386 }
387 
388 /**
389  * PLL used in RK3036
390  */
391 
392 #define RK3036_PLLCON(i) ((i)*0x4)
393 #define RK3036_PLLCON0_FBDIV_MASK 0xfff
394 #define RK3036_PLLCON0_FBDIV_SHIFT 0
395 #define RK3036_PLLCON0_POSTDIV1_MASK 0x7
396 #define RK3036_PLLCON0_POSTDIV1_SHIFT 12
397 #define RK3036_PLLCON1_REFDIV_MASK 0x3f
398 #define RK3036_PLLCON1_REFDIV_SHIFT 0
399 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7
400 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6
401 #define RK3036_PLLCON1_LOCK_STATUS BIT(10)
402 #define RK3036_PLLCON1_DSMPD_MASK 0x1
403 #define RK3036_PLLCON1_DSMPD_SHIFT 12
404 #define RK3036_PLLCON1_PWRDOWN BIT(13)
405 #define RK3036_PLLCON2_FRAC_MASK 0xffffff
406 #define RK3036_PLLCON2_FRAC_SHIFT 0
407 
rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll * pll)408 static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
409 {
410     u32 pllcon;
411     int ret;
412 
413     /*
414      * Lock time typical 250, max 500 input clock cycles @24MHz
415      * So define a very safe maximum of 1000us, meaning 24000 cycles.
416      */
417     ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1), pllcon, pllcon & RK3036_PLLCON1_LOCK_STATUS, 0,
418                                      0x3e8);
419     if (ret) {
420         pr_err("%s: timeout waiting for pll to lock\n", __func__);
421     }
422 
423     return ret;
424 }
425 
rockchip_rk3036_pll_con_to_rate(struct rockchip_clk_pll * pll,u32 con0,u32 con1)426 static unsigned long rockchip_rk3036_pll_con_to_rate(struct rockchip_clk_pll *pll, u32 con0, u32 con1)
427 {
428     unsigned int fbdiv, postdiv1, refdiv, postdiv2;
429     u64 rate64 = 24000000;
430 
431     fbdiv = ((con0 >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK);
432     postdiv1 = ((con0 >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK);
433     refdiv = ((con1 >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK);
434     postdiv2 = ((con1 >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK);
435 
436     rate64 *= fbdiv;
437     do_div(rate64, refdiv);
438     do_div(rate64, postdiv1);
439     do_div(rate64, postdiv2);
440 
441     return (unsigned long)rate64;
442 }
443 
rockchip_rk3036_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)444 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll, struct rockchip_pll_rate_table *rate)
445 {
446     u32 pllcon;
447 
448     pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
449     rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK);
450     rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK);
451 
452     pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
453     rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK);
454     rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK);
455     rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK);
456 
457     pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
458     rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
459 }
460 
rockchip_rk3036_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)461 static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
462 {
463     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
464     struct rockchip_pll_rate_table cur;
465     u64 rate64 = prate, frac_rate64 = prate;
466 
467     if (pll->sel && pll->scaling) {
468         return pll->scaling;
469     }
470 
471     rockchip_rk3036_pll_get_params(pll, &cur);
472 
473     rate64 *= cur.fbdiv;
474     do_div(rate64, cur.refdiv);
475 
476     if (cur.dsmpd == 0) {
477         /* fractional mode */
478         frac_rate64 *= cur.frac;
479 
480         do_div(frac_rate64, cur.refdiv);
481         rate64 += frac_rate64 >> 0x18;
482     }
483 
484     do_div(rate64, cur.postdiv1);
485     do_div(rate64, cur.postdiv2);
486 
487     return (unsigned long)rate64;
488 }
489 
rockchip_rk3036_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)490 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll, const struct rockchip_pll_rate_table *rate)
491 {
492     const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
493     struct clk_mux *pll_mux = &pll->pll_mux;
494     struct rockchip_pll_rate_table cur;
495     u32 pllcon;
496     int rate_change_remuxed = 0;
497     int cur_parent;
498     int ret;
499 
500     pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
501              __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
502 
503     rockchip_rk3036_pll_get_params(pll, &cur);
504     cur.rate = 0;
505 
506     cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
507     if (cur_parent == PLL_MODE_NORM) {
508         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
509         rate_change_remuxed = 1;
510     }
511 
512     /* update pll values */
513     writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK, RK3036_PLLCON0_FBDIV_SHIFT) |
514                        HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK, RK3036_PLLCON0_POSTDIV1_SHIFT),
515                    pll->reg_base + RK3036_PLLCON(0));
516 
517     writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK, RK3036_PLLCON1_REFDIV_SHIFT) |
518                        HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK, RK3036_PLLCON1_POSTDIV2_SHIFT) |
519                        HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK, RK3036_PLLCON1_DSMPD_SHIFT),
520                    pll->reg_base + RK3036_PLLCON(1));
521 
522     /* GPLL CON2 is not HIWORD_MASK */
523     pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0x2));
524     pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
525     pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
526     writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(0x2));
527 
528     rockchip_boost_disable_low(pll);
529 
530     /* wait for the pll to lock */
531     ret = rockchip_rk3036_pll_wait_lock(pll);
532     if (ret) {
533         pr_warn("%s: pll update unsuccessful, trying to restore old params\n", __func__);
534         rockchip_rk3036_pll_set_params(pll, &cur);
535     }
536 
537     if (rate_change_remuxed) {
538         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
539     }
540 
541     return ret;
542 }
543 
rockchip_rk3036_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)544 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
545 {
546     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
547     const struct rockchip_pll_rate_table *rate;
548 
549     pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", __func__, __clk_get_name(hw->clk), drate, prate);
550 
551     /* Get required rate settings from table */
552     rate = rockchip_get_pll_settings(pll, drate);
553     if (!rate) {
554         pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, drate, __clk_get_name(hw->clk));
555         return -EINVAL;
556     }
557 
558     return rockchip_rk3036_pll_set_params(pll, rate);
559 }
560 
rockchip_rk3036_pll_enable(struct clk_hw * hw)561 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
562 {
563     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
564 
565     writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0), pll->reg_base + RK3036_PLLCON(1));
566     rockchip_rk3036_pll_wait_lock(pll);
567 
568     return 0;
569 }
570 
rockchip_rk3036_pll_disable(struct clk_hw * hw)571 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
572 {
573     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
574 
575     writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN, RK3036_PLLCON1_PWRDOWN, 0), pll->reg_base + RK3036_PLLCON(1));
576 }
577 
rockchip_rk3036_pll_is_enabled(struct clk_hw * hw)578 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
579 {
580     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
581     u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
582 
583     return !(pllcon & RK3036_PLLCON1_PWRDOWN);
584 }
585 
rockchip_rk3036_pll_init(struct clk_hw * hw)586 static int rockchip_rk3036_pll_init(struct clk_hw *hw)
587 {
588     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
589     const struct rockchip_pll_rate_table *rate;
590     struct rockchip_pll_rate_table cur;
591     unsigned long drate;
592 
593     if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) {
594         return 0;
595     }
596 
597     drate = clk_hw_get_rate(hw);
598     rate = rockchip_get_pll_settings(pll, drate);
599     /* when no rate setting for the current rate, rely on clk_set_rate */
600     if (!rate) {
601         return 0;
602     }
603 
604     rockchip_rk3036_pll_get_params(pll, &cur);
605 
606     pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), drate);
607     pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", cur.fbdiv, cur.postdiv1,
608              cur.refdiv, cur.postdiv2, cur.dsmpd, cur.frac);
609     pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", rate->fbdiv,
610              rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
611 
612     if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || rate->refdiv != cur.refdiv ||
613         rate->postdiv2 != cur.postdiv2 || rate->dsmpd != cur.dsmpd || (!cur.dsmpd && (rate->frac != cur.frac))) {
614         struct clk *parent = clk_get_parent(hw->clk);
615 
616         if (!parent) {
617             pr_warn("%s: parent of %s not available\n", __func__, __clk_get_name(hw->clk));
618             return 0;
619         }
620 
621         pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", __func__, __clk_get_name(hw->clk));
622         rockchip_rk3036_pll_set_params(pll, rate);
623     }
624 
625     return 0;
626 }
627 
628 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
629     .recalc_rate = rockchip_rk3036_pll_recalc_rate,
630     .enable = rockchip_rk3036_pll_enable,
631     .disable = rockchip_rk3036_pll_disable,
632     .is_enabled = rockchip_rk3036_pll_is_enabled,
633 };
634 
635 static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
636     .recalc_rate = rockchip_rk3036_pll_recalc_rate,
637     .round_rate = rockchip_pll_round_rate,
638     .set_rate = rockchip_rk3036_pll_set_rate,
639     .enable = rockchip_rk3036_pll_enable,
640     .disable = rockchip_rk3036_pll_disable,
641     .is_enabled = rockchip_rk3036_pll_is_enabled,
642     .init = rockchip_rk3036_pll_init,
643 };
644 
645 /**
646  * PLL used in RK3066, RK3188 and RK3288
647  */
648 
649 #define RK3066_PLL_RESET_DELAY(nr) (((nr)*500) / 24 + 1)
650 
651 #define RK3066_PLLCON(i) ((i)*0x4)
652 #define RK3066_PLLCON0_OD_MASK 0xf
653 #define RK3066_PLLCON0_OD_SHIFT 0
654 #define RK3066_PLLCON0_NR_MASK 0x3f
655 #define RK3066_PLLCON0_NR_SHIFT 8
656 #define RK3066_PLLCON1_NF_MASK 0x1fff
657 #define RK3066_PLLCON1_NF_SHIFT 0
658 #define RK3066_PLLCON2_NB_MASK 0xfff
659 #define RK3066_PLLCON2_NB_SHIFT 0
660 #define RK3066_PLLCON3_RESET (1 << 5)
661 #define RK3066_PLLCON3_PWRDOWN (1 << 1)
662 #define RK3066_PLLCON3_BYPASS (1 << 0)
663 
rockchip_rk3066_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)664 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll, struct rockchip_pll_rate_table *rate)
665 {
666     u32 pllcon;
667 
668     pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
669     rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
670     rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
671 
672     pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
673     rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
674 
675     pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
676     rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
677 }
678 
rockchip_rk3066_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)679 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
680 {
681     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
682     struct rockchip_pll_rate_table cur;
683     u64 rate64 = prate;
684     u32 pllcon;
685 
686     pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
687     if (pllcon & RK3066_PLLCON3_BYPASS) {
688         pr_debug("%s: pll %s is bypassed\n", __func__, clk_hw_get_name(hw));
689         return prate;
690     }
691 
692     if (pll->sel && pll->scaling) {
693         return pll->scaling;
694     }
695 
696     rockchip_rk3066_pll_get_params(pll, &cur);
697 
698     rate64 *= cur.nf;
699     do_div(rate64, cur.nr);
700     do_div(rate64, cur.no);
701 
702     return (unsigned long)rate64;
703 }
704 
rockchip_rk3066_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)705 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll, const struct rockchip_pll_rate_table *rate)
706 {
707     const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
708     struct clk_mux *pll_mux = &pll->pll_mux;
709     struct rockchip_pll_rate_table cur;
710     int rate_change_remuxed = 0;
711     int cur_parent;
712     int ret;
713 
714     pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", __func__, rate->rate, rate->nr, rate->no,
715              rate->nf);
716 
717     rockchip_rk3066_pll_get_params(pll, &cur);
718     cur.rate = 0;
719 
720     cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
721     if (cur_parent == PLL_MODE_NORM) {
722         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
723         rate_change_remuxed = 1;
724     }
725 
726     /* enter reset mode */
727     writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0), pll->reg_base + RK3066_PLLCON(3));
728 
729     /* update pll values */
730     writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK, RK3066_PLLCON0_NR_SHIFT) |
731                HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK, RK3066_PLLCON0_OD_SHIFT),
732            pll->reg_base + RK3066_PLLCON(0));
733 
734     writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK, RK3066_PLLCON1_NF_SHIFT),
735                    pll->reg_base + RK3066_PLLCON(1));
736     writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK, RK3066_PLLCON2_NB_SHIFT),
737                    pll->reg_base + RK3066_PLLCON(2));
738 
739     /* leave reset and wait the reset_delay */
740     writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0), pll->reg_base + RK3066_PLLCON(3));
741     udelay(RK3066_PLL_RESET_DELAY(rate->nr));
742 
743     /* wait for the pll to lock */
744     ret = rockchip_pll_wait_lock(pll);
745     if (ret) {
746         pr_warn("%s: pll update unsuccessful, trying to restore old params\n", __func__);
747         rockchip_rk3066_pll_set_params(pll, &cur);
748     }
749 
750     if (rate_change_remuxed) {
751         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
752     }
753 
754     return ret;
755 }
756 
rockchip_rk3066_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)757 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
758 {
759     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
760     const struct rockchip_pll_rate_table *rate;
761     unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
762     struct regmap *grf = pll->ctx->grf;
763     int ret;
764 
765     if (IS_ERR(grf)) {
766         pr_debug("%s: grf regmap not available, aborting rate change\n", __func__);
767         return PTR_ERR(grf);
768     }
769 
770     pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", __func__, clk_hw_get_name(hw), old_rate,
771              drate, prate);
772 
773     /* Get required rate settings from table */
774     rate = rockchip_get_pll_settings(pll, drate);
775     if (!rate) {
776         pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, drate, clk_hw_get_name(hw));
777         return -EINVAL;
778     }
779 
780     ret = rockchip_rk3066_pll_set_params(pll, rate);
781     if (ret) {
782         pll->scaling = 0;
783     }
784 
785     return ret;
786 }
787 
rockchip_rk3066_pll_enable(struct clk_hw * hw)788 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
789 {
790     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
791 
792     writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3066_PLLCON(3));
793     rockchip_pll_wait_lock(pll);
794 
795     return 0;
796 }
797 
rockchip_rk3066_pll_disable(struct clk_hw * hw)798 static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
799 {
800     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
801 
802     writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN, RK3066_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3066_PLLCON(3));
803 }
804 
rockchip_rk3066_pll_is_enabled(struct clk_hw * hw)805 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
806 {
807     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
808     u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
809 
810     return !(pllcon & RK3066_PLLCON3_PWRDOWN);
811 }
812 
rockchip_rk3066_pll_init(struct clk_hw * hw)813 static int rockchip_rk3066_pll_init(struct clk_hw *hw)
814 {
815     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
816     const struct rockchip_pll_rate_table *rate;
817     struct rockchip_pll_rate_table cur;
818     unsigned long drate;
819 
820     if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) {
821         return 0;
822     }
823 
824     drate = clk_hw_get_rate(hw);
825     rate = rockchip_get_pll_settings(pll, drate);
826     /* when no rate setting for the current rate, rely on clk_set_rate */
827     if (!rate) {
828         return 0;
829     }
830 
831     rockchip_rk3066_pll_get_params(pll, &cur);
832 
833     pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n", __func__, clk_hw_get_name(hw), drate,
834              rate->nr, cur.nr, rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
835     if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf || rate->nb != cur.nb) {
836         pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", __func__, clk_hw_get_name(hw));
837         rockchip_rk3066_pll_set_params(pll, rate);
838     }
839 
840     return 0;
841 }
842 
843 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
844     .recalc_rate = rockchip_rk3066_pll_recalc_rate,
845     .enable = rockchip_rk3066_pll_enable,
846     .disable = rockchip_rk3066_pll_disable,
847     .is_enabled = rockchip_rk3066_pll_is_enabled,
848 };
849 
850 static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
851     .recalc_rate = rockchip_rk3066_pll_recalc_rate,
852     .round_rate = rockchip_pll_round_rate,
853     .set_rate = rockchip_rk3066_pll_set_rate,
854     .enable = rockchip_rk3066_pll_enable,
855     .disable = rockchip_rk3066_pll_disable,
856     .is_enabled = rockchip_rk3066_pll_is_enabled,
857     .init = rockchip_rk3066_pll_init,
858 };
859 
860 /**
861  * PLL used in RK3399
862  */
863 
864 #define RK3399_PLLCON(i) ((i)*0x4)
865 #define RK3399_PLLCON0_FBDIV_MASK 0xfff
866 #define RK3399_PLLCON0_FBDIV_SHIFT 0
867 #define RK3399_PLLCON1_REFDIV_MASK 0x3f
868 #define RK3399_PLLCON1_REFDIV_SHIFT 0
869 #define RK3399_PLLCON1_POSTDIV1_MASK 0x7
870 #define RK3399_PLLCON1_POSTDIV1_SHIFT 8
871 #define RK3399_PLLCON1_POSTDIV2_MASK 0x7
872 #define RK3399_PLLCON1_POSTDIV2_SHIFT 12
873 #define RK3399_PLLCON2_FRAC_MASK 0xffffff
874 #define RK3399_PLLCON2_FRAC_SHIFT 0
875 #define RK3399_PLLCON2_LOCK_STATUS BIT(31)
876 #define RK3399_PLLCON3_PWRDOWN BIT(0)
877 #define RK3399_PLLCON3_DSMPD_MASK 0x1
878 #define RK3399_PLLCON3_DSMPD_SHIFT 3
879 
rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll * pll)880 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
881 {
882     u32 pllcon;
883     int ret;
884 
885     /*
886      * Lock time typical 250, max 500 input clock cycles @24MHz
887      * So define a very safe maximum of 1000us, meaning 24000 cycles.
888      */
889     ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2), pllcon, pllcon & RK3399_PLLCON2_LOCK_STATUS, 0,
890                                      0x3e8);
891     if (ret) {
892         pr_err("%s: timeout waiting for pll to lock\n", __func__);
893     }
894 
895     return ret;
896 }
897 
rockchip_rk3399_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)898 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll, struct rockchip_pll_rate_table *rate)
899 {
900     u32 pllcon;
901 
902     pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
903     rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) & RK3399_PLLCON0_FBDIV_MASK);
904 
905     pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
906     rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) & RK3399_PLLCON1_REFDIV_MASK);
907     rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) & RK3399_PLLCON1_POSTDIV1_MASK);
908     rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) & RK3399_PLLCON1_POSTDIV2_MASK);
909 
910     pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
911     rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) & RK3399_PLLCON2_FRAC_MASK);
912 
913     pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
914     rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) & RK3399_PLLCON3_DSMPD_MASK);
915 }
916 
rockchip_rk3399_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)917 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
918 {
919     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
920     struct rockchip_pll_rate_table cur;
921     u64 rate64 = prate;
922 
923     if (pll->sel && pll->scaling) {
924         return pll->scaling;
925     }
926 
927     rockchip_rk3399_pll_get_params(pll, &cur);
928 
929     rate64 *= cur.fbdiv;
930     do_div(rate64, cur.refdiv);
931 
932     if (cur.dsmpd == 0) {
933         /* fractional mode */
934         u64 frac_rate64 = prate * cur.frac;
935 
936         do_div(frac_rate64, cur.refdiv);
937         rate64 += frac_rate64 >> 0x18;
938     }
939 
940     do_div(rate64, cur.postdiv1);
941     do_div(rate64, cur.postdiv2);
942 
943     return (unsigned long)rate64;
944 }
945 
rockchip_rk3399_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)946 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll, const struct rockchip_pll_rate_table *rate)
947 {
948     const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
949     struct clk_mux *pll_mux = &pll->pll_mux;
950     struct rockchip_pll_rate_table cur;
951     u32 pllcon;
952     int rate_change_remuxed = 0;
953     int cur_parent;
954     int ret;
955 
956     pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
957              __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
958 
959     rockchip_rk3399_pll_get_params(pll, &cur);
960     cur.rate = 0;
961 
962     cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
963     if (cur_parent == PLL_MODE_NORM) {
964         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
965         rate_change_remuxed = 1;
966     }
967 
968     /* set pll power down */
969     writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3399_PLLCON(0x3));
970 
971     /* update pll values */
972     writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, RK3399_PLLCON0_FBDIV_SHIFT),
973                    pll->reg_base + RK3399_PLLCON(0));
974 
975     writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, RK3399_PLLCON1_REFDIV_SHIFT) |
976                        HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, RK3399_PLLCON1_POSTDIV1_SHIFT) |
977                        HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, RK3399_PLLCON1_POSTDIV2_SHIFT),
978                    pll->reg_base + RK3399_PLLCON(1));
979 
980     /* xPLL CON2 is not HIWORD_MASK */
981     pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0x2));
982     pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
983     pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
984     writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(0x2));
985 
986     writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, RK3399_PLLCON3_DSMPD_SHIFT),
987                    pll->reg_base + RK3399_PLLCON(0x3));
988 
989     /* set pll power up */
990     writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3399_PLLCON(0x3));
991 
992     /* wait for the pll to lock */
993     ret = rockchip_rk3399_pll_wait_lock(pll);
994     if (ret) {
995         pr_warn("%s: pll update unsuccessful, trying to restore old params\n", __func__);
996         rockchip_rk3399_pll_set_params(pll, &cur);
997     }
998 
999     if (rate_change_remuxed) {
1000         pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
1001     }
1002 
1003     return ret;
1004 }
1005 
rockchip_rk3399_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)1006 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
1007 {
1008     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1009     const struct rockchip_pll_rate_table *rate;
1010     unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate);
1011     int ret;
1012 
1013     pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", __func__, __clk_get_name(hw->clk), old_rate,
1014              drate, prate);
1015 
1016     /* Get required rate settings from table */
1017     rate = rockchip_get_pll_settings(pll, drate);
1018     if (!rate) {
1019         pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, drate, __clk_get_name(hw->clk));
1020         return -EINVAL;
1021     }
1022 
1023     ret = rockchip_rk3399_pll_set_params(pll, rate);
1024     if (ret) {
1025         pll->scaling = 0;
1026     }
1027 
1028     return ret;
1029 }
1030 
rockchip_rk3399_pll_enable(struct clk_hw * hw)1031 static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
1032 {
1033     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1034 
1035     writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3399_PLLCON(0x3));
1036     rockchip_rk3399_pll_wait_lock(pll);
1037 
1038     return 0;
1039 }
1040 
rockchip_rk3399_pll_disable(struct clk_hw * hw)1041 static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
1042 {
1043     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1044 
1045     writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3399_PLLCON(0x3));
1046 }
1047 
rockchip_rk3399_pll_is_enabled(struct clk_hw * hw)1048 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
1049 {
1050     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1051     u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(0x3));
1052 
1053     return !(pllcon & RK3399_PLLCON3_PWRDOWN);
1054 }
1055 
rockchip_rk3399_pll_init(struct clk_hw * hw)1056 static int rockchip_rk3399_pll_init(struct clk_hw *hw)
1057 {
1058     struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1059     const struct rockchip_pll_rate_table *rate;
1060     struct rockchip_pll_rate_table cur;
1061     unsigned long drate;
1062 
1063     if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) {
1064         return 0;
1065     }
1066 
1067     drate = clk_hw_get_rate(hw);
1068     rate = rockchip_get_pll_settings(pll, drate);
1069     /* when no rate setting for the current rate, rely on clk_set_rate */
1070     if (!rate) {
1071         return 0;
1072     }
1073 
1074     rockchip_rk3399_pll_get_params(pll, &cur);
1075 
1076     pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), drate);
1077     pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", cur.fbdiv, cur.postdiv1,
1078              cur.refdiv, cur.postdiv2, cur.dsmpd, cur.frac);
1079     pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", rate->fbdiv,
1080              rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
1081 
1082     if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || rate->refdiv != cur.refdiv ||
1083         rate->postdiv2 != cur.postdiv2 || rate->dsmpd != cur.dsmpd || (!cur.dsmpd && (rate->frac != cur.frac))) {
1084         struct clk *parent = clk_get_parent(hw->clk);
1085 
1086         if (!parent) {
1087             pr_warn("%s: parent of %s not available\n", __func__, __clk_get_name(hw->clk));
1088             return 0;
1089         }
1090 
1091         pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", __func__, __clk_get_name(hw->clk));
1092         rockchip_rk3399_pll_set_params(pll, rate);
1093     }
1094 
1095     return 0;
1096 }
1097 
1098 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
1099     .recalc_rate = rockchip_rk3399_pll_recalc_rate,
1100     .enable = rockchip_rk3399_pll_enable,
1101     .disable = rockchip_rk3399_pll_disable,
1102     .is_enabled = rockchip_rk3399_pll_is_enabled,
1103 };
1104 
1105 static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
1106     .recalc_rate = rockchip_rk3399_pll_recalc_rate,
1107     .round_rate = rockchip_pll_round_rate,
1108     .set_rate = rockchip_rk3399_pll_set_rate,
1109     .enable = rockchip_rk3399_pll_enable,
1110     .disable = rockchip_rk3399_pll_disable,
1111     .is_enabled = rockchip_rk3399_pll_is_enabled,
1112     .init = rockchip_rk3399_pll_init,
1113 };
1114 
1115 #ifdef CONFIG_ROCKCHIP_CLK_COMPENSATION
rockchip_pll_clk_compensation(struct clk * clk,int ppm)1116 int rockchip_pll_clk_compensation(struct clk *clk, int ppm)
1117 {
1118     struct clk *parent = clk_get_parent(clk);
1119     struct rockchip_clk_pll *pll;
1120     static u32 frac, fbdiv;
1121     bool negative;
1122     u32 pllcon, pllcon0, pllcon2, fbdiv_mask, frac_mask, frac_shift;
1123     u64 fracdiv, m, n;
1124 
1125     if ((ppm > 0x3e8) || (ppm < -0x3e8)) {
1126         return -EINVAL;
1127     }
1128 
1129     if (IS_ERR_OR_NULL(parent)) {
1130         return -EINVAL;
1131     }
1132 
1133     pll = to_rockchip_clk_pll(__clk_get_hw(parent));
1134     if (!pll) {
1135         return -EINVAL;
1136     }
1137 
1138     switch (pll->type) {
1139         case pll_rk3036:
1140         case pll_rk3328:
1141             pllcon0 = RK3036_PLLCON(0);
1142             pllcon2 = RK3036_PLLCON(0x2);
1143             fbdiv_mask = RK3036_PLLCON0_FBDIV_MASK;
1144             frac_mask = RK3036_PLLCON2_FRAC_MASK;
1145             frac_shift = RK3036_PLLCON2_FRAC_SHIFT;
1146             break;
1147         case pll_rk3066:
1148             return -EINVAL;
1149         case pll_rk3399:
1150             pllcon0 = RK3399_PLLCON(0);
1151             pllcon2 = RK3399_PLLCON(2);
1152             fbdiv_mask = RK3399_PLLCON0_FBDIV_MASK;
1153             frac_mask = RK3399_PLLCON2_FRAC_MASK;
1154             frac_shift = RK3399_PLLCON2_FRAC_SHIFT;
1155             break;
1156         default:
1157             return -EINVAL;
1158     }
1159 
1160     negative = !!(ppm & BIT(0x1f));
1161     ppm = negative ? ~ppm + 1 : ppm;
1162 
1163     if (!frac) {
1164         frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1165         fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1166     }
1167 
1168     /*
1169      *   delta frac                 frac          ppm
1170      * -------------- = (fbdiv + ----------) * ---------
1171      *    1 << 24                 1 << 24       1000000
1172      *
1173      */
1174     m = div64_u64((uint64_t)frac * ppm, 0xf4240);
1175     n = div64_u64((uint64_t)ppm << 0x18, 0xf4240) * fbdiv;
1176 
1177     fracdiv = negative ? frac - (m + n) : frac + (m + n);
1178 
1179     if (!frac || fracdiv > frac_mask) {
1180         return -EINVAL;
1181     }
1182 
1183     pllcon = readl_relaxed(pll->reg_base + pllcon2);
1184     pllcon &= ~(frac_mask << frac_shift);
1185     pllcon |= fracdiv << frac_shift;
1186     writel_relaxed(pllcon, pll->reg_base + pllcon2);
1187 
1188     return 0;
1189 }
1190 EXPORT_SYMBOL(rockchip_pll_clk_compensation);
1191 #endif
1192 
1193 /*
1194  * Common registering of pll clocks
1195  */
1196 
rockchip_clk_register_pll(struct rockchip_clk_provider * ctx,enum rockchip_pll_type pll_type,const char * name,const char * const * parent_names,u8 num_parents,int con_offset,int grf_lock_offset,int lock_shift,int mode_offset,int mode_shift,struct rockchip_pll_rate_table * rate_table,unsigned long flags,u8 clk_pll_flags)1197 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, enum rockchip_pll_type pll_type,
1198                                       const char *name, const char *const *parent_names, u8 num_parents, int con_offset,
1199                                       int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift,
1200                                       struct rockchip_pll_rate_table *rate_table, unsigned long flags, u8 clk_pll_flags)
1201 {
1202     const char *pll_parents[3];
1203     struct clk_init_data init;
1204     struct rockchip_clk_pll *pll;
1205     struct clk_mux *pll_mux;
1206     struct clk *pll_clk, *mux_clk;
1207     char pll_name[20];
1208     int ret = 0;
1209 
1210     if ((pll_type != pll_rk3328 && num_parents != 0x2) || (pll_type == pll_rk3328 && num_parents != 0x1)) {
1211         pr_err("%s: needs two parent clocks\n", __func__);
1212         return ERR_PTR(-EINVAL);
1213     }
1214 
1215     /* name the actual pll */
1216     ret = snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
1217 
1218     pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1219     if (!pll) {
1220         return ERR_PTR(-ENOMEM);
1221     }
1222 
1223     /* create the mux on top of the real pll */
1224     pll->pll_mux_ops = &clk_mux_ops;
1225     pll_mux = &pll->pll_mux;
1226     pll_mux->reg = ctx->reg_base + mode_offset;
1227     pll_mux->shift = mode_shift;
1228     if (pll_type == pll_rk3328) {
1229         pll_mux->mask = PLL_RK3328_MODE_MASK;
1230     } else {
1231         pll_mux->mask = PLL_MODE_MASK;
1232     }
1233     pll_mux->flags = 0;
1234     pll_mux->lock = &ctx->lock;
1235     pll_mux->hw.init = &init;
1236 
1237     if (pll_type == pll_rk3036 || pll_type == pll_rk3066 || pll_type == pll_rk3328 || pll_type == pll_rk3399) {
1238         pll_mux->flags |= CLK_MUX_HIWORD_MASK;
1239     }
1240 
1241     /* the actual muxing is xin24m, pll-output, xin32k */
1242     pll_parents[0x0] = parent_names[0x0];
1243     pll_parents[0x1] = pll_name;
1244     pll_parents[0x2] = parent_names[0x1];
1245 
1246     init.name = name;
1247     init.flags = CLK_SET_RATE_PARENT;
1248     init.ops = pll->pll_mux_ops;
1249     init.parent_names = pll_parents;
1250     if (pll_type == pll_rk3328) {
1251         init.num_parents = 0x2;
1252     } else {
1253         init.num_parents = ARRAY_SIZE(pll_parents);
1254     }
1255 
1256     mux_clk = clk_register(NULL, &pll_mux->hw);
1257     if (IS_ERR(mux_clk)) {
1258         goto err_mux;
1259     }
1260 
1261     /* now create the actual pll */
1262     init.name = pll_name;
1263 
1264 #ifndef CONFIG_ROCKCHIP_LOW_PERFORMANCE
1265     /* keep all plls untouched for now */
1266     init.flags = flags | CLK_IGNORE_UNUSED;
1267 #else
1268     init.flags = flags;
1269 #endif
1270 
1271     init.parent_names = &parent_names[0];
1272     init.num_parents = 1;
1273 
1274     if (rate_table) {
1275         int len;
1276 
1277         /* find count of rates in rate_table */
1278         for (len = 0; rate_table[len].rate != 0;) {
1279             len++;
1280         }
1281 
1282         pll->rate_count = len;
1283         pll->rate_table = kmemdup(rate_table, pll->rate_count * sizeof(struct rockchip_pll_rate_table), GFP_KERNEL);
1284         WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name);
1285     }
1286 
1287     switch (pll_type) {
1288         case pll_rk3036:
1289         case pll_rk3328:
1290             if (!pll->rate_table || IS_ERR(ctx->grf)) {
1291                 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
1292             } else {
1293                 init.ops = &rockchip_rk3036_pll_clk_ops;
1294             }
1295             break;
1296         case pll_rk3066:
1297             if (!pll->rate_table || IS_ERR(ctx->grf)) {
1298                 init.ops = &rockchip_rk3066_pll_clk_norate_ops;
1299             } else {
1300                 init.ops = &rockchip_rk3066_pll_clk_ops;
1301             }
1302             break;
1303         case pll_rk3399:
1304             if (!pll->rate_table) {
1305                 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
1306             } else {
1307                 init.ops = &rockchip_rk3399_pll_clk_ops;
1308             }
1309             break;
1310         default:
1311             pr_warn("%s: Unknown pll type for pll clk %s\n", __func__, name);
1312     }
1313 
1314     pll->hw.init = &init;
1315     pll->type = pll_type;
1316     pll->reg_base = ctx->reg_base + con_offset;
1317     pll->lock_offset = grf_lock_offset;
1318     pll->lock_shift = lock_shift;
1319     pll->flags = clk_pll_flags;
1320     pll->lock = &ctx->lock;
1321     pll->ctx = ctx;
1322 
1323     pll_clk = clk_register(NULL, &pll->hw);
1324     if (IS_ERR(pll_clk)) {
1325         pr_err("%s: failed to register pll clock %s : %ld\n", __func__, name, PTR_ERR(pll_clk));
1326         goto err_pll;
1327     }
1328 
1329     return mux_clk;
1330 
1331 err_pll:
1332     clk_unregister(mux_clk);
1333     mux_clk = pll_clk;
1334 err_mux:
1335     kfree(pll);
1336     return mux_clk;
1337 }
1338 
rockchip_pll_con_to_rate(struct rockchip_clk_pll * pll,u32 con0,u32 con1)1339 static unsigned long rockchip_pll_con_to_rate(struct rockchip_clk_pll *pll, u32 con0, u32 con1)
1340 {
1341     switch (pll->type) {
1342         case pll_rk3036:
1343         case pll_rk3328:
1344             return rockchip_rk3036_pll_con_to_rate(pll, con0, con1);
1345         case pll_rk3066:
1346             break;
1347         case pll_rk3399:
1348             break;
1349         default:
1350             pr_warn("%s: Unknown pll type\n", __func__);
1351     }
1352 
1353     return 0;
1354 }
1355 
rockchip_boost_init(struct clk_hw * hw)1356 void rockchip_boost_init(struct clk_hw *hw)
1357 {
1358     struct rockchip_clk_pll *pll;
1359     struct device_node *np;
1360     u32 value, con0, con1;
1361 
1362     if (!hw) {
1363         return;
1364     }
1365     pll = to_rockchip_clk_pll(hw);
1366     np = of_parse_phandle(pll->ctx->cru_node, "rockchip,boost", 0);
1367     if (!np) {
1368         pr_debug("%s: failed to get boost np\n", __func__);
1369         return;
1370     }
1371     pll->boost = syscon_node_to_regmap(np);
1372     if (IS_ERR(pll->boost)) {
1373         pr_debug("%s: failed to get boost regmap\n", __func__);
1374         return;
1375     }
1376 
1377     if (!of_property_read_u32(np, "rockchip,boost-low-con0", &con0) &&
1378         !of_property_read_u32(np, "rockchip,boost-low-con1", &con1)) {
1379         pr_debug("boost-low-con=0x%x 0x%x\n", con0, con1);
1380         regmap_write(pll->boost, BOOST_PLL_L_CON(0), HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0));
1381         regmap_write(pll->boost, BOOST_PLL_L_CON(1), HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0));
1382         pll->boost_low_rate = rockchip_pll_con_to_rate(pll, con0, con1);
1383         pr_debug("boost-low-rate=%lu\n", pll->boost_low_rate);
1384     }
1385     if (!of_property_read_u32(np, "rockchip,boost-high-con0", &con0) &&
1386         !of_property_read_u32(np, "rockchip,boost-high-con1", &con1)) {
1387         pr_debug("boost-high-con=0x%x 0x%x\n", con0, con1);
1388         regmap_write(pll->boost, BOOST_PLL_H_CON(0), HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0));
1389         regmap_write(pll->boost, BOOST_PLL_H_CON(1), HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0));
1390         pll->boost_high_rate = rockchip_pll_con_to_rate(pll, con0, con1);
1391         pr_debug("boost-high-rate=%lu\n", pll->boost_high_rate);
1392     }
1393     if (!of_property_read_u32(np, "rockchip,boost-backup-pll", &value)) {
1394         pr_debug("boost-backup-pll=0x%x\n", value);
1395         regmap_write(pll->boost, BOOST_CLK_CON, HIWORD_UPDATE(value, BOOST_BACKUP_PLL_MASK, BOOST_BACKUP_PLL_SHIFT));
1396     }
1397     if (!of_property_read_u32(np, "rockchip,boost-backup-pll-usage", &pll->boost_backup_pll_usage)) {
1398         pr_debug("boost-backup-pll-usage=0x%x\n", pll->boost_backup_pll_usage);
1399         regmap_write(
1400             pll->boost, BOOST_CLK_CON,
1401             HIWORD_UPDATE(pll->boost_backup_pll_usage, BOOST_BACKUP_PLL_USAGE_MASK, BOOST_BACKUP_PLL_USAGE_SHIFT));
1402     }
1403     if (!of_property_read_u32(np, "rockchip,boost-switch-threshold", &value)) {
1404         pr_debug("boost-switch-threshold=0x%x\n", value);
1405         regmap_write(pll->boost, BOOST_SWITCH_THRESHOLD, value);
1406     }
1407     if (!of_property_read_u32(np, "rockchip,boost-statis-threshold", &value)) {
1408         pr_debug("boost-statis-threshold=0x%x\n", value);
1409         regmap_write(pll->boost, BOOST_STATIS_THRESHOLD, value);
1410     }
1411     if (!of_property_read_u32(np, "rockchip,boost-statis-enable", &value)) {
1412         pr_debug("boost-statis-enable=0x%x\n", value);
1413         regmap_write(pll->boost, BOOST_BOOST_CON,
1414                      HIWORD_UPDATE(value, BOOST_STATIS_ENABLE_MASK, BOOST_STATIS_ENABLE_SHIFT));
1415     }
1416     if (!of_property_read_u32(np, "rockchip,boost-enable", &value)) {
1417         pr_debug("boost-enable=0x%x\n", value);
1418         regmap_write(pll->boost, BOOST_BOOST_CON, HIWORD_UPDATE(value, BOOST_ENABLE_MASK, BOOST_ENABLE_SHIFT));
1419         if (value) {
1420             pll->boost_enabled = true;
1421         }
1422     }
1423 #ifdef CONFIG_DEBUG_FS
1424     if (pll->boost_enabled) {
1425         mutex_lock(&clk_boost_lock);
1426         hlist_add_head(&pll->debug_node, &clk_boost_list);
1427         mutex_unlock(&clk_boost_lock);
1428     }
1429 #endif
1430 }
1431 
rockchip_boost_enable_recovery_sw_low(struct clk_hw * hw)1432 void rockchip_boost_enable_recovery_sw_low(struct clk_hw *hw)
1433 {
1434     struct rockchip_clk_pll *pll;
1435     unsigned int val;
1436 
1437     if (!hw) {
1438         return;
1439     }
1440     pll = to_rockchip_clk_pll(hw);
1441     if (!pll->boost_enabled) {
1442         return;
1443     }
1444 
1445     regmap_write(pll->boost, BOOST_BOOST_CON, HIWORD_UPDATE(1, BOOST_RECOVERY_MASK, BOOST_RECOVERY_SHIFT));
1446     do {
1447         regmap_read(pll->boost, BOOST_FSM_STATUS, &val);
1448     } while (!(val & BOOST_BUSY_STATE));
1449 
1450     regmap_write(pll->boost, BOOST_BOOST_CON,
1451                  HIWORD_UPDATE(1, BOOST_SW_CTRL_MASK, BOOST_SW_CTRL_SHIFT) |
1452                      HIWORD_UPDATE(1, BOOST_LOW_FREQ_EN_MASK, BOOST_LOW_FREQ_EN_SHIFT));
1453 }
1454 
rockchip_boost_disable_low(struct rockchip_clk_pll * pll)1455 static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll)
1456 {
1457     if (!pll->boost_enabled) {
1458         return;
1459     }
1460 
1461     regmap_write(pll->boost, BOOST_BOOST_CON, HIWORD_UPDATE(0, BOOST_LOW_FREQ_EN_MASK, BOOST_LOW_FREQ_EN_SHIFT));
1462 }
1463 
rockchip_boost_disable_recovery_sw(struct clk_hw * hw)1464 void rockchip_boost_disable_recovery_sw(struct clk_hw *hw)
1465 {
1466     struct rockchip_clk_pll *pll;
1467 
1468     if (!hw) {
1469         return;
1470     }
1471     pll = to_rockchip_clk_pll(hw);
1472     if (!pll->boost_enabled) {
1473         return;
1474     }
1475 
1476     regmap_write(pll->boost, BOOST_BOOST_CON, HIWORD_UPDATE(0, BOOST_RECOVERY_MASK, BOOST_RECOVERY_SHIFT));
1477     regmap_write(pll->boost, BOOST_BOOST_CON, HIWORD_UPDATE(0, BOOST_SW_CTRL_MASK, BOOST_SW_CTRL_SHIFT));
1478 }
1479 
rockchip_boost_add_core_div(struct clk_hw * hw,unsigned long prate)1480 void rockchip_boost_add_core_div(struct clk_hw *hw, unsigned long prate)
1481 {
1482     struct rockchip_clk_pll *pll;
1483     unsigned int div;
1484 
1485     if (!hw) {
1486         return;
1487     }
1488     pll = to_rockchip_clk_pll(hw);
1489     if (!pll->boost_enabled || pll->boost_backup_pll_rate == prate) {
1490         return;
1491     }
1492 
1493     /* todo */
1494     if (pll->boost_backup_pll_usage == BOOST_BACKUP_PLL_USAGE_TARGET) {
1495         return;
1496     }
1497     /*
1498      * cpu clock rate should be less than or equal to
1499      * low rate when change pll rate in boost module
1500      */
1501     if (pll->boost_low_rate && prate > pll->boost_low_rate) {
1502         div = DIV_ROUND_UP(prate, pll->boost_low_rate) - 1;
1503         regmap_write(pll->boost, BOOST_CLK_CON, HIWORD_UPDATE(div, BOOST_CORE_DIV_MASK, BOOST_CORE_DIV_SHIFT));
1504         pll->boost_backup_pll_rate = prate;
1505     }
1506 }
1507 
1508 #ifdef CONFIG_DEBUG_FS
1509 #include <linux/debugfs.h>
1510 
1511 #ifndef MODULE
boost_summary_show(struct seq_file * s,void * data)1512 static int boost_summary_show(struct seq_file *s, void *data)
1513 {
1514     struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1515     u32 boost_count = 0;
1516     u32 freq_cnt0 = 0, freq_cnt1 = 0;
1517     u64 freq_cnt = 0, high_freq_time = 0;
1518     u32 short_count = 0, short_threshold = 0;
1519     u32 interval_time = 0;
1520 
1521     seq_puts(
1522         s, " device    boost_count   high_freq_count  high_freq_time  short_count  short_threshold  interval_count\n");
1523     seq_puts(
1524         s, "------------------------------------------------------------------------------------------------------\n");
1525     seq_printf(s, " %s\n", clk_hw_get_name(&pll->hw));
1526 
1527     regmap_read(pll->boost, BOOST_SWITCH_CNT, &boost_count);
1528 
1529     regmap_read(pll->boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0);
1530     regmap_read(pll->boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1);
1531     freq_cnt = ((u64)freq_cnt1 << 0x20) + (u64)freq_cnt0;
1532     high_freq_time = freq_cnt;
1533     do_div(high_freq_time, 0x18);
1534 
1535     regmap_read(pll->boost, BOOST_SHORT_SWITCH_CNT, &short_count);
1536     regmap_read(pll->boost, BOOST_STATIS_THRESHOLD, &short_threshold);
1537     regmap_read(pll->boost, BOOST_SWITCH_THRESHOLD, &interval_time);
1538 
1539     seq_printf(s, "%22u %17llu %15llu %12u %16u %15u\n", boost_count, freq_cnt, high_freq_time, short_count,
1540                short_threshold, interval_time);
1541 
1542     return 0;
1543 }
1544 
boost_summary_open(struct inode * inode,struct file * file)1545 static int boost_summary_open(struct inode *inode, struct file *file)
1546 {
1547     return single_open(file, boost_summary_show, inode->i_private);
1548 }
1549 
1550 static const struct file_operations boost_summary_fops = {
1551     .open = boost_summary_open,
1552     .read = seq_read,
1553     .llseek = seq_lseek,
1554     .release = single_release,
1555 };
1556 
boost_config_show(struct seq_file * s,void * data)1557 static int boost_config_show(struct seq_file *s, void *data)
1558 {
1559     struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
1560 
1561     seq_printf(s, "boost_enabled:   %d\n", pll->boost_enabled);
1562     seq_printf(s, "boost_low_rate:  %lu\n", pll->boost_low_rate);
1563     seq_printf(s, "boost_high_rate: %lu\n", pll->boost_high_rate);
1564 
1565     return 0;
1566 }
1567 
boost_config_open(struct inode * inode,struct file * file)1568 static int boost_config_open(struct inode *inode, struct file *file)
1569 {
1570     return single_open(file, boost_config_show, inode->i_private);
1571 }
1572 
1573 static const struct file_operations boost_config_fops = {
1574     .open = boost_config_open,
1575     .read = seq_read,
1576     .llseek = seq_lseek,
1577     .release = single_release,
1578 };
1579 
boost_debug_create_one(struct rockchip_clk_pll * pll,struct dentry * rootdir)1580 static int boost_debug_create_one(struct rockchip_clk_pll *pll, struct dentry *rootdir)
1581 {
1582     struct dentry *pdentry, *d;
1583 
1584     pdentry = debugfs_lookup(clk_hw_get_name(&pll->hw), rootdir);
1585     if (!pdentry) {
1586         pr_err("%s: failed to lookup %s dentry\n", __func__, clk_hw_get_name(&pll->hw));
1587         return -ENOMEM;
1588     }
1589 
1590     d = debugfs_create_file("boost_summary", BOOTST_FILE_READ, pdentry, pll, &boost_summary_fops);
1591     if (!d) {
1592         pr_err("%s: failed to create boost_summary file\n", __func__);
1593         return -ENOMEM;
1594     }
1595 
1596     d = debugfs_create_file("boost_config", BOOTST_FILE_READ, pdentry, pll, &boost_config_fops);
1597     if (!d) {
1598         pr_err("%s: failed to create boost config file\n", __func__);
1599         return -ENOMEM;
1600     }
1601 
1602     return 0;
1603 }
1604 
boost_debug_init(void)1605 static int __init boost_debug_init(void)
1606 {
1607     struct rockchip_clk_pll *pll;
1608     struct dentry *rootdir;
1609 
1610     rootdir = debugfs_lookup("clk", NULL);
1611     if (!rootdir) {
1612         pr_err("%s: failed to lookup clk dentry\n", __func__);
1613         return -ENOMEM;
1614     }
1615 
1616     mutex_lock(&clk_boost_lock);
1617 
1618     hlist_for_each_entry(pll, &clk_boost_list, debug_node) boost_debug_create_one(pll, rootdir);
1619 
1620     mutex_unlock(&clk_boost_lock);
1621 
1622     return 0;
1623 }
1624 late_initcall(boost_debug_init);
1625 #endif /* MODULE */
1626 #endif /* CONFIG_DEBUG_FS */
1627