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 const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
58 struct rockchip_clk_pll *pll, unsigned long rate)
60 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
63 for (i = 0; i < pll->rate_count; i++) {
64 if (rate == rate_table[i].rate)
65 return &rate_table[i];
71 static long rockchip_pll_round_rate(struct clk_hw *hw,
72 unsigned long drate, unsigned long *prate)
74 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
75 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
78 /* Assumming rate_table is in descending order */
79 for (i = 0; i < pll->rate_count; i++) {
80 if (drate >= rate_table[i].rate)
81 return rate_table[i].rate;
84 /* return minimum supported value */
85 return rate_table[i - 1].rate;
89 * Wait for the pll to reach the locked state.
90 * The calling set_rate function is responsible for making sure the
91 * grf regmap is available.
93 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
95 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
97 int delay = 24000000, ret;
100 pr_err("%s: grf regmap not available\n", __func__);
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 rockchip_rk3036_pll_get_params(pll, &cur);
175 do_div(rate64, cur.refdiv);
177 if (cur.dsmpd == 0) {
178 /* fractional mode */
179 u64 frac_rate64 = prate * cur.frac;
181 do_div(frac_rate64, cur.refdiv);
182 rate64 += frac_rate64 >> 24;
185 do_div(rate64, cur.postdiv1);
186 do_div(rate64, cur.postdiv2);
188 return (unsigned long)rate64;
191 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
192 const struct rockchip_pll_rate_table *rate)
194 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
195 struct clk_mux *pll_mux = &pll->pll_mux;
196 struct rockchip_pll_rate_table cur;
198 int rate_change_remuxed = 0;
202 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
203 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
204 rate->postdiv2, rate->dsmpd, rate->frac);
206 rockchip_rk3036_pll_get_params(pll, &cur);
209 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
210 if (cur_parent == PLL_MODE_NORM) {
211 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
212 rate_change_remuxed = 1;
215 /* update pll values */
216 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
217 RK3036_PLLCON0_FBDIV_SHIFT) |
218 HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
219 RK3036_PLLCON0_POSTDIV1_SHIFT),
220 pll->reg_base + RK3036_PLLCON(0));
222 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
223 RK3036_PLLCON1_REFDIV_SHIFT) |
224 HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
225 RK3036_PLLCON1_POSTDIV2_SHIFT) |
226 HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
227 RK3036_PLLCON1_DSMPD_SHIFT),
228 pll->reg_base + RK3036_PLLCON(1));
230 /* GPLL CON2 is not HIWORD_MASK */
231 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
232 pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
233 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
234 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
236 /* wait for the pll to lock */
237 ret = rockchip_pll_wait_lock(pll);
239 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
241 rockchip_rk3036_pll_set_params(pll, &cur);
244 if (rate_change_remuxed)
245 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
250 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
253 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
254 const struct rockchip_pll_rate_table *rate;
255 unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
256 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
259 pr_debug("%s: grf regmap not available, aborting rate change\n",
264 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
265 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
267 /* Get required rate settings from table */
268 rate = rockchip_get_pll_settings(pll, drate);
270 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
271 drate, __clk_get_name(hw->clk));
275 return rockchip_rk3036_pll_set_params(pll, rate);
278 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
280 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
282 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
283 pll->reg_base + RK3036_PLLCON(1));
288 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
290 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
292 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
293 RK3036_PLLCON1_PWRDOWN, 0),
294 pll->reg_base + RK3036_PLLCON(1));
297 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
299 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
300 u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
302 return !(pllcon & RK3036_PLLCON1_PWRDOWN);
305 static void rockchip_rk3036_pll_init(struct clk_hw *hw)
307 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
308 const struct rockchip_pll_rate_table *rate;
309 struct rockchip_pll_rate_table cur;
312 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
315 drate = clk_hw_get_rate(hw);
316 rate = rockchip_get_pll_settings(pll, drate);
318 /* when no rate setting for the current rate, rely on clk_set_rate */
322 rockchip_rk3036_pll_get_params(pll, &cur);
324 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
326 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
327 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
328 cur.dsmpd, cur.frac);
329 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
330 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
331 rate->dsmpd, rate->frac);
333 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
334 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
335 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
336 struct clk *parent = clk_get_parent(hw->clk);
339 pr_warn("%s: parent of %s not available\n",
340 __func__, __clk_get_name(hw->clk));
344 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
345 __func__, __clk_get_name(hw->clk));
346 rockchip_rk3036_pll_set_params(pll, rate);
350 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
351 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
352 .enable = rockchip_rk3036_pll_enable,
353 .disable = rockchip_rk3036_pll_disable,
354 .is_enabled = rockchip_rk3036_pll_is_enabled,
357 static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
358 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
359 .round_rate = rockchip_pll_round_rate,
360 .set_rate = rockchip_rk3036_pll_set_rate,
361 .enable = rockchip_rk3036_pll_enable,
362 .disable = rockchip_rk3036_pll_disable,
363 .is_enabled = rockchip_rk3036_pll_is_enabled,
364 .init = rockchip_rk3036_pll_init,
368 * PLL used in RK3066, RK3188 and RK3288
371 #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1)
373 #define RK3066_PLLCON(i) (i * 0x4)
374 #define RK3066_PLLCON0_OD_MASK 0xf
375 #define RK3066_PLLCON0_OD_SHIFT 0
376 #define RK3066_PLLCON0_NR_MASK 0x3f
377 #define RK3066_PLLCON0_NR_SHIFT 8
378 #define RK3066_PLLCON1_NF_MASK 0x1fff
379 #define RK3066_PLLCON1_NF_SHIFT 0
380 #define RK3066_PLLCON2_NB_MASK 0xfff
381 #define RK3066_PLLCON2_NB_SHIFT 0
382 #define RK3066_PLLCON3_RESET (1 << 5)
383 #define RK3066_PLLCON3_PWRDOWN (1 << 1)
384 #define RK3066_PLLCON3_BYPASS (1 << 0)
386 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
387 struct rockchip_pll_rate_table *rate)
391 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
392 rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
393 & RK3066_PLLCON0_NR_MASK) + 1;
394 rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
395 & RK3066_PLLCON0_OD_MASK) + 1;
397 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
398 rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
399 & RK3066_PLLCON1_NF_MASK) + 1;
401 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
402 rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
403 & RK3066_PLLCON2_NB_MASK) + 1;
406 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
409 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
410 struct rockchip_pll_rate_table cur;
414 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
415 if (pllcon & RK3066_PLLCON3_BYPASS) {
416 pr_debug("%s: pll %s is bypassed\n", __func__,
417 clk_hw_get_name(hw));
421 rockchip_rk3066_pll_get_params(pll, &cur);
424 do_div(rate64, cur.nr);
425 do_div(rate64, cur.no);
427 return (unsigned long)rate64;
430 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
431 const struct rockchip_pll_rate_table *rate)
433 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
434 struct clk_mux *pll_mux = &pll->pll_mux;
435 struct rockchip_pll_rate_table cur;
436 int rate_change_remuxed = 0;
440 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
441 __func__, rate->rate, rate->nr, rate->no, rate->nf);
443 rockchip_rk3066_pll_get_params(pll, &cur);
446 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
447 if (cur_parent == PLL_MODE_NORM) {
448 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
449 rate_change_remuxed = 1;
452 /* enter reset mode */
453 writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
454 pll->reg_base + RK3066_PLLCON(3));
456 /* update pll values */
457 writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
458 RK3066_PLLCON0_NR_SHIFT) |
459 HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
460 RK3066_PLLCON0_OD_SHIFT),
461 pll->reg_base + RK3066_PLLCON(0));
463 writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
464 RK3066_PLLCON1_NF_SHIFT),
465 pll->reg_base + RK3066_PLLCON(1));
466 writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
467 RK3066_PLLCON2_NB_SHIFT),
468 pll->reg_base + RK3066_PLLCON(2));
470 /* leave reset and wait the reset_delay */
471 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
472 pll->reg_base + RK3066_PLLCON(3));
473 udelay(RK3066_PLL_RESET_DELAY(rate->nr));
475 /* wait for the pll to lock */
476 ret = rockchip_pll_wait_lock(pll);
478 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
480 rockchip_rk3066_pll_set_params(pll, &cur);
483 if (rate_change_remuxed)
484 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
489 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
492 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
493 const struct rockchip_pll_rate_table *rate;
494 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
495 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
498 pr_debug("%s: grf regmap not available, aborting rate change\n",
503 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
504 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
506 /* Get required rate settings from table */
507 rate = rockchip_get_pll_settings(pll, drate);
509 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
510 drate, clk_hw_get_name(hw));
514 return rockchip_rk3066_pll_set_params(pll, rate);
517 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
519 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
521 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
522 pll->reg_base + RK3066_PLLCON(3));
527 static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
529 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
531 writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
532 RK3066_PLLCON3_PWRDOWN, 0),
533 pll->reg_base + RK3066_PLLCON(3));
536 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
538 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
539 u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
541 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
544 static void rockchip_rk3066_pll_init(struct clk_hw *hw)
546 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
547 const struct rockchip_pll_rate_table *rate;
548 struct rockchip_pll_rate_table cur;
551 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
554 drate = clk_hw_get_rate(hw);
555 rate = rockchip_get_pll_settings(pll, drate);
557 /* when no rate setting for the current rate, rely on clk_set_rate */
561 rockchip_rk3066_pll_get_params(pll, &cur);
563 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
564 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
565 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
566 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
567 || rate->nb != cur.nb) {
568 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
573 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
574 __func__, clk_hw_get_name(hw));
575 rockchip_rk3066_pll_set_params(pll, rate);
579 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
580 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
581 .enable = rockchip_rk3066_pll_enable,
582 .disable = rockchip_rk3066_pll_disable,
583 .is_enabled = rockchip_rk3066_pll_is_enabled,
586 static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
587 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
588 .round_rate = rockchip_pll_round_rate,
589 .set_rate = rockchip_rk3066_pll_set_rate,
590 .enable = rockchip_rk3066_pll_enable,
591 .disable = rockchip_rk3066_pll_disable,
592 .is_enabled = rockchip_rk3066_pll_is_enabled,
593 .init = rockchip_rk3066_pll_init,
600 #define RK3399_PLLCON(i) (i * 0x4)
601 #define RK3399_PLLCON0_FBDIV_MASK 0xfff
602 #define RK3399_PLLCON0_FBDIV_SHIFT 0
603 #define RK3399_PLLCON1_REFDIV_MASK 0x3f
604 #define RK3399_PLLCON1_REFDIV_SHIFT 0
605 #define RK3399_PLLCON1_POSTDIV1_MASK 0x7
606 #define RK3399_PLLCON1_POSTDIV1_SHIFT 8
607 #define RK3399_PLLCON1_POSTDIV2_MASK 0x7
608 #define RK3399_PLLCON1_POSTDIV2_SHIFT 12
609 #define RK3399_PLLCON2_FRAC_MASK 0xffffff
610 #define RK3399_PLLCON2_FRAC_SHIFT 0
611 #define RK3399_PLLCON2_LOCK_STATUS BIT(31)
612 #define RK3399_PLLCON3_PWRDOWN BIT(0)
613 #define RK3399_PLLCON3_DSMPD_MASK 0x1
614 #define RK3399_PLLCON3_DSMPD_SHIFT 3
616 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
619 int delay = 24000000;
621 /* poll check the lock status in rk3399 xPLLCON2 */
623 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
624 if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
630 pr_err("%s: timeout waiting for pll to lock\n", __func__);
634 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
635 struct rockchip_pll_rate_table *rate)
639 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
640 rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
641 & RK3399_PLLCON0_FBDIV_MASK);
643 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
644 rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
645 & RK3399_PLLCON1_REFDIV_MASK);
646 rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
647 & RK3399_PLLCON1_POSTDIV1_MASK);
648 rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
649 & RK3399_PLLCON1_POSTDIV2_MASK);
651 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
652 rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
653 & RK3399_PLLCON2_FRAC_MASK);
655 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
656 rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
657 & RK3399_PLLCON3_DSMPD_MASK);
660 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
663 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
664 struct rockchip_pll_rate_table cur;
667 rockchip_rk3399_pll_get_params(pll, &cur);
670 do_div(rate64, cur.refdiv);
672 if (cur.dsmpd == 0) {
673 /* fractional mode */
674 u64 frac_rate64 = prate * cur.frac;
676 do_div(frac_rate64, cur.refdiv);
677 rate64 += frac_rate64 >> 24;
680 do_div(rate64, cur.postdiv1);
681 do_div(rate64, cur.postdiv2);
683 return (unsigned long)rate64;
686 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
687 const struct rockchip_pll_rate_table *rate)
689 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
690 struct clk_mux *pll_mux = &pll->pll_mux;
691 struct rockchip_pll_rate_table cur;
693 int rate_change_remuxed = 0;
697 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
698 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
699 rate->postdiv2, rate->dsmpd, rate->frac);
701 rockchip_rk3399_pll_get_params(pll, &cur);
704 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
705 if (cur_parent == PLL_MODE_NORM) {
706 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
707 rate_change_remuxed = 1;
710 /* update pll values */
711 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
712 RK3399_PLLCON0_FBDIV_SHIFT),
713 pll->reg_base + RK3399_PLLCON(0));
715 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
716 RK3399_PLLCON1_REFDIV_SHIFT) |
717 HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
718 RK3399_PLLCON1_POSTDIV1_SHIFT) |
719 HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
720 RK3399_PLLCON1_POSTDIV2_SHIFT),
721 pll->reg_base + RK3399_PLLCON(1));
723 /* xPLL CON2 is not HIWORD_MASK */
724 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
725 pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
726 pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
727 writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
729 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
730 RK3399_PLLCON3_DSMPD_SHIFT),
731 pll->reg_base + RK3399_PLLCON(3));
733 /* wait for the pll to lock */
734 ret = rockchip_rk3399_pll_wait_lock(pll);
736 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
738 rockchip_rk3399_pll_set_params(pll, &cur);
741 if (rate_change_remuxed)
742 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
747 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
750 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
751 const struct rockchip_pll_rate_table *rate;
752 unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate);
754 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
755 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
757 /* Get required rate settings from table */
758 rate = rockchip_get_pll_settings(pll, drate);
760 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
761 drate, __clk_get_name(hw->clk));
765 return rockchip_rk3399_pll_set_params(pll, rate);
768 static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
770 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
772 writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
773 pll->reg_base + RK3399_PLLCON(3));
778 static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
780 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
782 writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
783 RK3399_PLLCON3_PWRDOWN, 0),
784 pll->reg_base + RK3399_PLLCON(3));
787 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
789 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
790 u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
792 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
795 static void rockchip_rk3399_pll_init(struct clk_hw *hw)
797 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
798 const struct rockchip_pll_rate_table *rate;
799 struct rockchip_pll_rate_table cur;
802 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
805 drate = clk_hw_get_rate(hw);
806 rate = rockchip_get_pll_settings(pll, drate);
808 /* when no rate setting for the current rate, rely on clk_set_rate */
812 rockchip_rk3399_pll_get_params(pll, &cur);
814 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
816 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
817 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
818 cur.dsmpd, cur.frac);
819 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
820 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
821 rate->dsmpd, rate->frac);
823 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
824 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
825 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
826 struct clk *parent = clk_get_parent(hw->clk);
829 pr_warn("%s: parent of %s not available\n",
830 __func__, __clk_get_name(hw->clk));
834 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
835 __func__, __clk_get_name(hw->clk));
836 rockchip_rk3399_pll_set_params(pll, rate);
840 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
841 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
842 .enable = rockchip_rk3399_pll_enable,
843 .disable = rockchip_rk3399_pll_disable,
844 .is_enabled = rockchip_rk3399_pll_is_enabled,
847 static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
848 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
849 .round_rate = rockchip_pll_round_rate,
850 .set_rate = rockchip_rk3399_pll_set_rate,
851 .enable = rockchip_rk3399_pll_enable,
852 .disable = rockchip_rk3399_pll_disable,
853 .is_enabled = rockchip_rk3399_pll_is_enabled,
854 .init = rockchip_rk3399_pll_init,
858 * Common registering of pll clocks
861 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
862 enum rockchip_pll_type pll_type,
863 const char *name, const char *const *parent_names,
864 u8 num_parents, int con_offset, int grf_lock_offset,
865 int lock_shift, int mode_offset, int mode_shift,
866 struct rockchip_pll_rate_table *rate_table,
869 const char *pll_parents[3];
870 struct clk_init_data init;
871 struct rockchip_clk_pll *pll;
872 struct clk_mux *pll_mux;
873 struct clk *pll_clk, *mux_clk;
876 if (num_parents != 2) {
877 pr_err("%s: needs two parent clocks\n", __func__);
878 return ERR_PTR(-EINVAL);
881 /* name the actual pll */
882 snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
884 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
886 return ERR_PTR(-ENOMEM);
888 /* create the mux on top of the real pll */
889 pll->pll_mux_ops = &clk_mux_ops;
890 pll_mux = &pll->pll_mux;
891 pll_mux->reg = ctx->reg_base + mode_offset;
892 pll_mux->shift = mode_shift;
893 pll_mux->mask = PLL_MODE_MASK;
895 pll_mux->lock = &ctx->lock;
896 pll_mux->hw.init = &init;
898 if (pll_type == pll_rk3036 ||
899 pll_type == pll_rk3066 ||
900 pll_type == pll_rk3399)
901 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
903 /* the actual muxing is xin24m, pll-output, xin32k */
904 pll_parents[0] = parent_names[0];
905 pll_parents[1] = pll_name;
906 pll_parents[2] = parent_names[1];
909 init.flags = CLK_SET_RATE_PARENT;
910 init.ops = pll->pll_mux_ops;
911 init.parent_names = pll_parents;
912 init.num_parents = ARRAY_SIZE(pll_parents);
914 mux_clk = clk_register(NULL, &pll_mux->hw);
918 /* now create the actual pll */
919 init.name = pll_name;
921 /* keep all plls untouched for now */
922 init.flags = CLK_IGNORE_UNUSED;
924 init.parent_names = &parent_names[0];
925 init.num_parents = 1;
930 /* find count of rates in rate_table */
931 for (len = 0; rate_table[len].rate != 0; )
934 pll->rate_count = len;
935 pll->rate_table = kmemdup(rate_table,
937 sizeof(struct rockchip_pll_rate_table),
939 WARN(!pll->rate_table,
940 "%s: could not allocate rate table for %s\n",
946 if (!pll->rate_table)
947 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
949 init.ops = &rockchip_rk3036_pll_clk_ops;
952 if (!pll->rate_table)
953 init.ops = &rockchip_rk3066_pll_clk_norate_ops;
955 init.ops = &rockchip_rk3066_pll_clk_ops;
958 if (!pll->rate_table)
959 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
961 init.ops = &rockchip_rk3399_pll_clk_ops;
964 pr_warn("%s: Unknown pll type for pll clk %s\n",
968 pll->hw.init = &init;
969 pll->type = pll_type;
970 pll->reg_base = ctx->reg_base + con_offset;
971 pll->lock_offset = grf_lock_offset;
972 pll->lock_shift = lock_shift;
973 pll->flags = clk_pll_flags;
974 pll->lock = &ctx->lock;
977 pll_clk = clk_register(NULL, &pll->hw);
978 if (IS_ERR(pll_clk)) {
979 pr_err("%s: failed to register pll clock %s : %ld\n",
980 __func__, name, PTR_ERR(pll_clk));
987 clk_unregister(mux_clk);