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