xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_px30.c (revision 83ab7b4937c098a3febc8f361a6be16f28ae16aa)
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 DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
30 
31 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
32 	.refdiv = _refdiv,\
33 	.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
34 	.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
35 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 1, 1);
36 
37 static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1);
38 static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1);
39 
40 static const struct pll_div *apll_cfgs[] = {
41 	[APLL_816_MHZ] = &apll_816_cfg,
42 	[APLL_600_MHZ] = &apll_600_cfg,
43 };
44 
45 static u8 pll_mode_shift[PLL_COUNT] = {
46 	APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
47 	NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
48 };
49 static u32 pll_mode_mask[PLL_COUNT] = {
50 	APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
51 	NPLL_MODE_MASK, GPLL_MODE_MASK
52 };
53 
54 /*
55  *  the div restructions of pll in integer mode, these are defined in
56  *  * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
57  */
58 #define PLL_DIV_MIN	16
59 #define PLL_DIV_MAX	3200
60 
61 /*
62  * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
63  * Formulas also embedded within the Fractional PLL Verilog model:
64  * If DSMPD = 1 (DSM is disabled, "integer mode")
65  * FOUTVCO = FREF / REFDIV * FBDIV
66  * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
67  * Where:
68  * FOUTVCO = Fractional PLL non-divided output frequency
69  * FOUTPOSTDIV = Fractional PLL divided output frequency
70  *               (output of second post divider)
71  * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
72  * REFDIV = Fractional PLL input reference clock divider
73  * FBDIV = Integer value programmed into feedback divide
74  *
75  */
76 static void rkclk_set_pll(struct px30_cru *cru, enum px30_pll_id pll_id,
77 			  const struct pll_div *div)
78 {
79 	struct px30_pll *pll;
80 	unsigned int *mode;
81 	/* All PLLs have same VCO and output frequency range restrictions. */
82 	uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
83 	uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
84 
85 	if (pll_id == GPLL) {
86 		pll = &cru->gpll;
87 		mode = &cru->pmu_mode;
88 	} else {
89 		pll = &cru->pll[pll_id];
90 		mode = &cru->mode;
91 	};
92 
93 	debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
94 	      pll, div->fbdiv, div->refdiv, div->postdiv1,
95 	      div->postdiv2, vco_hz, output_hz);
96 	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
97 	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
98 
99 	/*
100 	 * When power on or changing PLL setting,
101 	 * we must force PLL into slow mode to ensure output stable clock.
102 	 */
103 	rk_clrsetreg(mode, pll_mode_mask[pll_id],
104 		     PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
105 
106 	/* use integer mode */
107 	rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
108 	/* Power down */
109 	rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
110 
111 	rk_clrsetreg(&pll->con0,
112 		     PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
113 		     (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
114 	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
115 		     (div->postdiv2 << PLL_POSTDIV2_SHIFT |
116 		     div->refdiv << PLL_REFDIV_SHIFT));
117 
118 	/* Power Up */
119 	rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
120 
121 	/* waiting for pll lock */
122 	while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
123 		udelay(1);
124 
125 	rk_clrsetreg(mode, pll_mode_mask[pll_id],
126 		     PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
127 
128 	return;
129 }
130 
131 static uint32_t rkclk_pll_get_rate(struct px30_cru *cru,
132 				   enum px30_pll_id pll_id)
133 {
134 	u32 refdiv, fbdiv, postdiv1, postdiv2;
135 	u32 con;
136 	struct px30_pll *pll;
137 	uint shift;
138 	uint mask;
139 
140 	if (pll_id == GPLL) {
141 		pll = &cru->gpll;
142 		con = readl(&cru->pmu_mode);
143 	} else {
144 		pll = &cru->pll[pll_id];
145 		con = readl(&cru->mode);
146 	}
147 
148 	shift = pll_mode_shift[pll_id];
149 	mask = pll_mode_mask[pll_id];
150 
151 	switch ((con & mask) >> shift) {
152 	case PLLMUX_FROM_XIN24M:
153 		return OSC_HZ;
154 	case PLLMUX_FROM_PLL:
155 		/* normal mode */
156 		con = readl(&pll->con0);
157 		postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
158 		fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
159 		con = readl(&pll->con1);
160 		postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
161 		refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
162 		return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
163 	case PLLMUX_FROM_RTC32K:
164 	default:
165 		return 32768;
166 	}
167 }
168 
169 static int pll_para_config(u32 freq_hz, struct pll_div *div)
170 {
171 	u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
172 	u32 postdiv1, postdiv2 = 1;
173 	u32 fref_khz;
174 	u32 diff_khz, best_diff_khz;
175 	const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
176 	const u32 max_postdiv1 = 7, max_postdiv2 = 7;
177 	u32 vco_khz;
178 	u32 freq_khz = freq_hz / KHz;
179 
180 	if (!freq_hz) {
181 		printf("%s: the frequency can't be 0 Hz\n", __func__);
182 		return -1;
183 	}
184 
185 	postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, freq_khz);
186 	if (postdiv1 > max_postdiv1) {
187 		postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
188 		postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
189 	}
190 
191 	vco_khz = freq_khz * postdiv1 * postdiv2;
192 
193 	if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
194 	    postdiv2 > max_postdiv2) {
195 		printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
196 		       __func__, freq_hz);
197 		return -1;
198 	}
199 
200 	div->postdiv1 = postdiv1;
201 	div->postdiv2 = postdiv2;
202 
203 	best_diff_khz = vco_khz;
204 	for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
205 		fref_khz = ref_khz / refdiv;
206 
207 		fbdiv = vco_khz / fref_khz;
208 		if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
209 			continue;
210 		diff_khz = vco_khz - fbdiv * fref_khz;
211 		if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
212 			fbdiv++;
213 			diff_khz = fref_khz - diff_khz;
214 		}
215 
216 		if (diff_khz >= best_diff_khz)
217 			continue;
218 
219 		best_diff_khz = diff_khz;
220 		div->refdiv = refdiv;
221 		div->fbdiv = fbdiv;
222 	}
223 
224 	if (best_diff_khz > 4 * (MHz / KHz)) {
225 		printf("%s: Failed to match output frequency %u bestis %u Hz\n",
226 		       __func__, freq_hz,
227 		       best_diff_khz * KHz);
228 		return -1;
229 	}
230 	return 0;
231 }
232 
233 static void rkclk_init(struct px30_cru *cru)
234 {
235 	u32 aclk_div;
236 
237 	/* init pll */
238 	rkclk_set_pll(cru, APLL, apll_cfgs[APLL_816_MHZ]);
239 	rkclk_set_pll(cru, GPLL, &gpll_init_cfg);
240 
241 	/*
242 	 * select apll as cpu/core clock pll source and
243 	 * set up dependent divisors for PERI and ACLK clocks.
244 	 * core hz : apll = 1:1
245 	 */
246 	aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
247 	rk_clrsetreg(&cru->clksel_con[0],
248 		     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
249 		     CORE_ACLK_DIV_MASK,
250 		     aclk_div << CORE_ACLK_DIV_SHIFT |
251 		     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
252 		     0 << CORE_DIV_CON_SHIFT);
253 }
254 
255 static ulong px30_i2c_get_clk(struct px30_cru *cru, ulong clk_id)
256 {
257 	u32 div, con;
258 
259 	switch (clk_id) {
260 	case SCLK_I2C0:
261 		con = readl(&cru->clksel_con[49]);
262 		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
263 		break;
264 	case SCLK_I2C1:
265 		con = readl(&cru->clksel_con[49]);
266 		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
267 		break;
268 	case SCLK_I2C2:
269 		con = readl(&cru->clksel_con[50]);
270 		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
271 		break;
272 	case SCLK_I2C3:
273 		con = readl(&cru->clksel_con[50]);
274 		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
275 		break;
276 	default:
277 		printf("do not support this i2c bus\n");
278 		return -EINVAL;
279 	}
280 
281 	return DIV_TO_RATE(GPLL_HZ, div);
282 }
283 
284 static ulong px30_i2c_set_clk(struct px30_cru *cru, ulong clk_id, uint hz)
285 {
286 	int src_clk_div;
287 
288 	src_clk_div = GPLL_HZ / hz;
289 	assert(src_clk_div - 1 < 127);
290 
291 	switch (clk_id) {
292 	case SCLK_I2C0:
293 		rk_clrsetreg(&cru->clksel_con[49],
294 			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
295 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
296 			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
297 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
298 		break;
299 	case SCLK_I2C1:
300 		rk_clrsetreg(&cru->clksel_con[49],
301 			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
302 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
303 			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
304 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
305 		break;
306 	case SCLK_I2C2:
307 		rk_clrsetreg(&cru->clksel_con[50],
308 			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
309 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
310 			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
311 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
312 		break;
313 	case SCLK_I2C3:
314 		rk_clrsetreg(&cru->clksel_con[50],
315 			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
316 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
317 			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
318 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
319 		break;
320 	default:
321 		printf("do not support this i2c bus\n");
322 		return -EINVAL;
323 	}
324 
325 	return px30_i2c_get_clk(cru, clk_id);
326 }
327 
328 static ulong px30_mmc_get_clk(struct px30_cru *cru, uint clk_id)
329 {
330 	u32 div, con, con_id;
331 
332 	switch (clk_id) {
333 	case HCLK_SDMMC:
334 	case SCLK_SDMMC:
335 		con_id = 16;
336 		break;
337 	case HCLK_EMMC:
338 	case SCLK_EMMC:
339 	case SCLK_EMMC_SAMPLE:
340 		con_id = 20;
341 		break;
342 	default:
343 		return -EINVAL;
344 	}
345 
346 	con = readl(&cru->clksel_con[con_id]);
347 	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
348 
349 	if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
350 	    == EMMC_SEL_24M)
351 		return DIV_TO_RATE(OSC_HZ, div) / 2;
352 	else
353 		return DIV_TO_RATE(GPLL_HZ, div) / 2;
354 
355 }
356 
357 static ulong px30_mmc_set_clk(struct px30_cru *cru,
358 				ulong clk_id, ulong set_rate)
359 {
360 	int src_clk_div;
361 	u32 con_id;
362 
363 	debug("%s %ld %ld\n", __func__, clk_id, set_rate);
364 	switch (clk_id) {
365 	case HCLK_SDMMC:
366 	case SCLK_SDMMC:
367 		con_id = 16;
368 		break;
369 	case HCLK_EMMC:
370 	case SCLK_EMMC:
371 		con_id = 20;
372 		break;
373 	default:
374 		return -EINVAL;
375 	}
376 	/* Select clk_sdmmc/emmc source from GPLL by default */
377 	/* mmc clock defaulg div 2 internal, need provide double in cru */
378 	src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
379 
380 	if (src_clk_div > 127) {
381 		/* use 24MHz source for 400KHz clock */
382 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
383 		rk_clrsetreg(&cru->clksel_con[con_id],
384 			     EMMC_PLL_MASK | EMMC_DIV_MASK,
385 			     EMMC_SEL_24M << EMMC_PLL_SHIFT |
386 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
387 	} else {
388 		rk_clrsetreg(&cru->clksel_con[con_id],
389 			     EMMC_PLL_MASK | EMMC_DIV_MASK,
390 			     EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
391 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
392 	}
393 	rk_clrsetreg(&cru->clksel_con[con_id +1], EMMC_CLK_SEL_MASK,
394 		     EMMC_CLK_SEL_EMMC);
395 
396 	return px30_mmc_get_clk(cru, clk_id);
397 }
398 
399 static ulong px30_pwm_get_clk(struct px30_cru *cru, ulong clk_id)
400 {
401 	u32 div, con;
402 
403 	switch (clk_id) {
404 	case SCLK_PWM0:
405 		con = readl(&cru->clksel_con[52]);
406 		div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
407 		break;
408 	case SCLK_PWM1:
409 		con = readl(&cru->clksel_con[52]);
410 		div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
411 		break;
412 	default:
413 		printf("do not support this pwm bus\n");
414 		return -EINVAL;
415 	}
416 
417 	return DIV_TO_RATE(GPLL_HZ, div);
418 }
419 
420 static ulong px30_pwm_set_clk(struct px30_cru *cru, ulong clk_id, uint hz)
421 {
422 	int src_clk_div;
423 
424 	src_clk_div = GPLL_HZ / hz;
425 	assert(src_clk_div - 1 < 127);
426 
427 	switch (clk_id) {
428 	case SCLK_PWM0:
429 		rk_clrsetreg(&cru->clksel_con[52],
430 			     CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
431 			     CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
432 			     (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
433 			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
434 		break;
435 	case SCLK_PWM1:
436 		rk_clrsetreg(&cru->clksel_con[52],
437 			     CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
438 			     CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
439 			     (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
440 			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
441 		break;
442 	default:
443 		printf("do not support this pwm bus\n");
444 		return -EINVAL;
445 	}
446 
447 	return px30_pwm_get_clk(cru, clk_id);
448 }
449 
450 static ulong px30_saradc_get_clk(struct px30_cru *cru)
451 {
452 	u32 div, con;
453 
454 	con = readl(&cru->clksel_con[55]);
455 	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
456 
457 	return DIV_TO_RATE(OSC_HZ, div);
458 }
459 
460 static ulong px30_saradc_set_clk(struct px30_cru *cru, uint hz)
461 {
462 	int src_clk_div;
463 
464 	src_clk_div = OSC_HZ / hz;
465 	assert(src_clk_div - 1 < 2047);
466 
467 	rk_clrsetreg(&cru->clksel_con[55],
468 		     CLK_SARADC_DIV_CON_MASK,
469 		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
470 
471 	return px30_saradc_get_clk(cru);
472 }
473 
474 static ulong px30_spi_get_clk(struct px30_cru *cru, ulong clk_id)
475 {
476 	u32 div, con;
477 
478 	switch (clk_id) {
479 	case SCLK_SPI0:
480 		con = readl(&cru->clksel_con[53]);
481 		div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
482 		break;
483 	case SCLK_SPI1:
484 		con = readl(&cru->clksel_con[53]);
485 		div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
486 		break;
487 	default:
488 		printf("do not support this pwm bus\n");
489 		return -EINVAL;
490 	}
491 
492 	return DIV_TO_RATE(GPLL_HZ, div);
493 }
494 
495 static ulong px30_spi_set_clk(struct px30_cru *cru, ulong clk_id, uint hz)
496 {
497 	int src_clk_div;
498 
499 	src_clk_div = GPLL_HZ / hz;
500 	assert(src_clk_div - 1 < 127);
501 
502 	switch (clk_id) {
503 	case SCLK_SPI0:
504 		rk_clrsetreg(&cru->clksel_con[53],
505 			     CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
506 			     CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
507 			     (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
508 			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
509 		break;
510 	case SCLK_SPI1:
511 		rk_clrsetreg(&cru->clksel_con[53],
512 			     CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
513 			     CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
514 			     (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
515 			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
516 		break;
517 	default:
518 		printf("do not support this pwm bus\n");
519 		return -EINVAL;
520 	}
521 
522 	return px30_spi_get_clk(cru, clk_id);
523 }
524 
525 static ulong px30_vop_get_clk(struct px30_cru *cru, ulong clk_id)
526 {
527 	u32 div, con, parent;
528 
529 	switch (clk_id) {
530 	case ACLK_VOPB:
531 		con = readl(&cru->clksel_con[3]);
532 		div = con & ACLK_VO_DIV_MASK;
533 		parent = GPLL_HZ;
534 		break;
535 	case DCLK_VOPB:
536 		con = readl(&cru->clksel_con[5]);
537 		div = con & DCLK_VOPB_DIV_MASK;
538 		parent = rkclk_pll_get_rate(cru, CPLL);
539 		break;
540 	default:
541 		return -ENOENT;
542 	}
543 
544 	return DIV_TO_RATE(parent, div);
545 }
546 
547 static ulong px30_vop_set_clk(struct px30_cru *cru, ulong clk_id, uint hz)
548 {
549 	int src_clk_div;
550 	struct pll_div cpll_config = {0};
551 
552 	src_clk_div = GPLL_HZ / hz;
553 	assert(src_clk_div - 1 < 31);
554 
555 	switch (clk_id) {
556 	case ACLK_VOPB:
557 		rk_clrsetreg(&cru->clksel_con[3],
558 			     ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
559 			     ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
560 			     (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
561 		break;
562 	case DCLK_VOPB:
563 		/*
564 		 * vopb dclk source from cpll, and equals to
565 		 * cpll(means div == 1)
566 		 */
567 		if (pll_para_config(hz, &cpll_config))
568 			return -1;
569 		rkclk_set_pll(cru, CPLL, &cpll_config);
570 
571 		rk_clrsetreg(&cru->clksel_con[5],
572 			     DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
573 			     DCLK_VOPB_DIV_MASK,
574 			     DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
575 			     DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
576 			     (1 - 1) << DCLK_VOPB_DIV_SHIFT);
577 		break;
578 	default:
579 		printf("do not support this vop freq\n");
580 		return -EINVAL;
581 	}
582 
583 	return hz;
584 }
585 
586 static ulong px30_bus_get_clk(struct px30_cru *cru, ulong clk_id)
587 {
588 	u32 div, con, parent;
589 
590 	switch (clk_id) {
591 	case ACLK_BUS_PRE:
592 		con = readl(&cru->clksel_con[23]);
593 		div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
594 		parent = GPLL_HZ;
595 		break;
596 	case HCLK_BUS_PRE:
597 		con = readl(&cru->clksel_con[24]);
598 		div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
599 		parent = GPLL_HZ;
600 		break;
601 	case PCLK_BUS_PRE:
602 		parent = px30_bus_get_clk(cru, ACLK_BUS_PRE);
603 		con = readl(&cru->clksel_con[24]);
604 		div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
605 		break;
606 	default:
607 		return -ENOENT;
608 	}
609 
610 	return DIV_TO_RATE(parent, div);
611 }
612 
613 static ulong px30_bus_set_clk(struct px30_cru *cru, ulong clk_id, ulong hz)
614 {
615 	int src_clk_div;
616 
617 	/*
618 	 * select gpll as pd_bus bus clock source and
619 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
620 	 */
621 	switch (clk_id) {
622 	case ACLK_BUS_PRE:
623 		src_clk_div = GPLL_HZ / hz;
624 		assert(src_clk_div - 1 < 31);
625 		rk_clrsetreg(&cru->clksel_con[23],
626 			     BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
627 			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
628 			     (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
629 		break;
630 	case HCLK_BUS_PRE:
631 		src_clk_div = GPLL_HZ / hz;
632 		assert(src_clk_div - 1 < 31);
633 		rk_clrsetreg(&cru->clksel_con[24],
634 			     BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
635 			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
636 			     (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
637 		break;
638 	case PCLK_BUS_PRE:
639 		src_clk_div = px30_bus_get_clk(cru, ACLK_BUS_PRE) / hz;
640 		assert(src_clk_div - 1 < 3);
641 		rk_clrsetreg(&cru->clksel_con[24],
642 			     BUS_PCLK_DIV_MASK,
643 			     (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
644 		break;
645 	default:
646 		printf("do not support this bus freq\n");
647 		return -EINVAL;
648 	}
649 
650 	return px30_bus_get_clk(cru, clk_id);
651 }
652 
653 static ulong px30_peri_get_clk(struct px30_cru *cru, ulong clk_id)
654 {
655 	u32 div, con, parent;
656 
657 	switch (clk_id) {
658 	case ACLK_PERI_PRE:
659 		con = readl(&cru->clksel_con[14]);
660 		div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
661 		parent = GPLL_HZ;
662 		break;
663 	case HCLK_PERI_PRE:
664 		con = readl(&cru->clksel_con[14]);
665 		div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
666 		parent = GPLL_HZ;
667 		break;
668 	default:
669 		return -ENOENT;
670 	}
671 
672 	return DIV_TO_RATE(parent, div);
673 }
674 
675 static ulong px30_peri_set_clk(struct px30_cru *cru, ulong clk_id, ulong hz)
676 {
677 	int src_clk_div;
678 
679 	src_clk_div = GPLL_HZ / hz;
680 	assert(src_clk_div - 1 < 31);
681 
682 	/*
683 	 * select gpll as pd_peri bus clock source and
684 	 * set up dependent divisors for HCLK and ACLK clocks.
685 	 */
686 	switch (clk_id) {
687 	case ACLK_PERI_PRE:
688 		rk_clrsetreg(&cru->clksel_con[14],
689 			     PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
690 			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
691 			     (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
692 		break;
693 	case HCLK_PERI_PRE:
694 		rk_clrsetreg(&cru->clksel_con[14],
695 			     PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
696 			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
697 			     (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
698 		break;
699 	default:
700 		printf("do not support this peri freq\n");
701 		return -EINVAL;
702 	}
703 
704 	return px30_peri_get_clk(cru, clk_id);
705 }
706 
707 static ulong px30_clk_get_rate(struct clk *clk)
708 {
709 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
710 	ulong rate = 0;
711 
712 	switch (clk->id) {
713 	case 0 ... 15:
714 		return 0;
715 	case HCLK_SDMMC:
716 	case HCLK_EMMC:
717 	case SCLK_SDMMC:
718 	case SCLK_EMMC:
719 	case SCLK_EMMC_SAMPLE:
720 		rate = px30_mmc_get_clk(priv->cru, clk->id);
721 		break;
722 	case SCLK_I2C0:
723 	case SCLK_I2C1:
724 	case SCLK_I2C2:
725 	case SCLK_I2C3:
726 		rate = px30_i2c_get_clk(priv->cru, clk->id);
727 		break;
728 	case SCLK_PWM0:
729 	case SCLK_PWM1:
730 		rate = px30_pwm_get_clk(priv->cru, clk->id);
731 		break;
732 	case SCLK_SARADC:
733 		rate = px30_saradc_get_clk(priv->cru);
734 		break;
735 	case SCLK_SPI0:
736 	case SCLK_SPI1:
737 		rate = px30_spi_get_clk(priv->cru, clk->id);
738 		break;
739 	case ACLK_VOPB:
740 	case DCLK_VOPB:
741 		rate = px30_vop_get_clk(priv->cru, clk->id);
742 		break;
743 	case ACLK_BUS_PRE:
744 	case HCLK_BUS_PRE:
745 	case PCLK_BUS_PRE:
746 		rate = px30_bus_get_clk(priv->cru, clk->id);
747 		break;
748 	case ACLK_PERI_PRE:
749 	case HCLK_PERI_PRE:
750 		rate = px30_peri_get_clk(priv->cru, clk->id);
751 		break;
752 	default:
753 		return -ENOENT;
754 	}
755 
756 	return rate;
757 }
758 
759 static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
760 {
761 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
762 	ulong ret = 0;
763 
764 	debug("%s %ld %ld\n", __func__, clk->id, rate);
765 	switch (clk->id) {
766 	case 0 ... 15:
767 		return 0;
768 	case HCLK_SDMMC:
769 	case HCLK_EMMC:
770 	case SCLK_SDMMC:
771 	case SCLK_EMMC:
772 		ret = px30_mmc_set_clk(priv->cru, clk->id, rate);
773 		break;
774 	case SCLK_I2C0:
775 	case SCLK_I2C1:
776 	case SCLK_I2C2:
777 	case SCLK_I2C3:
778 		ret = px30_i2c_set_clk(priv->cru, clk->id, rate);
779 		break;
780 	case SCLK_PWM0:
781 	case SCLK_PWM1:
782 		ret = px30_pwm_set_clk(priv->cru, clk->id, rate);
783 		break;
784 	case SCLK_SARADC:
785 		ret = px30_saradc_set_clk(priv->cru, rate);
786 		break;
787 	case SCLK_SPI0:
788 	case SCLK_SPI1:
789 		ret = px30_spi_set_clk(priv->cru, clk->id, rate);
790 		break;
791 	case ACLK_VOPB:
792 	case DCLK_VOPB:
793 		ret = px30_vop_set_clk(priv->cru, clk->id, rate);
794 		break;
795 	case ACLK_BUS_PRE:
796 	case HCLK_BUS_PRE:
797 	case PCLK_BUS_PRE:
798 		ret = px30_bus_set_clk(priv->cru, clk->id, rate);
799 		break;
800 	case ACLK_PERI_PRE:
801 	case HCLK_PERI_PRE:
802 		ret = px30_peri_set_clk(priv->cru, clk->id, rate);
803 		break;
804 	default:
805 		return -ENOENT;
806 	}
807 
808 	return ret;
809 }
810 
811 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
812 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
813 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
814 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
815 
816 #define PSECS_PER_SEC 1000000000000LL
817 /*
818  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
819  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
820  */
821 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
822 
823 int rockchip_mmc_get_phase(struct clk *clk)
824 {
825 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
826 	struct px30_cru *cru = priv->cru;
827 	u32 raw_value, delay_num;
828 	u16 degrees = 0;
829 	ulong rate;
830 
831 	rate = px30_clk_get_rate(clk);
832 
833 	if (rate < 0)
834 		return rate;
835 
836 	if (clk->id == SCLK_EMMC_SAMPLE)
837 		raw_value = readl(&cru->emmc_con[1]);
838 	else
839 		raw_value = readl(&cru->sdmmc_con[1]);
840 
841 	raw_value >>= 1;
842 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
843 
844 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
845 		/* degrees/delaynum * 10000 */
846 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
847 					36 * (rate / 1000000);
848 
849 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
850 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
851 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
852 	}
853 
854 	return degrees % 360;
855 }
856 
857 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees)
858 {
859 	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
860 	struct px30_cru *cru = priv->cru;
861 	u8 nineties, remainder, delay_num;
862 	u32 raw_value, delay;
863 	ulong rate;
864 
865 	rate = px30_clk_get_rate(clk);
866 
867 	if (rate < 0)
868 		return rate;
869 
870 	nineties = degrees / 90;
871 	remainder = (degrees % 90);
872 
873 	/*
874 	 * Convert to delay; do a little extra work to make sure we
875 	 * don't overflow 32-bit / 64-bit numbers.
876 	 */
877 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
878 	delay *= remainder;
879 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
880 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
881 
882 	delay_num = (u8)min_t(u32, delay, 255);
883 
884 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
885 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
886 	raw_value |= nineties;
887 
888 	raw_value <<= 1;
889 	if (clk->id == SCLK_EMMC_SAMPLE)
890 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
891 	else
892 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
893 
894 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
895 	      degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk));
896 
897 	return 0;
898 }
899 
900 static int px30_clk_get_phase(struct clk *clk)
901 {
902 	int ret;
903 
904 	switch (clk->id) {
905 	case SCLK_EMMC_SAMPLE:
906 	case SCLK_SDMMC_SAMPLE:
907 		ret = rockchip_mmc_get_phase(clk);
908 		break;
909 	default:
910 		return -ENOENT;
911 	}
912 
913 	return ret;
914 }
915 
916 static int px30_clk_set_phase(struct clk *clk, int degrees)
917 {
918 	int ret;
919 
920 	switch (clk->id) {
921 	case SCLK_EMMC_SAMPLE:
922 	case SCLK_SDMMC_SAMPLE:
923 		ret = rockchip_mmc_set_phase(clk, degrees);
924 		break;
925 	default:
926 		return -ENOENT;
927 	}
928 
929 	return ret;
930 }
931 
932 static struct clk_ops px30_clk_ops = {
933 	.get_rate = px30_clk_get_rate,
934 	.set_rate = px30_clk_set_rate,
935 	.get_phase	= px30_clk_get_phase,
936 	.set_phase	= px30_clk_set_phase,
937 };
938 
939 static int px30_clk_probe(struct udevice *dev)
940 {
941 	struct px30_clk_priv *priv = dev_get_priv(dev);
942 	u32 reg = readl(&priv->cru->clksel_con[23]);
943 
944 	/* Only do the rkclk_init() one time for boot up */
945 	if (((reg & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT) !=
946 	    (GPLL_HZ / BUS_ACLK_HZ - 1))
947 		rkclk_init(priv->cru);
948 
949 	return 0;
950 }
951 
952 static int px30_clk_ofdata_to_platdata(struct udevice *dev)
953 {
954 	struct px30_clk_priv *priv = dev_get_priv(dev);
955 
956 	priv->cru = dev_read_addr_ptr(dev);
957 
958 	return 0;
959 }
960 
961 static int px30_clk_bind(struct udevice *dev)
962 {
963 	int ret;
964 	struct udevice *sys_child, *sf_child;
965 	struct sysreset_reg *priv;
966 	struct softreset_reg *sf_priv;
967 
968 	/* The reset driver does not have a device node, so bind it here */
969 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
970 				 &sys_child);
971 	if (ret) {
972 		debug("Warning: No sysreset driver: ret=%d\n", ret);
973 	} else {
974 		priv = malloc(sizeof(struct sysreset_reg));
975 		priv->glb_srst_fst_value = offsetof(struct px30_cru,
976 						    glb_srst_fst);
977 		priv->glb_srst_snd_value = offsetof(struct px30_cru,
978 						    glb_srst_snd);
979 		sys_child->priv = priv;
980 	}
981 
982 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
983 					 dev_ofnode(dev), &sf_child);
984 	if (ret) {
985 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
986 	} else {
987 		sf_priv = malloc(sizeof(struct softreset_reg));
988 		sf_priv->sf_reset_offset = offsetof(struct px30_cru,
989 						    softrst_con[0]);
990 		sf_priv->sf_reset_num = 12;
991 		sf_child->priv = sf_priv;
992 	}
993 
994 	return 0;
995 }
996 
997 static const struct udevice_id px30_clk_ids[] = {
998 	{ .compatible = "rockchip,px30-cru" },
999 	{ }
1000 };
1001 
1002 U_BOOT_DRIVER(rockchip_px30_cru) = {
1003 	.name		= "rockchip_px30_cru",
1004 	.id		= UCLASS_CLK,
1005 	.of_match	= px30_clk_ids,
1006 	.priv_auto_alloc_size = sizeof(struct px30_clk_priv),
1007 	.ofdata_to_platdata = px30_clk_ofdata_to_platdata,
1008 	.ops		= &px30_clk_ops,
1009 	.bind		= px30_clk_bind,
1010 	.probe		= px30_clk_probe,
1011 };
1012