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/math64.h>
17 #include <linux/regmap.h>
18 #include <linux/clk.h>
19 #include "clk.h"
20
21 #define PLL_MODE_MASK 0x3
22 #define PLL_MODE_SLOW 0x0
23 #define PLL_MODE_NORM 0x1
24 #define PLL_MODE_DEEP 0x2
25 #define PLL_RK3328_MODE_MASK 0x1
26
27 struct rockchip_clk_pll {
28 struct clk_hw hw;
29
30 struct clk_mux pll_mux;
31 const struct clk_ops *pll_mux_ops;
32
33 struct notifier_block clk_nb;
34
35 void __iomem *reg_base;
36 int lock_offset;
37 unsigned int lock_shift;
38 enum rockchip_pll_type type;
39 u8 flags;
40 const struct rockchip_pll_rate_table *rate_table;
41 unsigned int rate_count;
42 spinlock_t *lock;
43
44 struct rockchip_clk_provider *ctx;
45 };
46
47 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
48 #define to_rockchip_clk_pll_nb(nb) \
49 container_of(nb, struct rockchip_clk_pll, clk_nb)
50
rockchip_get_pll_settings(struct rockchip_clk_pll * pll,unsigned long rate)51 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
52 struct rockchip_clk_pll *pll, unsigned long rate)
53 {
54 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
55 int i;
56
57 for (i = 0; i < pll->rate_count; i++) {
58 if (rate == rate_table[i].rate)
59 return &rate_table[i];
60 }
61
62 return NULL;
63 }
64
rockchip_pll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)65 static int rockchip_pll_determine_rate(struct clk_hw *hw,
66 struct clk_rate_request *req)
67 {
68 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
69 const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
70 int i;
71
72 /* Assuming rate_table is in descending order */
73 for (i = 0; i < pll->rate_count; i++) {
74 if (req->rate >= rate_table[i].rate) {
75 req->rate = rate_table[i].rate;
76
77 return 0;
78 }
79 }
80
81 /* return minimum supported value */
82 req->rate = rate_table[i - 1].rate;
83
84 return 0;
85 }
86
87 /*
88 * Wait for the pll to reach the locked state.
89 * The calling set_rate function is responsible for making sure the
90 * grf regmap is available.
91 */
rockchip_pll_wait_lock(struct rockchip_clk_pll * pll)92 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
93 {
94 struct regmap *grf = pll->ctx->grf;
95 unsigned int val;
96 int ret;
97
98 ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
99 val & BIT(pll->lock_shift), 0, 1000);
100 if (ret)
101 pr_err("%s: timeout waiting for pll to lock\n", __func__);
102
103 return ret;
104 }
105
106 /*
107 * PLL used in RK3036
108 */
109
110 #define RK3036_PLLCON(i) (i * 0x4)
111 #define RK3036_PLLCON0_FBDIV_MASK 0xfff
112 #define RK3036_PLLCON0_FBDIV_SHIFT 0
113 #define RK3036_PLLCON0_POSTDIV1_MASK 0x7
114 #define RK3036_PLLCON0_POSTDIV1_SHIFT 12
115 #define RK3036_PLLCON1_REFDIV_MASK 0x3f
116 #define RK3036_PLLCON1_REFDIV_SHIFT 0
117 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7
118 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6
119 #define RK3036_PLLCON1_LOCK_STATUS BIT(10)
120 #define RK3036_PLLCON1_DSMPD_MASK 0x1
121 #define RK3036_PLLCON1_DSMPD_SHIFT 12
122 #define RK3036_PLLCON1_PWRDOWN BIT(13)
123 #define RK3036_PLLCON2_FRAC_MASK 0xffffff
124 #define RK3036_PLLCON2_FRAC_SHIFT 0
125
rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll * pll)126 static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
127 {
128 u32 pllcon;
129 int ret;
130
131 /*
132 * Lock time typical 250, max 500 input clock cycles @24MHz
133 * So define a very safe maximum of 1000us, meaning 24000 cycles.
134 */
135 ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
136 pllcon,
137 pllcon & RK3036_PLLCON1_LOCK_STATUS,
138 0, 1000);
139 if (ret)
140 pr_err("%s: timeout waiting for pll to lock\n", __func__);
141
142 return ret;
143 }
144
rockchip_rk3036_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)145 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
146 struct rockchip_pll_rate_table *rate)
147 {
148 u32 pllcon;
149
150 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
151 rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
152 & RK3036_PLLCON0_FBDIV_MASK);
153 rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
154 & RK3036_PLLCON0_POSTDIV1_MASK);
155
156 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
157 rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
158 & RK3036_PLLCON1_REFDIV_MASK);
159 rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
160 & RK3036_PLLCON1_POSTDIV2_MASK);
161 rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
162 & RK3036_PLLCON1_DSMPD_MASK);
163
164 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
165 rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
166 & RK3036_PLLCON2_FRAC_MASK);
167 }
168
rockchip_rk3036_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)169 static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
170 unsigned long prate)
171 {
172 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
173 struct rockchip_pll_rate_table cur;
174 u64 rate64 = prate;
175
176 rockchip_rk3036_pll_get_params(pll, &cur);
177
178 rate64 *= cur.fbdiv;
179 do_div(rate64, cur.refdiv);
180
181 if (cur.dsmpd == 0) {
182 /* fractional mode */
183 u64 frac_rate64 = prate * cur.frac;
184
185 do_div(frac_rate64, cur.refdiv);
186 rate64 += frac_rate64 >> 24;
187 }
188
189 do_div(rate64, cur.postdiv1);
190 do_div(rate64, cur.postdiv2);
191
192 return (unsigned long)rate64;
193 }
194
rockchip_rk3036_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)195 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
196 const struct rockchip_pll_rate_table *rate)
197 {
198 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
199 struct clk_mux *pll_mux = &pll->pll_mux;
200 struct rockchip_pll_rate_table cur;
201 u32 pllcon;
202 int rate_change_remuxed = 0;
203 int cur_parent;
204 int ret;
205
206 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
207 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
208 rate->postdiv2, rate->dsmpd, rate->frac);
209
210 rockchip_rk3036_pll_get_params(pll, &cur);
211 cur.rate = 0;
212
213 if (!(pll->flags & ROCKCHIP_PLL_FIXED_MODE)) {
214 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
215 if (cur_parent == PLL_MODE_NORM) {
216 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
217 rate_change_remuxed = 1;
218 }
219 }
220
221 /* update pll values */
222 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
223 RK3036_PLLCON0_FBDIV_SHIFT) |
224 HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
225 RK3036_PLLCON0_POSTDIV1_SHIFT),
226 pll->reg_base + RK3036_PLLCON(0));
227
228 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
229 RK3036_PLLCON1_REFDIV_SHIFT) |
230 HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
231 RK3036_PLLCON1_POSTDIV2_SHIFT) |
232 HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
233 RK3036_PLLCON1_DSMPD_SHIFT),
234 pll->reg_base + RK3036_PLLCON(1));
235
236 /* GPLL CON2 is not HIWORD_MASK */
237 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
238 pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
239 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
240 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
241
242 /* wait for the pll to lock */
243 ret = rockchip_rk3036_pll_wait_lock(pll);
244 if (ret) {
245 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
246 __func__);
247 rockchip_rk3036_pll_set_params(pll, &cur);
248 }
249
250 if (rate_change_remuxed)
251 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
252
253 return ret;
254 }
255
rockchip_rk3036_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)256 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
257 unsigned long prate)
258 {
259 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
260 const struct rockchip_pll_rate_table *rate;
261
262 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
263 __func__, __clk_get_name(hw->clk), drate, prate);
264
265 /* Get required rate settings from table */
266 rate = rockchip_get_pll_settings(pll, drate);
267 if (!rate) {
268 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
269 drate, __clk_get_name(hw->clk));
270 return -EINVAL;
271 }
272
273 return rockchip_rk3036_pll_set_params(pll, rate);
274 }
275
rockchip_rk3036_pll_enable(struct clk_hw * hw)276 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
277 {
278 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
279
280 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
281 pll->reg_base + RK3036_PLLCON(1));
282 rockchip_rk3036_pll_wait_lock(pll);
283
284 return 0;
285 }
286
rockchip_rk3036_pll_disable(struct clk_hw * hw)287 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
288 {
289 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
290
291 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
292 RK3036_PLLCON1_PWRDOWN, 0),
293 pll->reg_base + RK3036_PLLCON(1));
294 }
295
rockchip_rk3036_pll_is_enabled(struct clk_hw * hw)296 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
297 {
298 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
299 u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
300
301 return !(pllcon & RK3036_PLLCON1_PWRDOWN);
302 }
303
rockchip_rk3036_pll_init(struct clk_hw * hw)304 static int rockchip_rk3036_pll_init(struct clk_hw *hw)
305 {
306 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
307 const struct rockchip_pll_rate_table *rate;
308 struct rockchip_pll_rate_table cur;
309 unsigned long drate;
310
311 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
312 return 0;
313
314 drate = clk_hw_get_rate(hw);
315 rate = rockchip_get_pll_settings(pll, drate);
316
317 /* when no rate setting for the current rate, rely on clk_set_rate */
318 if (!rate)
319 return 0;
320
321 rockchip_rk3036_pll_get_params(pll, &cur);
322
323 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
324 drate);
325 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
326 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
327 cur.dsmpd, cur.frac);
328 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
329 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
330 rate->dsmpd, rate->frac);
331
332 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
333 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
334 rate->dsmpd != cur.dsmpd ||
335 (!cur.dsmpd && (rate->frac != cur.frac))) {
336 struct clk *parent = clk_get_parent(hw->clk);
337
338 if (!parent) {
339 pr_warn("%s: parent of %s not available\n",
340 __func__, __clk_get_name(hw->clk));
341 return 0;
342 }
343
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);
347 }
348
349 return 0;
350 }
351
352 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
353 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
354 .enable = rockchip_rk3036_pll_enable,
355 .disable = rockchip_rk3036_pll_disable,
356 .is_enabled = rockchip_rk3036_pll_is_enabled,
357 };
358
359 static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
360 .recalc_rate = rockchip_rk3036_pll_recalc_rate,
361 .determine_rate = rockchip_pll_determine_rate,
362 .set_rate = rockchip_rk3036_pll_set_rate,
363 .enable = rockchip_rk3036_pll_enable,
364 .disable = rockchip_rk3036_pll_disable,
365 .is_enabled = rockchip_rk3036_pll_is_enabled,
366 .init = rockchip_rk3036_pll_init,
367 };
368
369 /*
370 * PLL used in RK3066, RK3188 and RK3288
371 */
372
373 #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1)
374
375 #define RK3066_PLLCON(i) (i * 0x4)
376 #define RK3066_PLLCON0_OD_MASK 0xf
377 #define RK3066_PLLCON0_OD_SHIFT 0
378 #define RK3066_PLLCON0_NR_MASK 0x3f
379 #define RK3066_PLLCON0_NR_SHIFT 8
380 #define RK3066_PLLCON1_NF_MASK 0x1fff
381 #define RK3066_PLLCON1_NF_SHIFT 0
382 #define RK3066_PLLCON2_NB_MASK 0xfff
383 #define RK3066_PLLCON2_NB_SHIFT 0
384 #define RK3066_PLLCON3_RESET (1 << 5)
385 #define RK3066_PLLCON3_PWRDOWN (1 << 1)
386 #define RK3066_PLLCON3_BYPASS (1 << 0)
387
rockchip_rk3066_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)388 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
389 struct rockchip_pll_rate_table *rate)
390 {
391 u32 pllcon;
392
393 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
394 rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
395 & RK3066_PLLCON0_NR_MASK) + 1;
396 rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
397 & RK3066_PLLCON0_OD_MASK) + 1;
398
399 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
400 rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
401 & RK3066_PLLCON1_NF_MASK) + 1;
402
403 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
404 rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
405 & RK3066_PLLCON2_NB_MASK) + 1;
406 }
407
rockchip_rk3066_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)408 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
409 unsigned long prate)
410 {
411 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
412 struct rockchip_pll_rate_table cur;
413 u64 rate64 = prate;
414 u32 pllcon;
415
416 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
417 if (pllcon & RK3066_PLLCON3_BYPASS) {
418 pr_debug("%s: pll %s is bypassed\n", __func__,
419 clk_hw_get_name(hw));
420 return prate;
421 }
422
423 rockchip_rk3066_pll_get_params(pll, &cur);
424
425 rate64 *= cur.nf;
426 do_div(rate64, cur.nr);
427 do_div(rate64, cur.no);
428
429 return (unsigned long)rate64;
430 }
431
rockchip_rk3066_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)432 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
433 const struct rockchip_pll_rate_table *rate)
434 {
435 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
436 struct clk_mux *pll_mux = &pll->pll_mux;
437 struct rockchip_pll_rate_table cur;
438 int rate_change_remuxed = 0;
439 int cur_parent;
440 int ret;
441
442 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
443 __func__, rate->rate, rate->nr, rate->no, rate->nf);
444
445 rockchip_rk3066_pll_get_params(pll, &cur);
446 cur.rate = 0;
447
448 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
449 if (cur_parent == PLL_MODE_NORM) {
450 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
451 rate_change_remuxed = 1;
452 }
453
454 /* enter reset mode */
455 writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
456 pll->reg_base + RK3066_PLLCON(3));
457
458 /* update pll values */
459 writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
460 RK3066_PLLCON0_NR_SHIFT) |
461 HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
462 RK3066_PLLCON0_OD_SHIFT),
463 pll->reg_base + RK3066_PLLCON(0));
464
465 writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
466 RK3066_PLLCON1_NF_SHIFT),
467 pll->reg_base + RK3066_PLLCON(1));
468 writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
469 RK3066_PLLCON2_NB_SHIFT),
470 pll->reg_base + RK3066_PLLCON(2));
471
472 /* leave reset and wait the reset_delay */
473 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
474 pll->reg_base + RK3066_PLLCON(3));
475 udelay(RK3066_PLL_RESET_DELAY(rate->nr));
476
477 /* wait for the pll to lock */
478 ret = rockchip_pll_wait_lock(pll);
479 if (ret) {
480 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
481 __func__);
482 rockchip_rk3066_pll_set_params(pll, &cur);
483 }
484
485 if (rate_change_remuxed)
486 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
487
488 return ret;
489 }
490
rockchip_rk3066_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)491 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
492 unsigned long prate)
493 {
494 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
495 const struct rockchip_pll_rate_table *rate;
496
497 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
498 __func__, clk_hw_get_name(hw), drate, prate);
499
500 /* Get required rate settings from table */
501 rate = rockchip_get_pll_settings(pll, drate);
502 if (!rate) {
503 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
504 drate, clk_hw_get_name(hw));
505 return -EINVAL;
506 }
507
508 return rockchip_rk3066_pll_set_params(pll, rate);
509 }
510
rockchip_rk3066_pll_enable(struct clk_hw * hw)511 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
512 {
513 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
514
515 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
516 pll->reg_base + RK3066_PLLCON(3));
517 rockchip_pll_wait_lock(pll);
518
519 return 0;
520 }
521
rockchip_rk3066_pll_disable(struct clk_hw * hw)522 static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
523 {
524 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
525
526 writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
527 RK3066_PLLCON3_PWRDOWN, 0),
528 pll->reg_base + RK3066_PLLCON(3));
529 }
530
rockchip_rk3066_pll_is_enabled(struct clk_hw * hw)531 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
532 {
533 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
534 u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
535
536 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
537 }
538
rockchip_rk3066_pll_init(struct clk_hw * hw)539 static int rockchip_rk3066_pll_init(struct clk_hw *hw)
540 {
541 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
542 const struct rockchip_pll_rate_table *rate;
543 struct rockchip_pll_rate_table cur;
544 unsigned long drate;
545
546 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
547 return 0;
548
549 drate = clk_hw_get_rate(hw);
550 rate = rockchip_get_pll_settings(pll, drate);
551
552 /* when no rate setting for the current rate, rely on clk_set_rate */
553 if (!rate)
554 return 0;
555
556 rockchip_rk3066_pll_get_params(pll, &cur);
557
558 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
559 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
560 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
561 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
562 || rate->nb != cur.nb) {
563 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
564 __func__, clk_hw_get_name(hw));
565 rockchip_rk3066_pll_set_params(pll, rate);
566 }
567
568 return 0;
569 }
570
571 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
572 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
573 .enable = rockchip_rk3066_pll_enable,
574 .disable = rockchip_rk3066_pll_disable,
575 .is_enabled = rockchip_rk3066_pll_is_enabled,
576 };
577
578 static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
579 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
580 .determine_rate = rockchip_pll_determine_rate,
581 .set_rate = rockchip_rk3066_pll_set_rate,
582 .enable = rockchip_rk3066_pll_enable,
583 .disable = rockchip_rk3066_pll_disable,
584 .is_enabled = rockchip_rk3066_pll_is_enabled,
585 .init = rockchip_rk3066_pll_init,
586 };
587
588 /*
589 * PLL used in RK3399
590 */
591
592 #define RK3399_PLLCON(i) (i * 0x4)
593 #define RK3399_PLLCON0_FBDIV_MASK 0xfff
594 #define RK3399_PLLCON0_FBDIV_SHIFT 0
595 #define RK3399_PLLCON1_REFDIV_MASK 0x3f
596 #define RK3399_PLLCON1_REFDIV_SHIFT 0
597 #define RK3399_PLLCON1_POSTDIV1_MASK 0x7
598 #define RK3399_PLLCON1_POSTDIV1_SHIFT 8
599 #define RK3399_PLLCON1_POSTDIV2_MASK 0x7
600 #define RK3399_PLLCON1_POSTDIV2_SHIFT 12
601 #define RK3399_PLLCON2_FRAC_MASK 0xffffff
602 #define RK3399_PLLCON2_FRAC_SHIFT 0
603 #define RK3399_PLLCON2_LOCK_STATUS BIT(31)
604 #define RK3399_PLLCON3_PWRDOWN BIT(0)
605 #define RK3399_PLLCON3_DSMPD_MASK 0x1
606 #define RK3399_PLLCON3_DSMPD_SHIFT 3
607
rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll * pll)608 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
609 {
610 u32 pllcon;
611 int ret;
612
613 /*
614 * Lock time typical 250, max 500 input clock cycles @24MHz
615 * So define a very safe maximum of 1000us, meaning 24000 cycles.
616 */
617 ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
618 pllcon,
619 pllcon & RK3399_PLLCON2_LOCK_STATUS,
620 0, 1000);
621 if (ret)
622 pr_err("%s: timeout waiting for pll to lock\n", __func__);
623
624 return ret;
625 }
626
rockchip_rk3399_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)627 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
628 struct rockchip_pll_rate_table *rate)
629 {
630 u32 pllcon;
631
632 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
633 rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
634 & RK3399_PLLCON0_FBDIV_MASK);
635
636 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
637 rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
638 & RK3399_PLLCON1_REFDIV_MASK);
639 rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
640 & RK3399_PLLCON1_POSTDIV1_MASK);
641 rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
642 & RK3399_PLLCON1_POSTDIV2_MASK);
643
644 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
645 rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
646 & RK3399_PLLCON2_FRAC_MASK);
647
648 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
649 rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
650 & RK3399_PLLCON3_DSMPD_MASK);
651 }
652
rockchip_rk3399_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)653 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
654 unsigned long prate)
655 {
656 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
657 struct rockchip_pll_rate_table cur;
658 u64 rate64 = prate;
659
660 rockchip_rk3399_pll_get_params(pll, &cur);
661
662 rate64 *= cur.fbdiv;
663 do_div(rate64, cur.refdiv);
664
665 if (cur.dsmpd == 0) {
666 /* fractional mode */
667 u64 frac_rate64 = prate * cur.frac;
668
669 do_div(frac_rate64, cur.refdiv);
670 rate64 += frac_rate64 >> 24;
671 }
672
673 do_div(rate64, cur.postdiv1);
674 do_div(rate64, cur.postdiv2);
675
676 return (unsigned long)rate64;
677 }
678
rockchip_rk3399_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)679 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
680 const struct rockchip_pll_rate_table *rate)
681 {
682 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
683 struct clk_mux *pll_mux = &pll->pll_mux;
684 struct rockchip_pll_rate_table cur;
685 u32 pllcon;
686 int rate_change_remuxed = 0;
687 int cur_parent;
688 int ret;
689
690 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
691 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
692 rate->postdiv2, rate->dsmpd, rate->frac);
693
694 rockchip_rk3399_pll_get_params(pll, &cur);
695 cur.rate = 0;
696
697 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
698 if (cur_parent == PLL_MODE_NORM) {
699 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
700 rate_change_remuxed = 1;
701 }
702
703 /* update pll values */
704 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
705 RK3399_PLLCON0_FBDIV_SHIFT),
706 pll->reg_base + RK3399_PLLCON(0));
707
708 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
709 RK3399_PLLCON1_REFDIV_SHIFT) |
710 HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
711 RK3399_PLLCON1_POSTDIV1_SHIFT) |
712 HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
713 RK3399_PLLCON1_POSTDIV2_SHIFT),
714 pll->reg_base + RK3399_PLLCON(1));
715
716 /* xPLL CON2 is not HIWORD_MASK */
717 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
718 pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
719 pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
720 writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
721
722 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
723 RK3399_PLLCON3_DSMPD_SHIFT),
724 pll->reg_base + RK3399_PLLCON(3));
725
726 /* wait for the pll to lock */
727 ret = rockchip_rk3399_pll_wait_lock(pll);
728 if (ret) {
729 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
730 __func__);
731 rockchip_rk3399_pll_set_params(pll, &cur);
732 }
733
734 if (rate_change_remuxed)
735 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
736
737 return ret;
738 }
739
rockchip_rk3399_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)740 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
741 unsigned long prate)
742 {
743 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
744 const struct rockchip_pll_rate_table *rate;
745
746 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
747 __func__, __clk_get_name(hw->clk), drate, prate);
748
749 /* Get required rate settings from table */
750 rate = rockchip_get_pll_settings(pll, drate);
751 if (!rate) {
752 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
753 drate, __clk_get_name(hw->clk));
754 return -EINVAL;
755 }
756
757 return rockchip_rk3399_pll_set_params(pll, rate);
758 }
759
rockchip_rk3399_pll_enable(struct clk_hw * hw)760 static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
761 {
762 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
763
764 writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
765 pll->reg_base + RK3399_PLLCON(3));
766 rockchip_rk3399_pll_wait_lock(pll);
767
768 return 0;
769 }
770
rockchip_rk3399_pll_disable(struct clk_hw * hw)771 static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
772 {
773 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
774
775 writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
776 RK3399_PLLCON3_PWRDOWN, 0),
777 pll->reg_base + RK3399_PLLCON(3));
778 }
779
rockchip_rk3399_pll_is_enabled(struct clk_hw * hw)780 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
781 {
782 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
783 u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
784
785 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
786 }
787
rockchip_rk3399_pll_init(struct clk_hw * hw)788 static int rockchip_rk3399_pll_init(struct clk_hw *hw)
789 {
790 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
791 const struct rockchip_pll_rate_table *rate;
792 struct rockchip_pll_rate_table cur;
793 unsigned long drate;
794
795 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
796 return 0;
797
798 drate = clk_hw_get_rate(hw);
799 rate = rockchip_get_pll_settings(pll, drate);
800
801 /* when no rate setting for the current rate, rely on clk_set_rate */
802 if (!rate)
803 return 0;
804
805 rockchip_rk3399_pll_get_params(pll, &cur);
806
807 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
808 drate);
809 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
810 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
811 cur.dsmpd, cur.frac);
812 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
813 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
814 rate->dsmpd, rate->frac);
815
816 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
817 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
818 rate->dsmpd != cur.dsmpd ||
819 (!cur.dsmpd && (rate->frac != cur.frac))) {
820 struct clk *parent = clk_get_parent(hw->clk);
821
822 if (!parent) {
823 pr_warn("%s: parent of %s not available\n",
824 __func__, __clk_get_name(hw->clk));
825 return 0;
826 }
827
828 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
829 __func__, __clk_get_name(hw->clk));
830 rockchip_rk3399_pll_set_params(pll, rate);
831 }
832
833 return 0;
834 }
835
836 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
837 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
838 .enable = rockchip_rk3399_pll_enable,
839 .disable = rockchip_rk3399_pll_disable,
840 .is_enabled = rockchip_rk3399_pll_is_enabled,
841 };
842
843 static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
844 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
845 .determine_rate = rockchip_pll_determine_rate,
846 .set_rate = rockchip_rk3399_pll_set_rate,
847 .enable = rockchip_rk3399_pll_enable,
848 .disable = rockchip_rk3399_pll_disable,
849 .is_enabled = rockchip_rk3399_pll_is_enabled,
850 .init = rockchip_rk3399_pll_init,
851 };
852
853 /*
854 * PLL used in RK3588
855 */
856
857 #define RK3588_PLLCON(i) (i * 0x4)
858 #define RK3588_PLLCON0_M_MASK 0x3ff
859 #define RK3588_PLLCON0_M_SHIFT 0
860 #define RK3588_PLLCON1_P_MASK 0x3f
861 #define RK3588_PLLCON1_P_SHIFT 0
862 #define RK3588_PLLCON1_S_MASK 0x7
863 #define RK3588_PLLCON1_S_SHIFT 6
864 #define RK3588_PLLCON2_K_MASK 0xffff
865 #define RK3588_PLLCON2_K_SHIFT 0
866 #define RK3588_PLLCON1_PWRDOWN BIT(13)
867 #define RK3588_PLLCON6_LOCK_STATUS BIT(15)
868
rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll * pll)869 static int rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll *pll)
870 {
871 u32 pllcon;
872 int ret;
873
874 /*
875 * Lock time typical 250, max 500 input clock cycles @24MHz
876 * So define a very safe maximum of 1000us, meaning 24000 cycles.
877 */
878 ret = readl_relaxed_poll_timeout(pll->reg_base + RK3588_PLLCON(6),
879 pllcon,
880 pllcon & RK3588_PLLCON6_LOCK_STATUS,
881 0, 1000);
882 if (ret)
883 pr_err("%s: timeout waiting for pll to lock\n", __func__);
884
885 return ret;
886 }
887
rockchip_rk3588_pll_get_params(struct rockchip_clk_pll * pll,struct rockchip_pll_rate_table * rate)888 static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,
889 struct rockchip_pll_rate_table *rate)
890 {
891 u32 pllcon;
892
893 pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(0));
894 rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT) & RK3588_PLLCON0_M_MASK);
895
896 pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));
897 rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT) & RK3588_PLLCON1_P_MASK);
898 rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT) & RK3588_PLLCON1_S_MASK);
899
900 pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(2));
901 rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT) & RK3588_PLLCON2_K_MASK);
902 }
903
904 /*
905 * 2250 MHz <= Fvco <= 4500 MHz
906 * For Fvco > 3 GHz: period jitter +-1% frac PLL, +-0.75% int PLL
907 * For Fvco < 3 GHz: period jitter +-2% frac PLL, +-1.50% int PLL
908 * Fvco = ((m + k / 65536) * Fin) / p
909 * Fout = ((m + k / 65536) * Fin) / (p * 2^s)
910 * -32768 <= k <= 32767 (only available in frac PLLs, not int PLLs)
911 */
rockchip_rk3588_pll_recalc_rate(struct clk_hw * hw,unsigned long prate)912 static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
913 {
914 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
915 struct rockchip_pll_rate_table cur;
916 u64 rate64 = prate, postdiv;
917
918 rockchip_rk3588_pll_get_params(pll, &cur);
919
920 rate64 *= cur.m;
921 do_div(rate64, cur.p);
922
923 if (cur.k) {
924 /* fractional mode */
925 s64 frac_rate64 = (s64)prate * cur.k;
926
927 postdiv = cur.p * 65536;
928 rate64 += div_s64(frac_rate64, postdiv);
929 }
930 rate64 = rate64 >> cur.s;
931
932 if (pll->type == pll_rk3588_ddr)
933 return (unsigned long)rate64 * 2;
934 else
935 return (unsigned long)rate64;
936 }
937
rockchip_rk3588_pll_set_params(struct rockchip_clk_pll * pll,const struct rockchip_pll_rate_table * rate)938 static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
939 const struct rockchip_pll_rate_table *rate)
940 {
941 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
942 struct clk_mux *pll_mux = &pll->pll_mux;
943 struct rockchip_pll_rate_table cur;
944 int rate_change_remuxed = 0;
945 int cur_parent;
946 int ret;
947
948 pr_debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
949 __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
950
951 rockchip_rk3588_pll_get_params(pll, &cur);
952 cur.rate = 0;
953
954 if (pll->type == pll_rk3588) {
955 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
956 if (cur_parent == PLL_MODE_NORM) {
957 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
958 rate_change_remuxed = 1;
959 }
960 }
961
962 /* set pll power down */
963 writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
964 RK3588_PLLCON1_PWRDOWN, 0),
965 pll->reg_base + RK3399_PLLCON(1));
966
967 /* update pll values */
968 writel_relaxed(HIWORD_UPDATE(rate->m, RK3588_PLLCON0_M_MASK, RK3588_PLLCON0_M_SHIFT),
969 pll->reg_base + RK3399_PLLCON(0));
970
971 writel_relaxed(HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK, RK3588_PLLCON1_P_SHIFT) |
972 HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK, RK3588_PLLCON1_S_SHIFT),
973 pll->reg_base + RK3399_PLLCON(1));
974
975 writel_relaxed(HIWORD_UPDATE(rate->k, RK3588_PLLCON2_K_MASK, RK3588_PLLCON2_K_SHIFT),
976 pll->reg_base + RK3399_PLLCON(2));
977
978 /* set pll power up */
979 writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),
980 pll->reg_base + RK3588_PLLCON(1));
981
982 /* wait for the pll to lock */
983 ret = rockchip_rk3588_pll_wait_lock(pll);
984 if (ret) {
985 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
986 __func__);
987 rockchip_rk3588_pll_set_params(pll, &cur);
988 }
989
990 if ((pll->type == pll_rk3588) && rate_change_remuxed)
991 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
992
993 return ret;
994 }
995
rockchip_rk3588_pll_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)996 static int rockchip_rk3588_pll_set_rate(struct clk_hw *hw, unsigned long drate,
997 unsigned long prate)
998 {
999 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1000 const struct rockchip_pll_rate_table *rate;
1001
1002 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
1003 __func__, __clk_get_name(hw->clk), drate, prate);
1004
1005 /* Get required rate settings from table */
1006 rate = rockchip_get_pll_settings(pll, drate);
1007 if (!rate) {
1008 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1009 drate, __clk_get_name(hw->clk));
1010 return -EINVAL;
1011 }
1012
1013 return rockchip_rk3588_pll_set_params(pll, rate);
1014 }
1015
rockchip_rk3588_pll_enable(struct clk_hw * hw)1016 static int rockchip_rk3588_pll_enable(struct clk_hw *hw)
1017 {
1018 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1019
1020 writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),
1021 pll->reg_base + RK3588_PLLCON(1));
1022 rockchip_rk3588_pll_wait_lock(pll);
1023
1024 return 0;
1025 }
1026
rockchip_rk3588_pll_disable(struct clk_hw * hw)1027 static void rockchip_rk3588_pll_disable(struct clk_hw *hw)
1028 {
1029 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1030
1031 writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0),
1032 pll->reg_base + RK3588_PLLCON(1));
1033 }
1034
rockchip_rk3588_pll_is_enabled(struct clk_hw * hw)1035 static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)
1036 {
1037 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1038 u32 pllcon = readl(pll->reg_base + RK3588_PLLCON(1));
1039
1040 return !(pllcon & RK3588_PLLCON1_PWRDOWN);
1041 }
1042
1043 static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {
1044 .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1045 .enable = rockchip_rk3588_pll_enable,
1046 .disable = rockchip_rk3588_pll_disable,
1047 .is_enabled = rockchip_rk3588_pll_is_enabled,
1048 };
1049
1050 static const struct clk_ops rockchip_rk3588_pll_clk_ops = {
1051 .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1052 .determine_rate = rockchip_pll_determine_rate,
1053 .set_rate = rockchip_rk3588_pll_set_rate,
1054 .enable = rockchip_rk3588_pll_enable,
1055 .disable = rockchip_rk3588_pll_disable,
1056 .is_enabled = rockchip_rk3588_pll_is_enabled,
1057 };
1058
1059 /*
1060 * Common registering of pll clocks
1061 */
1062
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)1063 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
1064 enum rockchip_pll_type pll_type,
1065 const char *name, const char *const *parent_names,
1066 u8 num_parents, int con_offset, int grf_lock_offset,
1067 int lock_shift, int mode_offset, int mode_shift,
1068 struct rockchip_pll_rate_table *rate_table,
1069 unsigned long flags, u8 clk_pll_flags)
1070 {
1071 const char *pll_parents[3];
1072 struct clk_init_data init;
1073 struct rockchip_clk_pll *pll;
1074 struct clk_mux *pll_mux;
1075 struct clk *pll_clk, *mux_clk;
1076 char pll_name[20];
1077
1078 if ((pll_type != pll_rk3328 && num_parents != 2) ||
1079 (pll_type == pll_rk3328 && num_parents != 1)) {
1080 pr_err("%s: needs two parent clocks\n", __func__);
1081 return ERR_PTR(-EINVAL);
1082 }
1083
1084 /* name the actual pll */
1085 snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
1086
1087 pll = kzalloc_obj(*pll);
1088 if (!pll)
1089 return ERR_PTR(-ENOMEM);
1090
1091 /* create the mux on top of the real pll */
1092 pll->pll_mux_ops = &clk_mux_ops;
1093 pll_mux = &pll->pll_mux;
1094 pll_mux->reg = ctx->reg_base + mode_offset;
1095 pll_mux->shift = mode_shift;
1096 if (pll_type == pll_rk3328)
1097 pll_mux->mask = PLL_RK3328_MODE_MASK;
1098 else
1099 pll_mux->mask = PLL_MODE_MASK;
1100 pll_mux->flags = 0;
1101 pll_mux->lock = &ctx->lock;
1102 pll_mux->hw.init = &init;
1103
1104 if (pll_type == pll_rk3036 ||
1105 pll_type == pll_rk3066 ||
1106 pll_type == pll_rk3328 ||
1107 pll_type == pll_rk3399 ||
1108 pll_type == pll_rk3588)
1109 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
1110
1111 /* the actual muxing is xin24m, pll-output, xin32k */
1112 pll_parents[0] = parent_names[0];
1113 pll_parents[1] = pll_name;
1114 pll_parents[2] = parent_names[1];
1115
1116 init.name = name;
1117 init.flags = CLK_SET_RATE_PARENT;
1118 init.ops = pll->pll_mux_ops;
1119 init.parent_names = pll_parents;
1120 if (pll_type == pll_rk3328)
1121 init.num_parents = 2;
1122 else
1123 init.num_parents = ARRAY_SIZE(pll_parents);
1124
1125 mux_clk = clk_register(NULL, &pll_mux->hw);
1126 if (IS_ERR(mux_clk))
1127 goto err_mux;
1128
1129 /* now create the actual pll */
1130 init.name = pll_name;
1131
1132 /* keep all plls untouched for now */
1133 init.flags = flags | CLK_IGNORE_UNUSED;
1134
1135 init.parent_names = &parent_names[0];
1136 init.num_parents = 1;
1137
1138 if (rate_table) {
1139 int len;
1140
1141 /* find count of rates in rate_table */
1142 for (len = 0; rate_table[len].rate != 0; )
1143 len++;
1144
1145 pll->rate_count = len;
1146 pll->rate_table = kmemdup_array(rate_table,
1147 pll->rate_count,
1148 sizeof(*pll->rate_table),
1149 GFP_KERNEL);
1150 WARN(!pll->rate_table,
1151 "%s: could not allocate rate table for %s\n",
1152 __func__, name);
1153 }
1154
1155 switch (pll_type) {
1156 case pll_rk3036:
1157 case pll_rk3328:
1158 if (!pll->rate_table)
1159 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
1160 else
1161 init.ops = &rockchip_rk3036_pll_clk_ops;
1162 break;
1163 case pll_rk3066:
1164 if (!pll->rate_table || IS_ERR(ctx->grf))
1165 init.ops = &rockchip_rk3066_pll_clk_norate_ops;
1166 else
1167 init.ops = &rockchip_rk3066_pll_clk_ops;
1168 break;
1169 case pll_rk3399:
1170 if (!pll->rate_table)
1171 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
1172 else
1173 init.ops = &rockchip_rk3399_pll_clk_ops;
1174 break;
1175 case pll_rk3588:
1176 case pll_rk3588_core:
1177 case pll_rk3588_ddr:
1178 if (!pll->rate_table)
1179 init.ops = &rockchip_rk3588_pll_clk_norate_ops;
1180 else
1181 init.ops = &rockchip_rk3588_pll_clk_ops;
1182 init.flags = flags;
1183 break;
1184 default:
1185 pr_warn("%s: Unknown pll type for pll clk %s\n",
1186 __func__, name);
1187 }
1188
1189 pll->hw.init = &init;
1190 pll->type = pll_type;
1191 pll->reg_base = ctx->reg_base + con_offset;
1192 pll->lock_offset = grf_lock_offset;
1193 pll->lock_shift = lock_shift;
1194 pll->flags = clk_pll_flags;
1195 pll->lock = &ctx->lock;
1196 pll->ctx = ctx;
1197
1198 pll_clk = clk_register(NULL, &pll->hw);
1199 if (IS_ERR(pll_clk)) {
1200 pr_err("%s: failed to register pll clock %s : %ld\n",
1201 __func__, name, PTR_ERR(pll_clk));
1202 goto err_pll;
1203 }
1204
1205 return mux_clk;
1206
1207 err_pll:
1208 kfree(pll->rate_table);
1209 clk_unregister(mux_clk);
1210 mux_clk = pll_clk;
1211 err_mux:
1212 kfree(pll);
1213 return mux_clk;
1214 }
1215