xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_px30.c (revision b8fa3d2a17dce6006a8a5f46cbc978a19a3fdf82)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_px30.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/px30-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 enum {
23 	VCO_MAX_HZ	= 3200U * 1000000,
24 	VCO_MIN_HZ	= 800 * 1000000,
25 	OUTPUT_MAX_HZ	= 3200U * 1000000,
26 	OUTPUT_MIN_HZ	= 24 * 1000000,
27 };
28 
29 #define PX30_VOP_PLL_LIMIT			600000000
30 
31 #define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
32 			_postdiv2, _dsmpd, _frac)		\
33 {								\
34 	.rate	= _rate##U,					\
35 	.fbdiv = _fbdiv,					\
36 	.postdiv1 = _postdiv1,					\
37 	.refdiv = _refdiv,					\
38 	.postdiv2 = _postdiv2,					\
39 	.dsmpd = _dsmpd,					\
40 	.frac = _frac,						\
41 }
42 
43 #define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
44 {								\
45 	.rate	= _rate##U,					\
46 	.aclk_div = _aclk_div,					\
47 	.pclk_div = _pclk_div,					\
48 }
49 
50 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
51 
52 #define PX30_CLK_DUMP(_id, _name, _iscru)	\
53 {						\
54 	.id = _id,				\
55 	.name = _name,				\
56 	.is_cru = _iscru,			\
57 }
58 
59 static struct pll_rate_table px30_pll_rates[] = {
60 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
61 	PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
62 	PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
63 	PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
64 	PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
65 	PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
66 	PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
67 	PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
68 };
69 
70 static const struct px30_clk_info clks_dump[] = {
71 	PX30_CLK_DUMP(PLL_APLL, "apll", true),
72 	PX30_CLK_DUMP(PLL_DPLL, "dpll", true),
73 	PX30_CLK_DUMP(PLL_CPLL, "cpll", true),
74 	PX30_CLK_DUMP(PLL_NPLL, "npll", true),
75 	PX30_CLK_DUMP(PLL_GPLL, "gpll", false),
76 	PX30_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true),
77 	PX30_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true),
78 	PX30_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true),
79 	PX30_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true),
80 	PX30_CLK_DUMP(HCLK_PERI_PRE, "hclk_peri", true),
81 	PX30_CLK_DUMP(PCLK_PMU_PRE, "pclk_pmu", false),
82 };
83 
84 static struct cpu_rate_table px30_cpu_rates[] = {
85 	PX30_CPUCLK_RATE(1200000000, 1, 5),
86 	PX30_CPUCLK_RATE(1008000000, 1, 5),
87 	PX30_CPUCLK_RATE(816000000, 1, 3),
88 	PX30_CPUCLK_RATE(600000000, 1, 3),
89 };
90 
91 static u8 pll_mode_shift[PLL_COUNT] = {
92 	APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
93 	NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
94 };
95 static u32 pll_mode_mask[PLL_COUNT] = {
96 	APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
97 	NPLL_MODE_MASK, GPLL_MODE_MASK
98 };
99 
100 static struct pll_rate_table auto_table;
101 
102 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
103 				   enum px30_pll_id pll_id);
104 
105 static struct pll_rate_table *pll_clk_set_by_auto(u32 drate)
106 {
107 	struct pll_rate_table *rate = &auto_table;
108 	u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
109 	u32 postdiv1, postdiv2 = 1;
110 	u32 fref_khz;
111 	u32 diff_khz, best_diff_khz;
112 	const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
113 	const u32 max_postdiv1 = 7, max_postdiv2 = 7;
114 	u32 vco_khz;
115 	u32 rate_khz = drate / KHz;
116 
117 	if (!drate) {
118 		printf("%s: the frequency can't be 0 Hz\n", __func__);
119 		return NULL;
120 	}
121 
122 	postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz);
123 	if (postdiv1 > max_postdiv1) {
124 		postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
125 		postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
126 	}
127 
128 	vco_khz = rate_khz * postdiv1 * postdiv2;
129 
130 	if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
131 	    postdiv2 > max_postdiv2) {
132 		printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
133 		       __func__, rate_khz);
134 		return NULL;
135 	}
136 
137 	rate->postdiv1 = postdiv1;
138 	rate->postdiv2 = postdiv2;
139 
140 	best_diff_khz = vco_khz;
141 	for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
142 		fref_khz = ref_khz / refdiv;
143 
144 		fbdiv = vco_khz / fref_khz;
145 		if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
146 			continue;
147 		diff_khz = vco_khz - fbdiv * fref_khz;
148 		if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
149 			fbdiv++;
150 			diff_khz = fref_khz - diff_khz;
151 		}
152 
153 		if (diff_khz >= best_diff_khz)
154 			continue;
155 
156 		best_diff_khz = diff_khz;
157 		rate->refdiv = refdiv;
158 		rate->fbdiv = fbdiv;
159 	}
160 
161 	if (best_diff_khz > 4 * (MHz / KHz)) {
162 		printf("%s: Failed to match output frequency %u bestis %u Hz\n",
163 		       __func__, rate_khz,
164 		       best_diff_khz * KHz);
165 		return NULL;
166 	}
167 
168 	return rate;
169 }
170 
171 static const struct pll_rate_table *get_pll_settings(unsigned long rate)
172 {
173 	unsigned int rate_count = ARRAY_SIZE(px30_pll_rates);
174 	int i;
175 
176 	for (i = 0; i < rate_count; i++) {
177 		if (rate == px30_pll_rates[i].rate)
178 			return &px30_pll_rates[i];
179 	}
180 
181 	return pll_clk_set_by_auto(rate);
182 }
183 
184 static const struct cpu_rate_table *get_cpu_settings(unsigned long rate)
185 {
186 	unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates);
187 	int i;
188 
189 	for (i = 0; i < rate_count; i++) {
190 		if (rate == px30_cpu_rates[i].rate)
191 			return &px30_cpu_rates[i];
192 	}
193 
194 	return NULL;
195 }
196 
197 /*
198  * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
199  * Formulas also embedded within the Fractional PLL Verilog model:
200  * If DSMPD = 1 (DSM is disabled, "integer mode")
201  * FOUTVCO = FREF / REFDIV * FBDIV
202  * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
203  * Where:
204  * FOUTVCO = Fractional PLL non-divided output frequency
205  * FOUTPOSTDIV = Fractional PLL divided output frequency
206  *               (output of second post divider)
207  * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
208  * REFDIV = Fractional PLL input reference clock divider
209  * FBDIV = Integer value programmed into feedback divide
210  *
211  */
212 static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode,
213 			 enum px30_pll_id pll_id,
214 			 unsigned long drate)
215 {
216 	const struct pll_rate_table *rate;
217 	uint vco_hz, output_hz;
218 
219 	rate = get_pll_settings(drate);
220 	if (!rate) {
221 		printf("%s unsupport rate\n", __func__);
222 		return -EINVAL;
223 	}
224 
225 	/* All PLLs have same VCO and output frequency range restrictions. */
226 	vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000;
227 	output_hz = vco_hz / rate->postdiv1 / rate->postdiv2;
228 
229 	debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
230 	      pll, rate->fbdiv, rate->refdiv, rate->postdiv1,
231 	      rate->postdiv2, vco_hz, output_hz);
232 	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
233 	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
234 
235 	/*
236 	 * When power on or changing PLL setting,
237 	 * we must force PLL into slow mode to ensure output stable clock.
238 	 */
239 	rk_clrsetreg(mode, pll_mode_mask[pll_id],
240 		     PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
241 
242 	/* use integer mode */
243 	rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
244 	/* Power down */
245 	rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
246 
247 	rk_clrsetreg(&pll->con0,
248 		     PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
249 		     (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv);
250 	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
251 		     (rate->postdiv2 << PLL_POSTDIV2_SHIFT |
252 		     rate->refdiv << PLL_REFDIV_SHIFT));
253 
254 	/* Power Up */
255 	rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
256 
257 	/* waiting for pll lock */
258 	while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
259 		udelay(1);
260 
261 	rk_clrsetreg(mode, pll_mode_mask[pll_id],
262 		     PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
263 
264 	return 0;
265 }
266 
267 static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode,
268 				   enum px30_pll_id pll_id)
269 {
270 	u32 refdiv, fbdiv, postdiv1, postdiv2;
271 	u32 con, shift, mask;
272 
273 	con = readl(mode);
274 	shift = pll_mode_shift[pll_id];
275 	mask = pll_mode_mask[pll_id];
276 
277 	switch ((con & mask) >> shift) {
278 	case PLLMUX_FROM_XIN24M:
279 		return OSC_HZ;
280 	case PLLMUX_FROM_PLL:
281 		/* normal mode */
282 		con = readl(&pll->con0);
283 		postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
284 		fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
285 		con = readl(&pll->con1);
286 		postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
287 		refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
288 		return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
289 	case PLLMUX_FROM_RTC32K:
290 	default:
291 		return 32768;
292 	}
293 }
294 
295 static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id)
296 {
297 	struct px30_cru *cru = priv->cru;
298 	u32 div, con;
299 
300 	switch (clk_id) {
301 	case SCLK_I2C0:
302 		con = readl(&cru->clksel_con[49]);
303 		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
304 		break;
305 	case SCLK_I2C1:
306 		con = readl(&cru->clksel_con[49]);
307 		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
308 		break;
309 	case SCLK_I2C2:
310 		con = readl(&cru->clksel_con[50]);
311 		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
312 		break;
313 	case SCLK_I2C3:
314 		con = readl(&cru->clksel_con[50]);
315 		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
316 		break;
317 	default:
318 		printf("do not support this i2c bus\n");
319 		return -EINVAL;
320 	}
321 
322 	return DIV_TO_RATE(priv->gpll_hz, div);
323 }
324 
325 static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
326 {
327 	struct px30_cru *cru = priv->cru;
328 	int src_clk_div;
329 
330 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
331 	assert(src_clk_div - 1 <= 127);
332 
333 	switch (clk_id) {
334 	case SCLK_I2C0:
335 		rk_clrsetreg(&cru->clksel_con[49],
336 			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
337 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
338 			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
339 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
340 		break;
341 	case SCLK_I2C1:
342 		rk_clrsetreg(&cru->clksel_con[49],
343 			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
344 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
345 			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
346 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
347 		break;
348 	case SCLK_I2C2:
349 		rk_clrsetreg(&cru->clksel_con[50],
350 			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
351 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
352 			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
353 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
354 		break;
355 	case SCLK_I2C3:
356 		rk_clrsetreg(&cru->clksel_con[50],
357 			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
358 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
359 			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
360 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
361 		break;
362 	default:
363 		printf("do not support this i2c bus\n");
364 		return -EINVAL;
365 	}
366 
367 	return px30_i2c_get_clk(priv, clk_id);
368 }
369 
370 static ulong px30_nandc_get_clk(struct px30_clk_priv *priv)
371 {
372 	struct px30_cru *cru = priv->cru;
373 	u32 div, con;
374 
375 	con = readl(&cru->clksel_con[15]);
376 	div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT;
377 
378 	return DIV_TO_RATE(priv->gpll_hz, div);
379 }
380 
381 static ulong px30_nandc_set_clk(struct px30_clk_priv *priv,
382 				ulong set_rate)
383 {
384 	struct px30_cru *cru = priv->cru;
385 	int src_clk_div;
386 
387 	/* Select nandc source from GPLL by default */
388 	/* nandc clock defaulg div 2 internal, need provide double in cru */
389 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
390 	assert(src_clk_div - 1 <= 31);
391 
392 	rk_clrsetreg(&cru->clksel_con[15],
393 		     NANDC_CLK_SEL_MASK | NANDC_PLL_MASK |
394 		     NANDC_DIV_MASK,
395 		     NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT |
396 		     NANDC_SEL_GPLL << NANDC_PLL_SHIFT |
397 		     (src_clk_div - 1) << NANDC_DIV_SHIFT);
398 
399 	return px30_nandc_get_clk(priv);
400 }
401 
402 static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id)
403 {
404 	struct px30_cru *cru = priv->cru;
405 	u32 div, con, con_id;
406 
407 	switch (clk_id) {
408 	case HCLK_SDMMC:
409 	case SCLK_SDMMC:
410 		con_id = 16;
411 		break;
412 	case HCLK_EMMC:
413 	case SCLK_EMMC:
414 	case SCLK_EMMC_SAMPLE:
415 		con_id = 20;
416 		break;
417 	default:
418 		return -EINVAL;
419 	}
420 
421 	con = readl(&cru->clksel_con[con_id]);
422 	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
423 
424 	if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
425 	    == EMMC_SEL_24M)
426 		return DIV_TO_RATE(OSC_HZ, div) / 2;
427 	else
428 		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
429 
430 }
431 
432 static ulong px30_mmc_set_clk(struct px30_clk_priv *priv,
433 			      ulong clk_id, ulong set_rate)
434 {
435 	struct px30_cru *cru = priv->cru;
436 	int src_clk_div;
437 	u32 con_id;
438 
439 	switch (clk_id) {
440 	case HCLK_SDMMC:
441 	case SCLK_SDMMC:
442 		con_id = 16;
443 		break;
444 	case HCLK_EMMC:
445 	case SCLK_EMMC:
446 		con_id = 20;
447 		break;
448 	default:
449 		return -EINVAL;
450 	}
451 
452 	/* Select clk_sdmmc/emmc source from GPLL by default */
453 	/* mmc clock defaulg div 2 internal, need provide double in cru */
454 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
455 
456 	if (src_clk_div > 127) {
457 		/* use 24MHz source for 400KHz clock */
458 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
459 		rk_clrsetreg(&cru->clksel_con[con_id],
460 			     EMMC_PLL_MASK | EMMC_DIV_MASK,
461 			     EMMC_SEL_24M << EMMC_PLL_SHIFT |
462 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
463 	} else {
464 		rk_clrsetreg(&cru->clksel_con[con_id],
465 			     EMMC_PLL_MASK | EMMC_DIV_MASK,
466 			     EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
467 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
468 	}
469 	rk_clrsetreg(&cru->clksel_con[con_id +1], EMMC_CLK_SEL_MASK,
470 		     EMMC_CLK_SEL_EMMC);
471 
472 	return px30_mmc_get_clk(priv, clk_id);
473 }
474 
475 static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id)
476 {
477 	struct px30_cru *cru = priv->cru;
478 	u32 div, con;
479 
480 	switch (clk_id) {
481 	case SCLK_PWM0:
482 		con = readl(&cru->clksel_con[52]);
483 		div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
484 		break;
485 	case SCLK_PWM1:
486 		con = readl(&cru->clksel_con[52]);
487 		div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
488 		break;
489 	default:
490 		printf("do not support this pwm bus\n");
491 		return -EINVAL;
492 	}
493 
494 	return DIV_TO_RATE(priv->gpll_hz, div);
495 }
496 
497 static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
498 {
499 	struct px30_cru *cru = priv->cru;
500 	int src_clk_div;
501 
502 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
503 	assert(src_clk_div - 1 <= 127);
504 
505 	switch (clk_id) {
506 	case SCLK_PWM0:
507 		rk_clrsetreg(&cru->clksel_con[52],
508 			     CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
509 			     CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
510 			     (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
511 			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
512 		break;
513 	case SCLK_PWM1:
514 		rk_clrsetreg(&cru->clksel_con[52],
515 			     CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
516 			     CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
517 			     (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
518 			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
519 		break;
520 	default:
521 		printf("do not support this pwm bus\n");
522 		return -EINVAL;
523 	}
524 
525 	return px30_pwm_get_clk(priv, clk_id);
526 }
527 
528 static ulong px30_saradc_get_clk(struct px30_clk_priv *priv)
529 {
530 	struct px30_cru *cru = priv->cru;
531 	u32 div, con;
532 
533 	con = readl(&cru->clksel_con[55]);
534 	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
535 
536 	return DIV_TO_RATE(OSC_HZ, div);
537 }
538 
539 static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz)
540 {
541 	struct px30_cru *cru = priv->cru;
542 	int src_clk_div;
543 
544 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
545 	assert(src_clk_div - 1 <= 2047);
546 
547 	rk_clrsetreg(&cru->clksel_con[55],
548 		     CLK_SARADC_DIV_CON_MASK,
549 		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
550 
551 	return px30_saradc_get_clk(priv);
552 }
553 
554 static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id)
555 {
556 	struct px30_cru *cru = priv->cru;
557 	u32 div, con;
558 
559 	switch (clk_id) {
560 	case SCLK_SPI0:
561 		con = readl(&cru->clksel_con[53]);
562 		div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
563 		break;
564 	case SCLK_SPI1:
565 		con = readl(&cru->clksel_con[53]);
566 		div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
567 		break;
568 	default:
569 		printf("do not support this pwm bus\n");
570 		return -EINVAL;
571 	}
572 
573 	return DIV_TO_RATE(priv->gpll_hz, div);
574 }
575 
576 static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
577 {
578 	struct px30_cru *cru = priv->cru;
579 	int src_clk_div;
580 
581 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
582 	assert(src_clk_div - 1 <= 127);
583 
584 	switch (clk_id) {
585 	case SCLK_SPI0:
586 		rk_clrsetreg(&cru->clksel_con[53],
587 			     CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
588 			     CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
589 			     (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
590 			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
591 		break;
592 	case SCLK_SPI1:
593 		rk_clrsetreg(&cru->clksel_con[53],
594 			     CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
595 			     CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
596 			     (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
597 			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
598 		break;
599 	default:
600 		printf("do not support this pwm bus\n");
601 		return -EINVAL;
602 	}
603 
604 	return px30_spi_get_clk(priv, clk_id);
605 }
606 
607 static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id)
608 {
609 	struct px30_cru *cru = priv->cru;
610 	u32 div, con, parent;
611 
612 	switch (clk_id) {
613 	case ACLK_VOPB:
614 	case ACLK_VOPL:
615 		con = readl(&cru->clksel_con[3]);
616 		div = con & ACLK_VO_DIV_MASK;
617 		parent = priv->gpll_hz;
618 		break;
619 	case DCLK_VOPB:
620 		con = readl(&cru->clksel_con[5]);
621 		div = con & DCLK_VOPB_DIV_MASK;
622 		parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL);
623 		break;
624 	case DCLK_VOPL:
625 		con = readl(&cru->clksel_con[8]);
626 		div = con & DCLK_VOPL_DIV_MASK;
627 		parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL);
628 		break;
629 	default:
630 		return -ENOENT;
631 	}
632 
633 	return DIV_TO_RATE(parent, div);
634 }
635 
636 static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
637 {
638 	struct px30_cru *cru = priv->cru;
639 	ulong npll_hz;
640 	int src_clk_div;
641 
642 	switch (clk_id) {
643 	case ACLK_VOPB:
644 	case ACLK_VOPL:
645 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
646 		assert(src_clk_div - 1 <= 31);
647 		rk_clrsetreg(&cru->clksel_con[3],
648 			     ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
649 			     ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
650 			     (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
651 		break;
652 	case DCLK_VOPB:
653 		if (hz < PX30_VOP_PLL_LIMIT)
654 			src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
655 		else
656 			src_clk_div = 1;
657 		assert(src_clk_div - 1 <= 255);
658 		rkclk_set_pll(&cru->pll[CPLL], &cru->mode, CPLL, hz * src_clk_div);
659 		rk_clrsetreg(&cru->clksel_con[5],
660 			     DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
661 			     DCLK_VOPB_DIV_MASK,
662 			     DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
663 			     DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
664 			     (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT);
665 		break;
666 	case DCLK_VOPL:
667 		npll_hz = px30_clk_get_pll_rate(priv, NPLL);
668 		if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz && npll_hz % hz == 0) {
669 			src_clk_div = npll_hz / hz;
670 			assert(src_clk_div - 1 <= 255);
671 		} else {
672 			if (hz < PX30_VOP_PLL_LIMIT)
673 				src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
674 			else
675 				src_clk_div = 1;
676 			assert(src_clk_div - 1 <= 255);
677 			rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL, hz * src_clk_div);
678 		}
679 		rk_clrsetreg(&cru->clksel_con[8],
680 			     DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK |
681 			     DCLK_VOPL_DIV_MASK,
682 			     DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT |
683 			     DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT |
684 			     (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT);
685 		break;
686 	default:
687 		printf("do not support this vop freq\n");
688 		return -EINVAL;
689 	}
690 
691 	return px30_vop_get_clk(priv, clk_id);
692 }
693 
694 static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id)
695 {
696 	struct px30_cru *cru = priv->cru;
697 	u32 div, con, parent;
698 
699 	switch (clk_id) {
700 	case ACLK_BUS_PRE:
701 		con = readl(&cru->clksel_con[23]);
702 		div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
703 		parent = priv->gpll_hz;
704 		break;
705 	case HCLK_BUS_PRE:
706 		con = readl(&cru->clksel_con[24]);
707 		div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
708 		parent = priv->gpll_hz;
709 		break;
710 	case PCLK_BUS_PRE:
711 		parent = px30_bus_get_clk(priv, ACLK_BUS_PRE);
712 		con = readl(&cru->clksel_con[24]);
713 		div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
714 		break;
715 	default:
716 		return -ENOENT;
717 	}
718 
719 	return DIV_TO_RATE(parent, div);
720 }
721 
722 static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id,
723 			      ulong hz)
724 {
725 	struct px30_cru *cru = priv->cru;
726 	int src_clk_div;
727 
728 	/*
729 	 * select gpll as pd_bus bus clock source and
730 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
731 	 */
732 	switch (clk_id) {
733 	case ACLK_BUS_PRE:
734 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
735 		assert(src_clk_div - 1 <= 31);
736 		rk_clrsetreg(&cru->clksel_con[23],
737 			     BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
738 			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
739 			     (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
740 		break;
741 	case HCLK_BUS_PRE:
742 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
743 		assert(src_clk_div - 1 <= 31);
744 		rk_clrsetreg(&cru->clksel_con[24],
745 			     BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
746 			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
747 			     (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
748 		break;
749 	case PCLK_BUS_PRE:
750 		src_clk_div =
751 			DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz);
752 		assert(src_clk_div - 1 <= 3);
753 		rk_clrsetreg(&cru->clksel_con[24],
754 			     BUS_PCLK_DIV_MASK,
755 			     (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
756 		break;
757 	default:
758 		printf("do not support this bus freq\n");
759 		return -EINVAL;
760 	}
761 
762 	return px30_bus_get_clk(priv, clk_id);
763 }
764 
765 static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id)
766 {
767 	struct px30_cru *cru = priv->cru;
768 	u32 div, con, parent;
769 
770 	switch (clk_id) {
771 	case ACLK_PERI_PRE:
772 		con = readl(&cru->clksel_con[14]);
773 		div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
774 		parent = priv->gpll_hz;
775 		break;
776 	case HCLK_PERI_PRE:
777 		con = readl(&cru->clksel_con[14]);
778 		div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
779 		parent = priv->gpll_hz;
780 		break;
781 	default:
782 		return -ENOENT;
783 	}
784 
785 	return DIV_TO_RATE(parent, div);
786 }
787 
788 static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id,
789 			       ulong hz)
790 {
791 	struct px30_cru *cru = priv->cru;
792 	int src_clk_div;
793 
794 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
795 	assert(src_clk_div - 1 <= 31);
796 
797 	/*
798 	 * select gpll as pd_peri bus clock source and
799 	 * set up dependent divisors for HCLK and ACLK clocks.
800 	 */
801 	switch (clk_id) {
802 	case ACLK_PERI_PRE:
803 		rk_clrsetreg(&cru->clksel_con[14],
804 			     PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
805 			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
806 			     (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
807 		break;
808 	case HCLK_PERI_PRE:
809 		rk_clrsetreg(&cru->clksel_con[14],
810 			     PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
811 			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
812 			     (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
813 		break;
814 	default:
815 		printf("do not support this peri freq\n");
816 		return -EINVAL;
817 	}
818 
819 	return px30_peri_get_clk(priv, clk_id);
820 }
821 
822 static int px30_clk_get_gpll_rate(ulong *rate)
823 {
824 	struct udevice *pmucru_dev;
825 	struct px30_pmuclk_priv *priv;
826 	int ret;
827 
828 	ret = uclass_get_device_by_driver(UCLASS_CLK,
829 					  DM_GET_DRIVER(rockchip_px30_pmucru),
830 					  &pmucru_dev);
831 	if (ret) {
832 		printf("%s: could not find pmucru device\n", __func__);
833 		return ret;
834 	}
835 	priv = dev_get_priv(pmucru_dev);
836 	*rate =  priv->gpll_hz;
837 
838 	return 0;
839 }
840 
841 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
842 				   enum px30_pll_id pll_id)
843 {
844 	struct px30_cru *cru = priv->cru;
845 
846 	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
847 }
848 
849 static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv,
850 				   enum px30_pll_id pll_id, ulong hz)
851 {
852 	struct px30_cru *cru = priv->cru;
853 
854 	if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz))
855 		return -EINVAL;
856 	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
857 }
858 
859 static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz)
860 {
861 	struct px30_cru *cru = priv->cru;
862 	const struct cpu_rate_table *rate;
863 	ulong old_rate;
864 
865 	rate = get_cpu_settings(hz);
866 	if (!rate) {
867 		printf("%s unsupport rate\n", __func__);
868 		return -EINVAL;
869 	}
870 
871 	/*
872 	 * select apll as cpu/core clock pll source and
873 	 * set up dependent divisors for PERI and ACLK clocks.
874 	 * core hz : apll = 1:1
875 	 */
876 	old_rate = px30_clk_get_pll_rate(priv, APLL);
877 	if (old_rate > hz) {
878 		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
879 			return -EINVAL;
880 		rk_clrsetreg(&cru->clksel_con[0],
881 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
882 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
883 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
884 			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
885 			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
886 			     0 << CORE_DIV_CON_SHIFT);
887 	} else if (old_rate < hz) {
888 		rk_clrsetreg(&cru->clksel_con[0],
889 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
890 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
891 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
892 			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
893 			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
894 			     0 << CORE_DIV_CON_SHIFT);
895 		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
896 			return -EINVAL;
897 	}
898 
899 	return px30_clk_get_pll_rate(priv, APLL);
900 }
901 
902 static ulong px30_clk_get_rate(struct clk *clk)
903 {
904 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
905 	ulong rate = 0;
906 
907 	if (!priv->gpll_hz && clk->id > ARMCLK) {
908 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
909 		return -ENOENT;
910 	}
911 
912 	debug("%s %ld\n", __func__, clk->id);
913 	switch (clk->id) {
914 	case PLL_APLL:
915 		rate = px30_clk_get_pll_rate(priv, APLL);
916 		break;
917 	case PLL_DPLL:
918 		rate = px30_clk_get_pll_rate(priv, DPLL);
919 		break;
920 	case PLL_CPLL:
921 		rate = px30_clk_get_pll_rate(priv, CPLL);
922 		break;
923 	case PLL_NPLL:
924 		rate = px30_clk_get_pll_rate(priv, NPLL);
925 		break;
926 	case ARMCLK:
927 		rate = px30_clk_get_pll_rate(priv, APLL);
928 		break;
929 	case HCLK_SDMMC:
930 	case HCLK_EMMC:
931 	case SCLK_SDMMC:
932 	case SCLK_EMMC:
933 	case SCLK_EMMC_SAMPLE:
934 		rate = px30_mmc_get_clk(priv, clk->id);
935 		break;
936 	case SCLK_I2C0:
937 	case SCLK_I2C1:
938 	case SCLK_I2C2:
939 	case SCLK_I2C3:
940 		rate = px30_i2c_get_clk(priv, clk->id);
941 		break;
942 	case SCLK_PWM0:
943 	case SCLK_PWM1:
944 		rate = px30_pwm_get_clk(priv, clk->id);
945 		break;
946 	case SCLK_SARADC:
947 		rate = px30_saradc_get_clk(priv);
948 		break;
949 	case SCLK_SPI0:
950 	case SCLK_SPI1:
951 		rate = px30_spi_get_clk(priv, clk->id);
952 		break;
953 	case ACLK_VOPB:
954 	case ACLK_VOPL:
955 	case DCLK_VOPB:
956 	case DCLK_VOPL:
957 		rate = px30_vop_get_clk(priv, clk->id);
958 		break;
959 	case ACLK_BUS_PRE:
960 	case HCLK_BUS_PRE:
961 	case PCLK_BUS_PRE:
962 		rate = px30_bus_get_clk(priv, clk->id);
963 		break;
964 	case ACLK_PERI_PRE:
965 	case HCLK_PERI_PRE:
966 		rate = px30_peri_get_clk(priv, clk->id);
967 		break;
968 	default:
969 		return -ENOENT;
970 	}
971 
972 	return rate;
973 }
974 
975 static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
976 {
977 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
978 	ulong ret = 0;
979 
980 	if (!priv->gpll_hz && clk->id > ARMCLK) {
981 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
982 		return -ENOENT;
983 	}
984 
985 	debug("%s %ld %ld\n", __func__, clk->id, rate);
986 	switch (clk->id) {
987 	case PLL_NPLL:
988 		ret = px30_clk_set_pll_rate(priv, NPLL, rate);
989 		break;
990 	case ARMCLK:
991 		if (priv->armclk_hz)
992 			px30_armclk_set_clk(priv, rate);
993 		priv->armclk_hz = rate;
994 		break;
995 	case HCLK_SDMMC:
996 	case HCLK_EMMC:
997 	case SCLK_SDMMC:
998 	case SCLK_EMMC:
999 		ret = px30_mmc_set_clk(priv, clk->id, rate);
1000 		break;
1001 	case SCLK_I2C0:
1002 	case SCLK_I2C1:
1003 	case SCLK_I2C2:
1004 	case SCLK_I2C3:
1005 		ret = px30_i2c_set_clk(priv, clk->id, rate);
1006 		break;
1007 	case SCLK_PWM0:
1008 	case SCLK_PWM1:
1009 		ret = px30_pwm_set_clk(priv, clk->id, rate);
1010 		break;
1011 	case SCLK_SARADC:
1012 		ret = px30_saradc_set_clk(priv, rate);
1013 		break;
1014 	case SCLK_SPI0:
1015 	case SCLK_SPI1:
1016 		ret = px30_spi_set_clk(priv, clk->id, rate);
1017 		break;
1018 	case ACLK_VOPB:
1019 	case ACLK_VOPL:
1020 	case DCLK_VOPB:
1021 	case DCLK_VOPL:
1022 		ret = px30_vop_set_clk(priv, clk->id, rate);
1023 		break;
1024 	case ACLK_BUS_PRE:
1025 	case HCLK_BUS_PRE:
1026 	case PCLK_BUS_PRE:
1027 		ret = px30_bus_set_clk(priv, clk->id, rate);
1028 		break;
1029 	case ACLK_PERI_PRE:
1030 	case HCLK_PERI_PRE:
1031 		ret = px30_peri_set_clk(priv, clk->id, rate);
1032 		break;
1033 	default:
1034 		return -ENOENT;
1035 	}
1036 
1037 	return ret;
1038 }
1039 
1040 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1041 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1042 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1043 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1044 
1045 #define PSECS_PER_SEC 1000000000000LL
1046 /*
1047  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1048  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1049  */
1050 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1051 
1052 int rockchip_mmc_get_phase(struct clk *clk)
1053 {
1054 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1055 	struct px30_cru *cru = priv->cru;
1056 	u32 raw_value, delay_num;
1057 	u16 degrees = 0;
1058 	ulong rate;
1059 
1060 	rate = px30_clk_get_rate(clk);
1061 
1062 	if (rate < 0)
1063 		return rate;
1064 
1065 	if (clk->id == SCLK_EMMC_SAMPLE)
1066 		raw_value = readl(&cru->emmc_con[1]);
1067 	else
1068 		raw_value = readl(&cru->sdmmc_con[1]);
1069 
1070 	raw_value >>= 1;
1071 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1072 
1073 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1074 		/* degrees/delaynum * 10000 */
1075 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1076 					36 * (rate / 1000000);
1077 
1078 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1079 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1080 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1081 	}
1082 
1083 	return degrees % 360;
1084 }
1085 
1086 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees)
1087 {
1088 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1089 	struct px30_cru *cru = priv->cru;
1090 	u8 nineties, remainder, delay_num;
1091 	u32 raw_value, delay;
1092 	ulong rate;
1093 
1094 	rate = px30_clk_get_rate(clk);
1095 
1096 	if (rate < 0)
1097 		return rate;
1098 
1099 	nineties = degrees / 90;
1100 	remainder = (degrees % 90);
1101 
1102 	/*
1103 	 * Convert to delay; do a little extra work to make sure we
1104 	 * don't overflow 32-bit / 64-bit numbers.
1105 	 */
1106 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1107 	delay *= remainder;
1108 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1109 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1110 
1111 	delay_num = (u8)min_t(u32, delay, 255);
1112 
1113 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1114 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1115 	raw_value |= nineties;
1116 
1117 	raw_value <<= 1;
1118 	if (clk->id == SCLK_EMMC_SAMPLE)
1119 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1120 	else
1121 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1122 
1123 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1124 	      degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk));
1125 
1126 	return 0;
1127 }
1128 
1129 static int px30_clk_get_phase(struct clk *clk)
1130 {
1131 	int ret;
1132 
1133 	debug("%s %ld\n", __func__, clk->id);
1134 	switch (clk->id) {
1135 	case SCLK_EMMC_SAMPLE:
1136 	case SCLK_SDMMC_SAMPLE:
1137 		ret = rockchip_mmc_get_phase(clk);
1138 		break;
1139 	default:
1140 		return -ENOENT;
1141 	}
1142 
1143 	return ret;
1144 }
1145 
1146 static int px30_clk_set_phase(struct clk *clk, int degrees)
1147 {
1148 	int ret;
1149 
1150 	debug("%s %ld\n", __func__, clk->id);
1151 	switch (clk->id) {
1152 	case SCLK_EMMC_SAMPLE:
1153 	case SCLK_SDMMC_SAMPLE:
1154 		ret = rockchip_mmc_set_phase(clk, degrees);
1155 		break;
1156 	default:
1157 		return -ENOENT;
1158 	}
1159 
1160 	return ret;
1161 }
1162 
1163 static struct clk_ops px30_clk_ops = {
1164 	.get_rate = px30_clk_get_rate,
1165 	.set_rate = px30_clk_set_rate,
1166 	.get_phase	= px30_clk_get_phase,
1167 	.set_phase	= px30_clk_set_phase,
1168 };
1169 
1170 static int px30_clk_probe(struct udevice *dev)
1171 {
1172 	struct px30_clk_priv *priv = dev_get_priv(dev);
1173 	int ret;
1174 
1175 	if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ) {
1176 		ret = px30_armclk_set_clk(priv, APLL_HZ);
1177 		if (ret < 0)
1178 			printf("%s failed to set armclk rate\n", __func__);
1179 	}
1180 
1181 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1182 	ret = clk_set_defaults(dev);
1183 	if (ret)
1184 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1185 
1186 	if (!priv->gpll_hz) {
1187 		ret = px30_clk_get_gpll_rate(&priv->gpll_hz);
1188 		if (ret) {
1189 			printf("%s failed to get gpll rate\n", __func__);
1190 			return ret;
1191 		}
1192 	}
1193 
1194 	return 0;
1195 }
1196 
1197 static int px30_clk_ofdata_to_platdata(struct udevice *dev)
1198 {
1199 	struct px30_clk_priv *priv = dev_get_priv(dev);
1200 
1201 	priv->cru = dev_read_addr_ptr(dev);
1202 
1203 	return 0;
1204 }
1205 
1206 static int px30_clk_bind(struct udevice *dev)
1207 {
1208 	int ret;
1209 	struct udevice *sys_child, *sf_child;
1210 	struct sysreset_reg *priv;
1211 	struct softreset_reg *sf_priv;
1212 
1213 	/* The reset driver does not have a device node, so bind it here */
1214 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1215 				 &sys_child);
1216 	if (ret) {
1217 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1218 	} else {
1219 		priv = malloc(sizeof(struct sysreset_reg));
1220 		priv->glb_srst_fst_value = offsetof(struct px30_cru,
1221 						    glb_srst_fst);
1222 		priv->glb_srst_snd_value = offsetof(struct px30_cru,
1223 						    glb_srst_snd);
1224 		sys_child->priv = priv;
1225 	}
1226 
1227 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1228 					 dev_ofnode(dev), &sf_child);
1229 	if (ret) {
1230 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1231 	} else {
1232 		sf_priv = malloc(sizeof(struct softreset_reg));
1233 		sf_priv->sf_reset_offset = offsetof(struct px30_cru,
1234 						    softrst_con[0]);
1235 		sf_priv->sf_reset_num = 12;
1236 		sf_child->priv = sf_priv;
1237 	}
1238 
1239 	return 0;
1240 }
1241 
1242 static const struct udevice_id px30_clk_ids[] = {
1243 	{ .compatible = "rockchip,px30-cru" },
1244 	{ }
1245 };
1246 
1247 U_BOOT_DRIVER(rockchip_px30_cru) = {
1248 	.name		= "rockchip_px30_cru",
1249 	.id		= UCLASS_CLK,
1250 	.of_match	= px30_clk_ids,
1251 	.priv_auto_alloc_size = sizeof(struct px30_clk_priv),
1252 	.ofdata_to_platdata = px30_clk_ofdata_to_platdata,
1253 	.ops		= &px30_clk_ops,
1254 	.bind		= px30_clk_bind,
1255 	.probe		= px30_clk_probe,
1256 };
1257 
1258 static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv)
1259 {
1260 	struct px30_pmucru *pmucru = priv->pmucru;
1261 	u32 div, con;
1262 
1263 	con = readl(&pmucru->pmu_clksel_con[0]);
1264 	div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT;
1265 
1266 	return DIV_TO_RATE(priv->gpll_hz, div);
1267 }
1268 
1269 static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
1270 {
1271 	struct px30_pmucru *pmucru = priv->pmucru;
1272 	int src_clk_div;
1273 
1274 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
1275 	assert(src_clk_div - 1 <= 31);
1276 
1277 	rk_clrsetreg(&pmucru->pmu_clksel_con[0],
1278 		     CLK_PMU_PCLK_DIV_MASK,
1279 		     (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT);
1280 
1281 	return px30_pclk_pmu_get_pmuclk(priv);
1282 }
1283 
1284 static ulong px30_gpll_get_pmuclk(struct px30_pmuclk_priv *priv)
1285 {
1286 	struct px30_pmucru *pmucru = priv->pmucru;
1287 
1288 	return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL);
1289 }
1290 
1291 static ulong px30_gpll_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
1292 {
1293 	struct udevice *cru_dev;
1294 	struct px30_clk_priv *cru_priv;
1295 	struct px30_pmucru *pmucru = priv->pmucru;
1296 	u32 div;
1297 	ulong emmc_rate, sdmmc_rate, nandc_rate;
1298 	ulong aclk_bus_rate, hclk_bus_rate, pclk_bus_rate;
1299 	ulong aclk_peri_rate, hclk_peri_rate, pclk_pmu_rate;
1300 	int ret;
1301 
1302 	ret = uclass_get_device_by_name(UCLASS_CLK,
1303 					"clock-controller@ff2b0000",
1304 					 &cru_dev);
1305 	if (ret) {
1306 		printf("%s failed to get cru device\n", __func__);
1307 		return ret;
1308 	}
1309 	cru_priv = dev_get_priv(cru_dev);
1310 
1311 	if (priv->gpll_hz == hz)
1312 		return priv->gpll_hz;
1313 
1314 	cru_priv->gpll_hz = priv->gpll_hz;
1315 	div = DIV_ROUND_UP(hz, priv->gpll_hz);
1316 
1317 	/* save clock rate */
1318 	aclk_bus_rate = px30_bus_get_clk(cru_priv, ACLK_BUS_PRE);
1319 	hclk_bus_rate = px30_bus_get_clk(cru_priv, HCLK_BUS_PRE);
1320 	pclk_bus_rate = px30_bus_get_clk(cru_priv, PCLK_BUS_PRE);
1321 	aclk_peri_rate = px30_peri_get_clk(cru_priv, ACLK_PERI_PRE);
1322 	hclk_peri_rate = px30_peri_get_clk(cru_priv, HCLK_PERI_PRE);
1323 	pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv);
1324 	debug("%s aclk_bus=%lu, hclk_bus=%lu, pclk_bus=%lu\n", __func__,
1325 	      aclk_bus_rate, hclk_bus_rate, pclk_bus_rate);
1326 	debug("%s aclk_peri=%lu, hclk_peri=%lu, pclk_pmu=%lu\n", __func__,
1327 	      aclk_peri_rate, hclk_peri_rate, pclk_pmu_rate);
1328 	emmc_rate = px30_mmc_get_clk(cru_priv, SCLK_EMMC);
1329 	sdmmc_rate = px30_mmc_get_clk(cru_priv, SCLK_SDMMC);
1330 	nandc_rate = px30_nandc_get_clk(cru_priv);
1331 	debug("%s emmc=%lu, sdmmc=%lu, nandc=%lu\n", __func__,
1332 	      emmc_rate, sdmmc_rate, nandc_rate);
1333 
1334 	/* avoid rate too large, reduce rate first */
1335 	px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, aclk_bus_rate / div);
1336 	px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, hclk_bus_rate / div);
1337 	px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, pclk_bus_rate / div);
1338 	px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, aclk_peri_rate / div);
1339 	px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, hclk_peri_rate / div);
1340 	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div);
1341 
1342 	px30_mmc_set_clk(cru_priv, SCLK_EMMC, emmc_rate / div);
1343 	px30_mmc_set_clk(cru_priv, SCLK_SDMMC, sdmmc_rate / div);
1344 	px30_nandc_set_clk(cru_priv, nandc_rate / div);
1345 
1346 	/* change gpll rate */
1347 	rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz);
1348 	priv->gpll_hz = px30_gpll_get_pmuclk(priv);
1349 	cru_priv->gpll_hz = priv->gpll_hz;
1350 
1351 	/* restore clock rate */
1352 	px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, aclk_bus_rate);
1353 	px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, hclk_bus_rate);
1354 	px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, pclk_bus_rate);
1355 	px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, aclk_peri_rate);
1356 	px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, hclk_peri_rate);
1357 	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate);
1358 
1359 	px30_mmc_set_clk(cru_priv, SCLK_EMMC, emmc_rate);
1360 	px30_mmc_set_clk(cru_priv, SCLK_SDMMC, sdmmc_rate);
1361 	px30_nandc_set_clk(cru_priv, nandc_rate);
1362 
1363 	return priv->gpll_hz;
1364 }
1365 
1366 static ulong px30_pmuclk_get_rate(struct clk *clk)
1367 {
1368 	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1369 	ulong rate = 0;
1370 
1371 	debug("%s %ld\n", __func__, clk->id);
1372 	switch (clk->id) {
1373 	case PLL_GPLL:
1374 		rate = px30_gpll_get_pmuclk(priv);
1375 		break;
1376 	case PCLK_PMU_PRE:
1377 		rate = px30_pclk_pmu_get_pmuclk(priv);
1378 		break;
1379 	default:
1380 		return -ENOENT;
1381 	}
1382 
1383 	return rate;
1384 }
1385 
1386 static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate)
1387 {
1388 	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1389 	ulong ret = 0;
1390 
1391 	debug("%s %ld %ld\n", __func__, clk->id, rate);
1392 	switch (clk->id) {
1393 	case PLL_GPLL:
1394 		ret = px30_gpll_set_pmuclk(priv, rate);
1395 		break;
1396 	case PCLK_PMU_PRE:
1397 		ret = px30_pclk_pmu_set_pmuclk(priv, rate);
1398 		break;
1399 	default:
1400 		return -ENOENT;
1401 	}
1402 
1403 	return ret;
1404 }
1405 
1406 static struct clk_ops px30_pmuclk_ops = {
1407 	.get_rate = px30_pmuclk_get_rate,
1408 	.set_rate = px30_pmuclk_set_rate,
1409 };
1410 
1411 static void px30_clk_init(struct px30_pmuclk_priv *priv)
1412 {
1413 	struct udevice *cru_dev;
1414 	struct px30_clk_priv *cru_priv;
1415 	ulong npll_hz;
1416 	int ret;
1417 
1418 	priv->gpll_hz = px30_gpll_get_pmuclk(priv);
1419 	if (priv->gpll_hz != GPLL_HZ) {
1420 		ret = px30_gpll_set_pmuclk(priv, GPLL_HZ);
1421 		if (ret < 0)
1422 			printf("%s failed to set gpll rate\n", __func__);
1423 	}
1424 
1425 	ret = uclass_get_device_by_name(UCLASS_CLK,
1426 					"clock-controller@ff2b0000",
1427 					 &cru_dev);
1428 	if (ret) {
1429 		printf("%s failed to get cru device\n", __func__);
1430 		return;
1431 	}
1432 	cru_priv = dev_get_priv(cru_dev);
1433 	cru_priv->gpll_hz = priv->gpll_hz;
1434 
1435 	npll_hz = px30_clk_get_pll_rate(cru_priv, NPLL);
1436 	if (npll_hz != NPLL_HZ) {
1437 		ret = px30_clk_set_pll_rate(cru_priv, NPLL, NPLL_HZ);
1438 		if (ret < 0)
1439 			printf("%s failed to set npll rate\n", __func__);
1440 	}
1441 
1442 	px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1443 	px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, HCLK_BUS_HZ);
1444 	px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, PCLK_BUS_HZ);
1445 	px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1446 	px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, HCLK_PERI_HZ);
1447 	px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ);
1448 }
1449 
1450 static int px30_pmuclk_probe(struct udevice *dev)
1451 {
1452 	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1453 	int ret;
1454 
1455 	px30_clk_init(priv);
1456 
1457 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1458 	ret = clk_set_defaults(dev);
1459 	if (ret)
1460 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1461 
1462 	return 0;
1463 }
1464 
1465 static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev)
1466 {
1467 	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1468 
1469 	priv->pmucru = dev_read_addr_ptr(dev);
1470 
1471 	return 0;
1472 }
1473 
1474 static const struct udevice_id px30_pmuclk_ids[] = {
1475 	{ .compatible = "rockchip,px30-pmucru" },
1476 	{ }
1477 };
1478 
1479 U_BOOT_DRIVER(rockchip_px30_pmucru) = {
1480 	.name		= "rockchip_px30_pmucru",
1481 	.id		= UCLASS_CLK,
1482 	.of_match	= px30_pmuclk_ids,
1483 	.priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv),
1484 	.ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata,
1485 	.ops		= &px30_pmuclk_ops,
1486 	.probe		= px30_pmuclk_probe,
1487 };
1488 
1489 /**
1490  * soc_clk_dump() - Print clock frequencies
1491  * Returns zero on success
1492  *
1493  * Implementation for the clk dump command.
1494  */
1495 int soc_clk_dump(void)
1496 {
1497 	struct udevice *cru_dev, *pmucru_dev;
1498 	const struct px30_clk_info *clk_dump;
1499 	struct clk clk;
1500 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1501 	unsigned long rate;
1502 	int i, ret;
1503 
1504 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1505 					  DM_GET_DRIVER(rockchip_px30_cru),
1506 					  &cru_dev);
1507 	if (ret) {
1508 		printf("%s failed to get cru device\n", __func__);
1509 		return ret;
1510 	}
1511 
1512 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1513 					  DM_GET_DRIVER(rockchip_px30_pmucru),
1514 					  &pmucru_dev);
1515 	if (ret) {
1516 		printf("%s failed to get pmucru device\n", __func__);
1517 		return ret;
1518 	}
1519 
1520 	printf("CLK:\n");
1521 	for (i = 0; i < clk_count; i++) {
1522 		clk_dump = &clks_dump[i];
1523 		if (clk_dump->name) {
1524 			clk.id = clk_dump->id;
1525 			if (clk_dump->is_cru)
1526 				ret = clk_request(cru_dev, &clk);
1527 			else
1528 				ret = clk_request(pmucru_dev, &clk);
1529 			if (ret < 0)
1530 				return ret;
1531 
1532 			rate = clk_get_rate(&clk);
1533 			clk_free(&clk);
1534 			if (i == 0) {
1535 				if (rate < 0)
1536 					printf("%s %s\n", clk_dump->name,
1537 					       "unknown");
1538 				else
1539 					printf("%s %lu KHz\n", clk_dump->name,
1540 					       rate / 1000);
1541 			} else {
1542 				if (rate < 0)
1543 					printf("%s %s\n", clk_dump->name,
1544 					       "unknown");
1545 				else
1546 					printf("%s %lu KHz\n", clk_dump->name,
1547 					       rate / 1000);
1548 			}
1549 		}
1550 	}
1551 
1552 	return 0;
1553 }
1554