2 * Copyright (c) 2014 MundoReader S.L.
3 * Author: Heiko Stuebner <heiko@sntech.de>
5 * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
6 * Author: Xing Zheng <zhengxing@rock-chips.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <asm/div64.h>
20 #include <linux/slab.h>
22 #include <linux/delay.h>
23 #include <linux/clk-provider.h>
24 #include <linux/regmap.h>
25 #include <linux/clk.h>
28 #define PLL_MODE_MASK 0x3
29 #define PLL_MODE_SLOW 0x0
30 #define PLL_MODE_NORM 0x1
31 #define PLL_MODE_DEEP 0x2
33 struct rockchip_clk_pll {
36 struct clk_mux pll_mux;
37 const struct clk_ops *pll_mux_ops;
39 struct notifier_block clk_nb;
41 void __iomem *reg_base;
43 unsigned int lock_shift;
44 enum rockchip_pll_type type;
46 const struct rockchip_pll_rate_table *rate_table;
47 unsigned int rate_count;
50 struct rockchip_clk_provider *ctx;
53 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
54 #define to_rockchip_clk_pll_nb(nb) \
55 container_of(nb, struct rockchip_clk_pll, clk_nb)
57 static void rockchip_rk3366_pll_get_params(struct rockchip_clk_pll *pll,
58 struct rockchip_pll_rate_table *rate);
59 static int rockchip_rk3366_pll_set_params(struct rockchip_clk_pll *pll,
60 const struct rockchip_pll_rate_table *rate);
62 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
63 struct rockchip_clk_pll *pll, unsigned long rate)
65 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
68 for (i = 0; i < pll->rate_count; i++) {
69 if (rate == rate_table[i].rate)
70 return &rate_table[i];
76 static long rockchip_pll_round_rate(struct clk_hw *hw,
77 unsigned long drate, unsigned long *prate)
79 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
80 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
83 /* Assumming rate_table is in descending order */
84 for (i = 0; i < pll->rate_count; i++) {
85 if (drate >= rate_table[i].rate)
86 return rate_table[i].rate;
89 /* return minimum supported value */
90 return rate_table[i - 1].rate;
94 * Wait for the pll to reach the locked state.
95 * The calling set_rate function is responsible for making sure the
96 * grf regmap is available.
98 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
100 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
102 int delay = 24000000, ret;
105 ret = regmap_read(grf, pll->lock_offset, &val);
107 pr_err("%s: failed to read pll lock status: %d\n",
112 if (val & BIT(pll->lock_shift))
117 pr_err("%s: timeout waiting for pll to lock\n", __func__);
125 #define RK3036_PLLCON(i) (i * 0x4)
126 #define RK3036_PLLCON0_FBDIV_MASK 0xfff
127 #define RK3036_PLLCON0_FBDIV_SHIFT 0
128 #define RK3036_PLLCON0_POSTDIV1_MASK 0x7
129 #define RK3036_PLLCON0_POSTDIV1_SHIFT 12
130 #define RK3036_PLLCON1_REFDIV_MASK 0x3f
131 #define RK3036_PLLCON1_REFDIV_SHIFT 0
132 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7
133 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6
134 #define RK3036_PLLCON1_DSMPD_MASK 0x1
135 #define RK3036_PLLCON1_DSMPD_SHIFT 12
136 #define RK3036_PLLCON2_FRAC_MASK 0xffffff
137 #define RK3036_PLLCON2_FRAC_SHIFT 0
139 #define RK3036_PLLCON1_PWRDOWN (1 << 13)
141 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
142 struct rockchip_pll_rate_table *rate)
146 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
147 rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
148 & RK3036_PLLCON0_FBDIV_MASK);
149 rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
150 & RK3036_PLLCON0_POSTDIV1_MASK);
152 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
153 rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
154 & RK3036_PLLCON1_REFDIV_MASK);
155 rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
156 & RK3036_PLLCON1_POSTDIV2_MASK);
157 rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
158 & RK3036_PLLCON1_DSMPD_MASK);
160 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
161 rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
162 & RK3036_PLLCON2_FRAC_MASK);
165 static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
168 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
169 struct rockchip_pll_rate_table cur;
172 if (pll->type == pll_rk3366)
173 rockchip_rk3366_pll_get_params(pll, &cur);
175 rockchip_rk3036_pll_get_params(pll, &cur);
178 do_div(rate64, cur.refdiv);
180 if (cur.dsmpd == 0) {
181 /* fractional mode */
182 u64 frac_rate64 = prate * cur.frac;
184 do_div(frac_rate64, cur.refdiv);
185 rate64 += frac_rate64 >> 24;
188 do_div(rate64, cur.postdiv1);
189 do_div(rate64, cur.postdiv2);
191 return (unsigned long)rate64;
194 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
195 const struct rockchip_pll_rate_table *rate)
197 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
198 struct clk_mux *pll_mux = &pll->pll_mux;
199 struct rockchip_pll_rate_table cur;
201 int rate_change_remuxed = 0;
205 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
206 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
207 rate->postdiv2, rate->dsmpd, rate->frac);
209 rockchip_rk3036_pll_get_params(pll, &cur);
212 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
213 if (cur_parent == PLL_MODE_NORM) {
214 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
215 rate_change_remuxed = 1;
218 /* update pll values */
219 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
220 RK3036_PLLCON0_FBDIV_SHIFT) |
221 HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
222 RK3036_PLLCON0_POSTDIV1_SHIFT),
223 pll->reg_base + RK3036_PLLCON(0));
225 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
226 RK3036_PLLCON1_REFDIV_SHIFT) |
227 HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
228 RK3036_PLLCON1_POSTDIV2_SHIFT) |
229 HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
230 RK3036_PLLCON1_DSMPD_SHIFT),
231 pll->reg_base + RK3036_PLLCON(1));
233 /* GPLL CON2 is not HIWORD_MASK */
234 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
235 pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
236 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
237 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
239 /* wait for the pll to lock */
240 ret = rockchip_pll_wait_lock(pll);
242 pr_warn("%s: pll update unsucessful, trying to restore old params\n",
244 rockchip_rk3036_pll_set_params(pll, &cur);
247 if (rate_change_remuxed)
248 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
253 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
256 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
257 const struct rockchip_pll_rate_table *rate;
258 unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
259 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
262 pr_debug("%s: grf regmap not available, aborting rate change\n",
267 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
268 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
270 /* Get required rate settings from table */
271 rate = rockchip_get_pll_settings(pll, drate);
273 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
274 drate, __clk_get_name(hw->clk));
278 if (pll->type == pll_rk3366)
279 return rockchip_rk3366_pll_set_params(pll, rate);
281 return rockchip_rk3036_pll_set_params(pll, rate);
284 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
286 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
288 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
289 pll->reg_base + RK3036_PLLCON(1));
294 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
296 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
298 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
299 RK3036_PLLCON1_PWRDOWN, 0),
300 pll->reg_base + RK3036_PLLCON(1));
303 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
305 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
306 u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
308 return !(pllcon & RK3036_PLLCON1_PWRDOWN);
311 static void rockchip_rk3036_pll_init(struct clk_hw *hw)
313 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
314 const struct rockchip_pll_rate_table *rate;
315 struct rockchip_pll_rate_table cur;
318 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
321 drate = clk_hw_get_rate(hw);
322 rate = rockchip_get_pll_settings(pll, drate);
324 /* when no rate setting for the current rate, rely on clk_set_rate */
328 if (pll->type == pll_rk3366)
329 rockchip_rk3366_pll_get_params(pll, &cur);
331 rockchip_rk3036_pll_get_params(pll, &cur);
333 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
335 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
336 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
337 cur.dsmpd, cur.frac);
338 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
339 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
340 rate->dsmpd, rate->frac);
342 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
343 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
344 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
345 struct clk *parent = clk_get_parent(hw->clk);
348 pr_warn("%s: parent of %s not available\n",
349 __func__, __clk_get_name(hw->clk));
353 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
354 __func__, __clk_get_name(hw->clk));
355 if (pll->type == pll_rk3366)
356 rockchip_rk3366_pll_set_params(pll, rate);
358 rockchip_rk3036_pll_set_params(pll, rate);
362 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
363 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
364 .enable = rockchip_rk3036_pll_enable,
365 .disable = rockchip_rk3036_pll_disable,
366 .is_enabled = rockchip_rk3036_pll_is_enabled,
369 static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
370 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
371 .round_rate = rockchip_pll_round_rate,
372 .set_rate = rockchip_rk3036_pll_set_rate,
373 .enable = rockchip_rk3036_pll_enable,
374 .disable = rockchip_rk3036_pll_disable,
375 .is_enabled = rockchip_rk3036_pll_is_enabled,
376 .init = rockchip_rk3036_pll_init,
380 * PLL used in RK3066, RK3188 and RK3288
383 #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1)
385 #define RK3066_PLLCON(i) (i * 0x4)
386 #define RK3066_PLLCON0_OD_MASK 0xf
387 #define RK3066_PLLCON0_OD_SHIFT 0
388 #define RK3066_PLLCON0_NR_MASK 0x3f
389 #define RK3066_PLLCON0_NR_SHIFT 8
390 #define RK3066_PLLCON1_NF_MASK 0x1fff
391 #define RK3066_PLLCON1_NF_SHIFT 0
392 #define RK3066_PLLCON2_NB_MASK 0xfff
393 #define RK3066_PLLCON2_NB_SHIFT 0
394 #define RK3066_PLLCON3_RESET (1 << 5)
395 #define RK3066_PLLCON3_PWRDOWN (1 << 1)
396 #define RK3066_PLLCON3_BYPASS (1 << 0)
398 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
399 struct rockchip_pll_rate_table *rate)
403 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
404 rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
405 & RK3066_PLLCON0_NR_MASK) + 1;
406 rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
407 & RK3066_PLLCON0_OD_MASK) + 1;
409 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
410 rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
411 & RK3066_PLLCON1_NF_MASK) + 1;
413 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
414 rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
415 & RK3066_PLLCON2_NB_MASK) + 1;
418 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
421 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
422 struct rockchip_pll_rate_table cur;
426 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
427 if (pllcon & RK3066_PLLCON3_BYPASS) {
428 pr_debug("%s: pll %s is bypassed\n", __func__,
429 clk_hw_get_name(hw));
433 rockchip_rk3066_pll_get_params(pll, &cur);
436 do_div(rate64, cur.nr);
437 do_div(rate64, cur.no);
439 return (unsigned long)rate64;
442 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
443 const struct rockchip_pll_rate_table *rate)
445 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
446 struct clk_mux *pll_mux = &pll->pll_mux;
447 struct rockchip_pll_rate_table cur;
448 int rate_change_remuxed = 0;
452 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
453 __func__, rate->rate, rate->nr, rate->no, rate->nf);
455 rockchip_rk3066_pll_get_params(pll, &cur);
458 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
459 if (cur_parent == PLL_MODE_NORM) {
460 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
461 rate_change_remuxed = 1;
464 /* enter reset mode */
465 writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
466 pll->reg_base + RK3066_PLLCON(3));
468 /* update pll values */
469 writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
470 RK3066_PLLCON0_NR_SHIFT) |
471 HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
472 RK3066_PLLCON0_OD_SHIFT),
473 pll->reg_base + RK3066_PLLCON(0));
475 writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
476 RK3066_PLLCON1_NF_SHIFT),
477 pll->reg_base + RK3066_PLLCON(1));
478 writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
479 RK3066_PLLCON2_NB_SHIFT),
480 pll->reg_base + RK3066_PLLCON(2));
482 /* leave reset and wait the reset_delay */
483 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
484 pll->reg_base + RK3066_PLLCON(3));
485 udelay(RK3066_PLL_RESET_DELAY(rate->nr));
487 /* wait for the pll to lock */
488 ret = rockchip_pll_wait_lock(pll);
490 pr_warn("%s: pll update unsucessful, trying to restore old params\n",
492 rockchip_rk3066_pll_set_params(pll, &cur);
495 if (rate_change_remuxed)
496 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
501 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
504 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
505 const struct rockchip_pll_rate_table *rate;
506 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
507 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
510 pr_debug("%s: grf regmap not available, aborting rate change\n",
515 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
516 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
518 /* Get required rate settings from table */
519 rate = rockchip_get_pll_settings(pll, drate);
521 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
522 drate, clk_hw_get_name(hw));
526 return rockchip_rk3066_pll_set_params(pll, rate);
529 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
531 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
533 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
534 pll->reg_base + RK3066_PLLCON(3));
539 static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
541 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
543 writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
544 RK3066_PLLCON3_PWRDOWN, 0),
545 pll->reg_base + RK3066_PLLCON(3));
548 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
550 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
551 u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
553 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
556 static void rockchip_rk3066_pll_init(struct clk_hw *hw)
558 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
559 const struct rockchip_pll_rate_table *rate;
560 struct rockchip_pll_rate_table cur;
563 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
566 drate = clk_hw_get_rate(hw);
567 rate = rockchip_get_pll_settings(pll, drate);
569 /* when no rate setting for the current rate, rely on clk_set_rate */
573 rockchip_rk3066_pll_get_params(pll, &cur);
575 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
576 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
577 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
578 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
579 || rate->nb != cur.nb) {
580 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
585 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
586 __func__, clk_hw_get_name(hw));
587 rockchip_rk3066_pll_set_params(pll, rate);
591 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
592 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
593 .enable = rockchip_rk3066_pll_enable,
594 .disable = rockchip_rk3066_pll_disable,
595 .is_enabled = rockchip_rk3066_pll_is_enabled,
598 static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
599 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
600 .round_rate = rockchip_pll_round_rate,
601 .set_rate = rockchip_rk3066_pll_set_rate,
602 .enable = rockchip_rk3066_pll_enable,
603 .disable = rockchip_rk3066_pll_disable,
604 .is_enabled = rockchip_rk3066_pll_is_enabled,
605 .init = rockchip_rk3066_pll_init,
612 #define RK3366_PLLCON(i) (i * 0x4)
613 #define RK3366_PLLCON0_FBDIV_MASK 0xfff
614 #define RK3366_PLLCON0_FBDIV_SHIFT 0
615 #define RK3366_PLLCON0_POSTDIV1_MASK 0x7
616 #define RK3366_PLLCON0_POSTDIV1_SHIFT 12
617 #define RK3366_PLLCON1_REFDIV_MASK 0x3f
618 #define RK3366_PLLCON1_REFDIV_SHIFT 0
619 #define RK3366_PLLCON1_POSTDIV2_MASK 0x7
620 #define RK3366_PLLCON1_POSTDIV2_SHIFT 6
621 #define RK3366_PLLCON2_FRAC_MASK 0xffffff
622 #define RK3366_PLLCON2_FRAC_SHIFT 0
623 #define RK3366_PLLCON3_DSMPD_MASK 0x1
624 #define RK3366_PLLCON3_DSMPD_SHIFT 2
626 #define RK3366_PLLCON3_PWRDOWN (1 << 0)
628 static void rockchip_rk3366_pll_get_params(struct rockchip_clk_pll *pll,
629 struct rockchip_pll_rate_table *rate)
633 pllcon = readl_relaxed(pll->reg_base + RK3366_PLLCON(0));
634 rate->fbdiv = ((pllcon >> RK3366_PLLCON0_FBDIV_SHIFT)
635 & RK3366_PLLCON0_FBDIV_MASK);
636 rate->postdiv1 = ((pllcon >> RK3366_PLLCON0_POSTDIV1_SHIFT)
637 & RK3366_PLLCON0_POSTDIV1_MASK);
639 pllcon = readl_relaxed(pll->reg_base + RK3366_PLLCON(1));
640 rate->refdiv = ((pllcon >> RK3366_PLLCON1_REFDIV_SHIFT)
641 & RK3366_PLLCON1_REFDIV_MASK);
642 rate->postdiv2 = ((pllcon >> RK3366_PLLCON1_POSTDIV2_SHIFT)
643 & RK3366_PLLCON1_POSTDIV2_MASK);
645 pllcon = readl_relaxed(pll->reg_base + RK3366_PLLCON(2));
646 rate->frac = ((pllcon >> RK3366_PLLCON2_FRAC_SHIFT)
647 & RK3366_PLLCON2_FRAC_MASK);
649 pllcon = readl_relaxed(pll->reg_base + RK3366_PLLCON(3));
650 rate->dsmpd = ((pllcon >> RK3366_PLLCON3_DSMPD_SHIFT)
651 & RK3366_PLLCON3_DSMPD_MASK);
654 static int rockchip_rk3366_pll_set_params(struct rockchip_clk_pll *pll,
655 const struct rockchip_pll_rate_table *rate)
657 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
658 struct clk_mux *pll_mux = &pll->pll_mux;
659 struct rockchip_pll_rate_table cur;
661 int rate_change_remuxed = 0;
665 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
666 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
667 rate->postdiv2, rate->dsmpd, rate->frac);
669 rockchip_rk3366_pll_get_params(pll, &cur);
672 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
673 if (cur_parent == PLL_MODE_NORM) {
674 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
675 rate_change_remuxed = 1;
678 /* update pll values */
679 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3366_PLLCON0_FBDIV_MASK,
680 RK3366_PLLCON0_FBDIV_SHIFT) |
681 HIWORD_UPDATE(rate->postdiv1, RK3366_PLLCON0_POSTDIV1_MASK,
682 RK3366_PLLCON0_POSTDIV1_SHIFT),
683 pll->reg_base + RK3366_PLLCON(0));
685 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3366_PLLCON1_REFDIV_MASK,
686 RK3366_PLLCON1_REFDIV_SHIFT) |
687 HIWORD_UPDATE(rate->postdiv2, RK3366_PLLCON1_POSTDIV2_MASK,
688 RK3366_PLLCON1_POSTDIV2_SHIFT),
689 pll->reg_base + RK3366_PLLCON(1));
691 /* GPLL CON2 is not HIWORD_MASK */
692 pllcon = readl_relaxed(pll->reg_base + RK3366_PLLCON(2));
693 pllcon &= ~(RK3366_PLLCON2_FRAC_MASK << RK3366_PLLCON2_FRAC_SHIFT);
694 pllcon |= rate->frac << RK3366_PLLCON2_FRAC_SHIFT;
695 writel_relaxed(pllcon, pll->reg_base + RK3366_PLLCON(2));
697 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3366_PLLCON3_DSMPD_MASK,
698 RK3366_PLLCON3_DSMPD_SHIFT),
699 pll->reg_base + RK3366_PLLCON(3));
701 /* wait for the pll to lock */
702 ret = rockchip_pll_wait_lock(pll);
704 pr_warn("%s: pll update unsucessful, trying to restore old params\n",
706 rockchip_rk3366_pll_set_params(pll, &cur);
709 if (rate_change_remuxed)
710 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
715 static int rockchip_rk3366_pll_enable(struct clk_hw *hw)
717 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
719 writel(HIWORD_UPDATE(0, RK3366_PLLCON3_PWRDOWN, 0),
720 pll->reg_base + RK3366_PLLCON(3));
725 static void rockchip_rk3366_pll_disable(struct clk_hw *hw)
727 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
729 writel(HIWORD_UPDATE(RK3366_PLLCON3_PWRDOWN,
730 RK3366_PLLCON3_PWRDOWN, 0),
731 pll->reg_base + RK3366_PLLCON(3));
734 static int rockchip_rk3366_pll_is_enabled(struct clk_hw *hw)
736 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
737 u32 pllcon = readl(pll->reg_base + RK3366_PLLCON(3));
739 return !(pllcon & RK3366_PLLCON3_PWRDOWN);
742 static const struct clk_ops rockchip_rk3366_pll_clk_norate_ops = {
743 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
744 .enable = rockchip_rk3366_pll_enable,
745 .disable = rockchip_rk3366_pll_disable,
746 .is_enabled = rockchip_rk3366_pll_is_enabled,
749 static const struct clk_ops rockchip_rk3366_pll_clk_ops = {
750 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
751 .round_rate = rockchip_pll_round_rate,
752 .set_rate = rockchip_rk3036_pll_set_rate,
753 .enable = rockchip_rk3366_pll_enable,
754 .disable = rockchip_rk3366_pll_disable,
755 .is_enabled = rockchip_rk3366_pll_is_enabled,
756 .init = rockchip_rk3036_pll_init,
763 #define RK3399_PLLCON(i) (i * 0x4)
764 #define RK3399_PLLCON0_FBDIV_MASK 0xfff
765 #define RK3399_PLLCON0_FBDIV_SHIFT 0
766 #define RK3399_PLLCON1_REFDIV_MASK 0x3f
767 #define RK3399_PLLCON1_REFDIV_SHIFT 0
768 #define RK3399_PLLCON1_POSTDIV1_MASK 0x7
769 #define RK3399_PLLCON1_POSTDIV1_SHIFT 8
770 #define RK3399_PLLCON1_POSTDIV2_MASK 0x7
771 #define RK3399_PLLCON1_POSTDIV2_SHIFT 12
772 #define RK3399_PLLCON2_FRAC_MASK 0xffffff
773 #define RK3399_PLLCON2_FRAC_SHIFT 0
774 #define RK3399_PLLCON2_LOCK_STATUS BIT(31)
775 #define RK3399_PLLCON3_PWRDOWN BIT(0)
776 #define RK3399_PLLCON3_DSMPD_MASK 0x1
777 #define RK3399_PLLCON3_DSMPD_SHIFT 3
779 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
782 int delay = 24000000;
784 /* poll check the lock status in rk3399 xPLLCON2 */
786 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
787 if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
793 pr_err("%s: timeout waiting for pll to lock\n", __func__);
797 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
798 struct rockchip_pll_rate_table *rate)
802 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
803 rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
804 & RK3399_PLLCON0_FBDIV_MASK);
806 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
807 rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
808 & RK3399_PLLCON1_REFDIV_MASK);
809 rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
810 & RK3399_PLLCON1_POSTDIV1_MASK);
811 rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
812 & RK3399_PLLCON1_POSTDIV2_MASK);
814 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
815 rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
816 & RK3399_PLLCON2_FRAC_MASK);
818 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
819 rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
820 & RK3399_PLLCON3_DSMPD_MASK);
823 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
826 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
827 struct rockchip_pll_rate_table cur;
830 rockchip_rk3399_pll_get_params(pll, &cur);
833 do_div(rate64, cur.refdiv);
835 if (cur.dsmpd == 0) {
836 /* fractional mode */
837 u64 frac_rate64 = prate * cur.frac;
839 do_div(frac_rate64, cur.refdiv);
840 rate64 += frac_rate64 >> 24;
843 do_div(rate64, cur.postdiv1);
844 do_div(rate64, cur.postdiv2);
846 return (unsigned long)rate64;
849 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
850 const struct rockchip_pll_rate_table *rate)
852 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
853 struct clk_mux *pll_mux = &pll->pll_mux;
854 struct rockchip_pll_rate_table cur;
856 int rate_change_remuxed = 0;
860 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
861 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
862 rate->postdiv2, rate->dsmpd, rate->frac);
864 rockchip_rk3399_pll_get_params(pll, &cur);
867 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
868 if (cur_parent == PLL_MODE_NORM) {
869 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
870 rate_change_remuxed = 1;
873 /* update pll values */
874 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
875 RK3399_PLLCON0_FBDIV_SHIFT),
876 pll->reg_base + RK3399_PLLCON(0));
878 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
879 RK3399_PLLCON1_REFDIV_SHIFT) |
880 HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
881 RK3399_PLLCON1_POSTDIV1_SHIFT) |
882 HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
883 RK3399_PLLCON1_POSTDIV2_SHIFT),
884 pll->reg_base + RK3399_PLLCON(1));
886 /* xPLL CON2 is not HIWORD_MASK */
887 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
888 pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
889 pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
890 writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
892 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
893 RK3399_PLLCON3_DSMPD_SHIFT),
894 pll->reg_base + RK3399_PLLCON(3));
896 /* wait for the pll to lock */
897 ret = rockchip_rk3399_pll_wait_lock(pll);
899 pr_warn("%s: pll update unsucessful, trying to restore old params\n",
901 rockchip_rk3399_pll_set_params(pll, &cur);
904 if (rate_change_remuxed)
905 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
910 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
913 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
914 const struct rockchip_pll_rate_table *rate;
915 unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate);
917 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
918 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
920 /* Get required rate settings from table */
921 rate = rockchip_get_pll_settings(pll, drate);
923 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
924 drate, __clk_get_name(hw->clk));
928 return rockchip_rk3399_pll_set_params(pll, rate);
931 static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
933 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
935 writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
936 pll->reg_base + RK3399_PLLCON(3));
941 static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
943 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
945 writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
946 RK3399_PLLCON3_PWRDOWN, 0),
947 pll->reg_base + RK3399_PLLCON(3));
950 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
952 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
953 u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
955 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
958 static void rockchip_rk3399_pll_init(struct clk_hw *hw)
960 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
961 const struct rockchip_pll_rate_table *rate;
962 struct rockchip_pll_rate_table cur;
965 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
968 drate = clk_hw_get_rate(hw);
969 rate = rockchip_get_pll_settings(pll, drate);
971 /* when no rate setting for the current rate, rely on clk_set_rate */
975 rockchip_rk3399_pll_get_params(pll, &cur);
977 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
979 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
980 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
981 cur.dsmpd, cur.frac);
982 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
983 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
984 rate->dsmpd, rate->frac);
986 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
987 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
988 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
989 struct clk *parent = clk_get_parent(hw->clk);
992 pr_warn("%s: parent of %s not available\n",
993 __func__, __clk_get_name(hw->clk));
997 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
998 __func__, __clk_get_name(hw->clk));
999 rockchip_rk3399_pll_set_params(pll, rate);
1003 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
1004 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
1005 .enable = rockchip_rk3399_pll_enable,
1006 .disable = rockchip_rk3399_pll_disable,
1007 .is_enabled = rockchip_rk3399_pll_is_enabled,
1010 static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
1011 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
1012 .round_rate = rockchip_pll_round_rate,
1013 .set_rate = rockchip_rk3399_pll_set_rate,
1014 .enable = rockchip_rk3399_pll_enable,
1015 .disable = rockchip_rk3399_pll_disable,
1016 .is_enabled = rockchip_rk3399_pll_is_enabled,
1017 .init = rockchip_rk3399_pll_init,
1021 * Common registering of pll clocks
1024 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1025 enum rockchip_pll_type pll_type,
1026 const char *name, const char *const *parent_names,
1027 u8 num_parents, int con_offset, int grf_lock_offset,
1028 int lock_shift, int mode_offset, int mode_shift,
1029 struct rockchip_pll_rate_table *rate_table,
1032 const char *pll_parents[3];
1033 struct clk_init_data init;
1034 struct rockchip_clk_pll *pll;
1035 struct clk_mux *pll_mux;
1036 struct clk *pll_clk, *mux_clk;
1039 if (num_parents != 2) {
1040 pr_err("%s: needs two parent clocks\n", __func__);
1041 return ERR_PTR(-EINVAL);
1044 /* name the actual pll */
1045 snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
1047 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1049 return ERR_PTR(-ENOMEM);
1051 /* create the mux on top of the real pll */
1052 pll->pll_mux_ops = &clk_mux_ops;
1053 pll_mux = &pll->pll_mux;
1054 pll_mux->reg = ctx->reg_base + mode_offset;
1055 pll_mux->shift = mode_shift;
1056 pll_mux->mask = PLL_MODE_MASK;
1058 pll_mux->lock = &ctx->lock;
1059 pll_mux->hw.init = &init;
1061 if (pll_type == pll_rk3036 ||
1062 pll_type == pll_rk3066 ||
1063 pll_type == pll_rk3366 ||
1064 pll_type == pll_rk3399)
1065 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
1067 /* the actual muxing is xin24m, pll-output, xin32k */
1068 pll_parents[0] = parent_names[0];
1069 pll_parents[1] = pll_name;
1070 pll_parents[2] = parent_names[1];
1073 init.flags = CLK_SET_RATE_PARENT;
1074 init.ops = pll->pll_mux_ops;
1075 init.parent_names = pll_parents;
1076 init.num_parents = ARRAY_SIZE(pll_parents);
1078 mux_clk = clk_register(NULL, &pll_mux->hw);
1079 if (IS_ERR(mux_clk))
1082 /* now create the actual pll */
1083 init.name = pll_name;
1085 /* keep all plls untouched for now */
1086 init.flags = CLK_IGNORE_UNUSED;
1088 init.parent_names = &parent_names[0];
1089 init.num_parents = 1;
1094 /* find count of rates in rate_table */
1095 for (len = 0; rate_table[len].rate != 0; )
1098 pll->rate_count = len;
1099 pll->rate_table = kmemdup(rate_table,
1101 sizeof(struct rockchip_pll_rate_table),
1103 WARN(!pll->rate_table,
1104 "%s: could not allocate rate table for %s\n",
1110 if (!pll->rate_table)
1111 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
1113 init.ops = &rockchip_rk3036_pll_clk_ops;
1116 if (!pll->rate_table)
1117 init.ops = &rockchip_rk3066_pll_clk_norate_ops;
1119 init.ops = &rockchip_rk3066_pll_clk_ops;
1122 if (!pll->rate_table)
1123 init.ops = &rockchip_rk3366_pll_clk_norate_ops;
1125 init.ops = &rockchip_rk3366_pll_clk_ops;
1128 if (!pll->rate_table)
1129 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
1131 init.ops = &rockchip_rk3399_pll_clk_ops;
1134 pr_warn("%s: Unknown pll type for pll clk %s\n",
1138 pll->hw.init = &init;
1139 pll->type = pll_type;
1140 pll->reg_base = ctx->reg_base + con_offset;
1141 pll->lock_offset = grf_lock_offset;
1142 pll->lock_shift = lock_shift;
1143 pll->flags = clk_pll_flags;
1144 pll->lock = &ctx->lock;
1147 pll_clk = clk_register(NULL, &pll->hw);
1148 if (IS_ERR(pll_clk)) {
1149 pr_err("%s: failed to register pll clock %s : %ld\n",
1150 __func__, name, PTR_ERR(pll_clk));
1157 clk_unregister(mux_clk);