xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1103b.c (revision 76f3cd6af247bad26c0dcc187a8f150d909cc52c)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2024 Rockchip Electronics Co., Ltd
4  * Author: Elaine Zhang <zhangqing@rock-chips.com>
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_rv1103b.h>
15 #include <asm/arch/grf_rv1103b.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rockchip,rv1103b-cru.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
24 
25 #ifdef CONFIG_SPL_BUILD
26 #ifndef BITS_WITH_WMASK
27 #define BITS_WITH_WMASK(bits, msk, shift) \
28 	((bits) << (shift)) | ((msk) << ((shift) + 16))
29 #endif
30 #endif
31 
32 static struct rockchip_pll_rate_table rv1103b_pll_rates[] = {
33 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
34 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
35 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
36 	{ /* sentinel */ },
37 };
38 
39 static struct rockchip_pll_clock rv1103b_pll_clks[] = {
40 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1103B_PLL_CON(24),
41 		     RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),
42 };
43 
44 #ifndef CONFIG_SPL_BUILD
45 #define RV1103B_CLK_DUMP(_id, _name, _iscru)	\
46 {						\
47 	.id = _id,				\
48 	.name = _name,				\
49 	.is_cru = _iscru,			\
50 }
51 
52 static const struct rv1103b_clk_info clks_dump[] = {
53 	RV1103B_CLK_DUMP(PLL_GPLL, "gpll", true),
54 	RV1103B_CLK_DUMP(ACLK_PERI_SRC, "aclk_peri_src", true),
55 	RV1103B_CLK_DUMP(LSCLK_PERI_SRC, "lsclk_peri_src", true),
56 	RV1103B_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true),
57 	RV1103B_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
58 	RV1103B_CLK_DUMP(LSCLK_PMU_ROOT, "lsclk_pmu_root", true),
59 };
60 #endif
61 
rv1103b_peri_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)62 static ulong rv1103b_peri_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
63 {
64 	struct rv1103b_cru *cru = priv->cru;
65 	u32 con, sel, div, rate, prate;
66 
67 	switch (clk_id) {
68 	case ACLK_PERI_SRC:
69 		con = readl(&cru->clksel_con[31]);
70 		sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
71 		if (sel == ACLK_PERI_SEL_600M)
72 			rate = 600 * MHz;
73 		else if (sel == ACLK_PERI_SEL_480M)
74 			rate = 480 * MHz;
75 		else
76 			rate = 400 * MHz;
77 		break;
78 	case LSCLK_PERI_SRC:
79 		con = readl(&cru->clksel_con[31]);
80 		sel = (con & LSCLK_PERI_SEL_MASK) >> LSCLK_PERI_SEL_SHIFT;
81 		if (sel == LSCLK_PERI_SEL_300M)
82 			rate = 300 * MHz;
83 		else
84 			rate = 200 * MHz;
85 		break;
86 	case PCLK_PERI_ROOT:
87 		con = readl(&cru->peri_clksel_con[0]);
88 		div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
89 		rate = DIV_TO_RATE(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
90 				   div);
91 		break;
92 	case PCLK_TOP_ROOT:
93 		rate = DIV_TO_RATE(priv->gpll_hz, 11);
94 		break;
95 	case LSCLK_PMU_ROOT:
96 	case PCLK_PMU:
97 		con = readl(&cru->pmu_clksel_con[2]);
98 		sel = (con & LSCLK_PMU_SEL_MASK) >> LSCLK_PMU_SEL_SHIFT;
99 		div = (con & LSCLK_PMU_DIV_MASK) >> LSCLK_PMU_DIV_SHIFT;
100 		if (sel == LSCLK_PMU_SEL_24M)
101 			prate = OSC_HZ;
102 		else
103 			prate = RC_OSC_HZ;
104 		rate = DIV_TO_RATE(prate, div);
105 		break;
106 	default:
107 		return -ENOENT;
108 	}
109 
110 	return rate;
111 }
112 
rv1103b_peri_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)113 static ulong rv1103b_peri_set_clk(struct rv1103b_clk_priv *priv,
114 				  ulong clk_id, ulong rate)
115 {
116 	struct rv1103b_cru *cru = priv->cru;
117 	int src_clk, div;
118 
119 	switch (clk_id) {
120 	case ACLK_PERI_SRC:
121 		if (rate >= 594 * MHz)
122 			src_clk = ACLK_PERI_SEL_600M;
123 		else if (rate >= 480 * MHz)
124 			src_clk = ACLK_PERI_SEL_480M;
125 		else
126 			src_clk = ACLK_PERI_SEL_400M;
127 		rk_clrsetreg(&cru->clksel_con[31],
128 			     ACLK_PERI_SEL_MASK,
129 			     src_clk << ACLK_PERI_SEL_SHIFT);
130 		break;
131 	case LSCLK_PERI_SRC:
132 		if (rate >= 297 * MHz)
133 			src_clk = LSCLK_PERI_SEL_300M;
134 		else
135 			src_clk = LSCLK_PERI_SEL_200M;
136 		rk_clrsetreg(&cru->clksel_con[31],
137 			     LSCLK_PERI_SEL_MASK,
138 			     src_clk << LSCLK_PERI_SEL_SHIFT);
139 		break;
140 	case PCLK_PERI_ROOT:
141 		div = DIV_ROUND_UP(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
142 				   rate);
143 		rk_clrsetreg(&cru->peri_clksel_con[0],
144 			     PCLK_PERI_DIV_MASK,
145 			     (div - 1) << PCLK_PERI_DIV_SHIFT);
146 		break;
147 	case PCLK_TOP_ROOT:
148 		break;
149 	case LSCLK_PMU_ROOT:
150 	case PCLK_PMU:
151 		if (!(OSC_HZ % rate)) {
152 			src_clk = LSCLK_PMU_SEL_24M;
153 			div = DIV_ROUND_UP(OSC_HZ, rate);
154 		} else {
155 			src_clk = LSCLK_PMU_SEL_RC_OSC;
156 			div = DIV_ROUND_UP(RC_OSC_HZ, rate);
157 		}
158 		rk_clrsetreg(&cru->pmu_clksel_con[2],
159 			     LSCLK_PMU_SEL_MASK | LSCLK_PMU_DIV_MASK,
160 			     (src_clk << LSCLK_PMU_SEL_SHIFT) |
161 			     ((div - 1) << LSCLK_PMU_DIV_SHIFT));
162 		break;
163 	default:
164 		printf("do not support this permid freq\n");
165 		return -EINVAL;
166 	}
167 
168 	return rv1103b_peri_get_clk(priv, clk_id);
169 }
170 
rv1103b_i2c_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)171 static ulong rv1103b_i2c_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
172 {
173 	struct rv1103b_cru *cru = priv->cru;
174 	u32 sel, con;
175 	ulong rate;
176 
177 	switch (clk_id) {
178 	case CLK_I2C1:
179 	case CLK_I2C2:
180 	case CLK_I2C3:
181 	case CLK_I2C4:
182 	case CLK_I2C_PERI:
183 		con = readl(&cru->clksel_con[34]);
184 		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
185 		break;
186 	case CLK_I2C0:
187 	case CLK_I2C_PMU:
188 		con = readl(&cru->clksel_con[34]);
189 		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
190 		break;
191 	default:
192 		return -ENOENT;
193 	}
194 
195 	if (sel == CLK_I2C_SEL_100M)
196 		rate = 100 * MHz;
197 	else
198 		rate = OSC_HZ;
199 
200 	return rate;
201 }
202 
rv1103b_crypto_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)203 static ulong rv1103b_crypto_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
204 {
205 	struct rv1103b_cru *cru = priv->cru;
206 	u32 sel, con, rate;
207 
208 	switch (clk_id) {
209 	case ACLK_CRYPTO:
210 	case HCLK_CRYPTO:
211 	case HCLK_RK_RNG_NS:
212 	case HCLK_RK_RNG_S:
213 		return rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC);
214 	case CLK_CORE_CRYPTO:
215 		con = readl(&cru->clksel_con[35]);
216 		sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
217 		      CLK_CORE_CRYPTO_SEL_SHIFT;
218 		break;
219 	case CLK_PKA_CRYPTO:
220 		con = readl(&cru->clksel_con[35]);
221 		sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
222 		      CLK_PKA_CRYPTO_SEL_SHIFT;
223 		break;
224 	default:
225 		return -ENOENT;
226 	}
227 	if (sel == CLK_CORE_CRYPTO_SEL_300M)
228 		rate = 300 * MHz;
229 	else if (sel == CLK_CORE_CRYPTO_SEL_200M)
230 		rate = 200 * MHz;
231 	else
232 		rate = 100 * MHz;
233 
234 	return rate;
235 
236 }
237 
rv1103b_crypto_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)238 static ulong rv1103b_crypto_set_clk(struct rv1103b_clk_priv *priv,
239 				    ulong clk_id, ulong rate)
240 {
241 	struct rv1103b_cru *cru = priv->cru;
242 	u32 sel;
243 
244 	if (rate >= 297 * MHz)
245 		sel = CLK_CORE_CRYPTO_SEL_300M;
246 	else if (rate >= 198 * MHz)
247 		sel = CLK_CORE_CRYPTO_SEL_200M;
248 	else
249 		sel = CLK_CORE_CRYPTO_SEL_100M;
250 
251 	switch (clk_id) {
252 	case ACLK_CRYPTO:
253 	case HCLK_CRYPTO:
254 	case HCLK_RK_RNG_NS:
255 	case HCLK_RK_RNG_S:
256 		rv1103b_peri_set_clk(priv, LSCLK_PERI_SRC, rate);
257 	case CLK_CORE_CRYPTO:
258 		rk_clrsetreg(&cru->clksel_con[35],
259 			     CLK_CORE_CRYPTO_SEL_MASK,
260 			     (sel << CLK_CORE_CRYPTO_SEL_SHIFT));
261 		break;
262 	case CLK_PKA_CRYPTO:
263 		rk_clrsetreg(&cru->clksel_con[35],
264 			     CLK_PKA_CRYPTO_SEL_MASK,
265 			     (sel << CLK_PKA_CRYPTO_SEL_SHIFT));
266 		break;
267 	default:
268 		return -ENOENT;
269 	}
270 	return rv1103b_crypto_get_clk(priv, clk_id);
271 }
272 
rv1103b_mmc_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)273 static ulong rv1103b_mmc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
274 {
275 	struct rv1103b_cru *cru = priv->cru;
276 	u32 div, sel, con, prate;
277 
278 	switch (clk_id) {
279 	case CCLK_SDMMC1:
280 	case HCLK_SDMMC1:
281 		con = readl(&cru->clksel_con[36]);
282 		sel = (con & CLK_SDMMC_SEL_MASK) >>
283 		      CLK_SDMMC_SEL_SHIFT;
284 		div = (con & CLK_SDMMC_DIV_MASK) >>
285 		      CLK_SDMMC_DIV_SHIFT;
286 		if (sel == CLK_MMC_SEL_GPLL)
287 			prate = priv->gpll_hz;
288 		else
289 			prate = OSC_HZ;
290 		return DIV_TO_RATE(prate, div);
291 	case CCLK_SDMMC0:
292 	case HCLK_SDMMC0:
293 		con = readl(&cru->clksel_con[32]);
294 		sel = (con & CLK_SDMMC_SEL_MASK) >>
295 		      CLK_SDMMC_SEL_SHIFT;
296 		div = (con & CLK_SDMMC_DIV_MASK) >>
297 		      CLK_SDMMC_DIV_SHIFT;
298 		if (sel == CLK_MMC_SEL_GPLL)
299 			prate = priv->gpll_hz;
300 		else
301 			prate = OSC_HZ;
302 		return DIV_TO_RATE(prate, div);
303 	case CCLK_EMMC:
304 	case HCLK_EMMC:
305 		con = readl(&cru->clksel_con[31]);
306 		sel = (con & CLK_EMMC_SEL_MASK) >>
307 		      CLK_EMMC_SEL_SHIFT;
308 		div = (con & CLK_EMMC_DIV_MASK) >>
309 		      CLK_EMMC_DIV_SHIFT;
310 		if (sel == CLK_MMC_SEL_GPLL)
311 			prate = priv->gpll_hz;
312 		else
313 			prate = OSC_HZ;
314 		return DIV_TO_RATE(prate, div);
315 	case SCLK_SFC_2X:
316 	case HCLK_SFC:
317 		con = readl(&cru->clksel_con[33]);
318 		sel = (con & CLK_SFC_SEL_MASK) >>
319 		      CLK_SFC_SEL_SHIFT;
320 		div = (con & CLK_SFC_DIV_MASK) >>
321 		      CLK_SFC_DIV_SHIFT;
322 		if (sel == CLK_MMC_SEL_GPLL)
323 			prate = priv->gpll_hz;
324 		else
325 			prate = OSC_HZ;
326 		return DIV_TO_RATE(prate, div);
327 	default:
328 		return -ENOENT;
329 	}
330 }
331 
rv1103b_mmc_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)332 static ulong rv1103b_mmc_set_clk(struct rv1103b_clk_priv *priv,
333 				 ulong clk_id, ulong rate)
334 {
335 	struct rv1103b_cru *cru = priv->cru;
336 	u32 sel, src_clk_div;
337 	ulong prate = 0;
338 
339 	if ((OSC_HZ % rate) == 0) {
340 		sel = CLK_MMC_SEL_OSC;
341 		prate = OSC_HZ;
342 	} else {
343 		sel = CLK_MMC_SEL_GPLL;
344 		prate = priv->gpll_hz;
345 	}
346 	src_clk_div = DIV_ROUND_UP(prate, rate);
347 
348 	switch (clk_id) {
349 	case CCLK_SDMMC1:
350 	case HCLK_SDMMC1:
351 		src_clk_div = DIV_ROUND_UP(prate, rate);
352 		rk_clrsetreg(&cru->clksel_con[36],
353 			     CLK_SDMMC_SEL_MASK |
354 			     CLK_SDMMC_DIV_MASK,
355 			     (sel << CLK_SDMMC_SEL_SHIFT) |
356 			     ((src_clk_div - 1) <<
357 			      CLK_SDMMC_DIV_SHIFT));
358 		break;
359 	case CCLK_SDMMC0:
360 	case HCLK_SDMMC0:
361 		src_clk_div = DIV_ROUND_UP(prate, rate);
362 		rk_clrsetreg(&cru->clksel_con[32],
363 			     CLK_SDMMC_SEL_MASK |
364 			     CLK_SDMMC_DIV_MASK,
365 			     (sel << CLK_SDMMC_SEL_SHIFT) |
366 			     ((src_clk_div - 1) <<
367 			      CLK_SDMMC_DIV_SHIFT));
368 		break;
369 	case CCLK_EMMC:
370 	case HCLK_EMMC:
371 		src_clk_div = DIV_ROUND_UP(prate, rate);
372 		rk_clrsetreg(&cru->clksel_con[31],
373 			     CLK_EMMC_SEL_MASK |
374 			     CLK_EMMC_DIV_MASK,
375 			     (sel << CLK_EMMC_SEL_SHIFT) |
376 			     ((src_clk_div - 1) <<
377 			      CLK_EMMC_DIV_SHIFT));
378 		break;
379 	case SCLK_SFC_2X:
380 	case HCLK_SFC:
381 		src_clk_div = DIV_ROUND_UP(prate, rate);
382 		rk_clrsetreg(&cru->clksel_con[33],
383 			     CLK_SFC_SEL_MASK |
384 			     CLK_SFC_DIV_MASK,
385 			     (sel << CLK_SFC_SEL_SHIFT) |
386 			     ((src_clk_div - 1) <<
387 			      CLK_SFC_DIV_SHIFT));
388 		break;
389 	default:
390 		return -ENOENT;
391 	}
392 	return rv1103b_mmc_get_clk(priv, clk_id);
393 }
394 
rv1103b_i2c_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)395 static ulong rv1103b_i2c_set_clk(struct rv1103b_clk_priv *priv, ulong clk_id,
396 				 ulong rate)
397 {
398 	struct rv1103b_cru *cru = priv->cru;
399 	int src_clk;
400 
401 	if (rate == OSC_HZ)
402 		src_clk = CLK_I2C_SEL_24M;
403 	else
404 		src_clk = CLK_I2C_SEL_100M;
405 
406 	switch (clk_id) {
407 	case CLK_I2C1:
408 	case CLK_I2C2:
409 	case CLK_I2C3:
410 	case CLK_I2C4:
411 	case CLK_I2C_PERI:
412 		rk_clrsetreg(&cru->clksel_con[34], CLK_I2C1_SEL_MASK,
413 			     src_clk << CLK_I2C1_SEL_SHIFT);
414 		break;
415 	case CLK_I2C0:
416 	case CLK_I2C_PMU:
417 		rk_clrsetreg(&cru->clksel_con[34], CLK_I2C0_SEL_MASK,
418 			     src_clk << CLK_I2C0_SEL_SHIFT);
419 		break;
420 	default:
421 		return -ENOENT;
422 	}
423 	return rv1103b_i2c_get_clk(priv, clk_id);
424 }
425 
rv1103b_spi_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)426 static ulong rv1103b_spi_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
427 {
428 	struct rv1103b_cru *cru = priv->cru;
429 	u32 sel, con, rate;
430 
431 	switch (clk_id) {
432 	case CLK_SPI0:
433 		con = readl(&cru->clksel_con[34]);
434 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
435 		break;
436 	default:
437 		return -ENOENT;
438 	}
439 	if (sel == CLK_SPI0_SEL_200M)
440 		rate = 200 * MHz;
441 	else if (sel == CLK_SPI0_SEL_100M)
442 		rate = 100 * MHz;
443 	else if (sel == CLK_SPI0_SEL_50M)
444 		rate = 50 * MHz;
445 	else
446 		rate = OSC_HZ;
447 
448 	return rate;
449 }
450 
rv1103b_spi_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)451 static ulong rv1103b_spi_set_clk(struct rv1103b_clk_priv *priv,
452 				 ulong clk_id, ulong rate)
453 {
454 	struct rv1103b_cru *cru = priv->cru;
455 	int src_clk;
456 
457 	if (rate >= 198 * MHz)
458 		src_clk = CLK_SPI0_SEL_200M;
459 	else if (rate >= 99 * MHz)
460 		src_clk = CLK_SPI0_SEL_100M;
461 	else if (rate >= 48 * MHz)
462 		src_clk = CLK_SPI0_SEL_50M;
463 	else
464 		src_clk = CLK_SPI0_SEL_24M;
465 
466 	switch (clk_id) {
467 	case CLK_SPI0:
468 		rk_clrsetreg(&cru->clksel_con[34], CLK_SPI0_SEL_MASK,
469 			     src_clk << CLK_SPI0_SEL_SHIFT);
470 		break;
471 	default:
472 		return -ENOENT;
473 	}
474 
475 	return rv1103b_spi_get_clk(priv, clk_id);
476 }
477 
rv1103b_pwm_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)478 static ulong rv1103b_pwm_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
479 {
480 	struct rv1103b_cru *cru = priv->cru;
481 	u32 sel, con;
482 
483 	switch (clk_id) {
484 	case CLK_PWM0:
485 	case CLK_PWM0_SRC:
486 		con = readl(&cru->clksel_con[34]);
487 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
488 		break;
489 	case CLK_PWM1:
490 		con = readl(&cru->clksel_con[34]);
491 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
492 		break;
493 	case CLK_PWM2:
494 		con = readl(&cru->clksel_con[34]);
495 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
496 		break;
497 	default:
498 		return -ENOENT;
499 	}
500 
501 	switch (sel) {
502 	case CLK_PWM_SEL_100M:
503 		return 100 * MHz;
504 	case CLK_PWM_SEL_24M:
505 		return OSC_HZ;
506 	default:
507 		return -ENOENT;
508 	}
509 }
510 
rv1103b_pwm_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)511 static ulong rv1103b_pwm_set_clk(struct rv1103b_clk_priv *priv,
512 				 ulong clk_id, ulong rate)
513 {
514 	struct rv1103b_cru *cru = priv->cru;
515 	int src_clk;
516 
517 	if (rate >= 99 * MHz)
518 		src_clk = CLK_PWM_SEL_100M;
519 	else
520 		src_clk = CLK_PWM_SEL_24M;
521 
522 	switch (clk_id) {
523 	case CLK_PWM0:
524 	case CLK_PWM0_SRC:
525 		rk_clrsetreg(&cru->clksel_con[34],
526 			     CLK_PWM0_SEL_MASK,
527 			     src_clk << CLK_PWM0_SEL_SHIFT);
528 		break;
529 	case CLK_PWM1:
530 		rk_clrsetreg(&cru->clksel_con[34],
531 			     CLK_PWM1_SEL_MASK,
532 			     src_clk << CLK_PWM1_SEL_SHIFT);
533 		break;
534 	case CLK_PWM2:
535 		rk_clrsetreg(&cru->clksel_con[34],
536 			     CLK_PWM2_SEL_MASK,
537 			     src_clk << CLK_PWM2_SEL_SHIFT);
538 		break;
539 	default:
540 		return -ENOENT;
541 	}
542 
543 	return rv1103b_pwm_get_clk(priv, clk_id);
544 }
545 
rv1103b_adc_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)546 static ulong rv1103b_adc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
547 {
548 	struct rv1103b_cru *cru = priv->cru;
549 	u32 div, con;
550 
551 	switch (clk_id) {
552 	case CLK_SARADC:
553 		con = readl(&cru->peri_clksel_con[1]);
554 		div = (con & CLK_SARADC_DIV_MASK) >>
555 		      CLK_SARADC_DIV_SHIFT;
556 		return DIV_TO_RATE(OSC_HZ, div);
557 	case CLK_TSADC_TSEN:
558 		con = readl(&cru->peri_clksel_con[0]);
559 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
560 		      CLK_TSADC_TSEN_DIV_SHIFT;
561 		return DIV_TO_RATE(OSC_HZ, div);
562 	case CLK_TSADC:
563 		con = readl(&cru->peri_clksel_con[0]);
564 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
565 		return DIV_TO_RATE(OSC_HZ, div);
566 	default:
567 		return -ENOENT;
568 	}
569 }
570 
rv1103b_adc_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)571 static ulong rv1103b_adc_set_clk(struct rv1103b_clk_priv *priv,
572 				 ulong clk_id, ulong rate)
573 {
574 	struct rv1103b_cru *cru = priv->cru;
575 	int src_clk_div;
576 
577 	src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
578 
579 	switch (clk_id) {
580 	case CLK_SARADC:
581 		assert(src_clk_div - 1 <= 7);
582 		rk_clrsetreg(&cru->peri_clksel_con[1],
583 			     CLK_SARADC_DIV_MASK,
584 			     (src_clk_div - 1) <<
585 			     CLK_SARADC_DIV_SHIFT);
586 		break;
587 	case CLK_TSADC_TSEN:
588 		assert(src_clk_div - 1 <= 32);
589 		rk_clrsetreg(&cru->peri_clksel_con[0],
590 			     CLK_TSADC_TSEN_DIV_MASK,
591 			     (src_clk_div - 1) <<
592 			     CLK_TSADC_TSEN_DIV_SHIFT);
593 		break;
594 	case CLK_TSADC:
595 		assert(src_clk_div - 1 <= 32);
596 		rk_clrsetreg(&cru->peri_clksel_con[0],
597 			     CLK_TSADC_DIV_MASK,
598 			     (src_clk_div - 1) <<
599 			     CLK_TSADC_DIV_SHIFT);
600 		break;
601 	default:
602 		return -ENOENT;
603 	}
604 	return rv1103b_adc_get_clk(priv, clk_id);
605 }
606 
607 /*
608  *
609  * rational_best_approximation(31415, 10000,
610  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
611  *
612  * you may look at given_numerator as a fixed point number,
613  * with the fractional part size described in given_denominator.
614  *
615  * for theoretical background, see:
616  * http://en.wikipedia.org/wiki/Continued_fraction
617  */
rational_best_approximation(unsigned long given_numerator,unsigned long given_denominator,unsigned long max_numerator,unsigned long max_denominator,unsigned long * best_numerator,unsigned long * best_denominator)618 static void rational_best_approximation(unsigned long given_numerator,
619 					unsigned long given_denominator,
620 					unsigned long max_numerator,
621 					unsigned long max_denominator,
622 					unsigned long *best_numerator,
623 					unsigned long *best_denominator)
624 {
625 	unsigned long n, d, n0, d0, n1, d1;
626 
627 	n = given_numerator;
628 	d = given_denominator;
629 	n0 = 0;
630 	d1 = 0;
631 	n1 = 1;
632 	d0 = 1;
633 	for (;;) {
634 		unsigned long t, a;
635 
636 		if (n1 > max_numerator || d1 > max_denominator) {
637 			n1 = n0;
638 			d1 = d0;
639 			break;
640 		}
641 		if (d == 0)
642 			break;
643 		t = d;
644 		a = n / d;
645 		d = n % d;
646 		n = t;
647 		t = n0 + a * n1;
648 		n0 = n1;
649 		n1 = t;
650 		t = d0 + a * d1;
651 		d0 = d1;
652 		d1 = t;
653 	}
654 	*best_numerator = n1;
655 	*best_denominator = d1;
656 }
657 
rv1103b_uart_get_rate(struct rv1103b_clk_priv * priv,ulong clk_id)658 static ulong rv1103b_uart_get_rate(struct rv1103b_clk_priv *priv, ulong clk_id)
659 {
660 	struct rv1103b_cru *cru = priv->cru;
661 	u32 reg, con, fracdiv, div, src, p_rate;
662 	unsigned long m, n;
663 
664 	switch (clk_id) {
665 	case SCLK_UART0:
666 		reg = 10;
667 		con = readl(&cru->clksel_con[32]);
668 		src = (con & CLK_UART0_SEL_MASK) >> CLK_UART0_SEL_SHIFT;
669 		con = readl(&cru->clksel_con[5]);
670 		div = (con & CLK_UART0_SRC_DIV_MASK) >> CLK_UART0_SRC_DIV_SHIFT;
671 		break;
672 	case SCLK_UART1:
673 		reg = 11;
674 		con = readl(&cru->clksel_con[32]);
675 		src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
676 		con = readl(&cru->clksel_con[5]);
677 		div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
678 		break;
679 	case SCLK_UART2:
680 		reg = 12;
681 		con = readl(&cru->clksel_con[32]);
682 		src = (con & CLK_UART2_SEL_MASK) >> CLK_UART2_SEL_SHIFT;
683 		con = readl(&cru->clksel_con[5]);
684 		div = (con & CLK_UART2_SRC_DIV_MASK) >> CLK_UART2_SRC_DIV_SHIFT;
685 		break;
686 	default:
687 		return -ENOENT;
688 	}
689 
690 	p_rate = priv->gpll_hz;
691 	if (src == CLK_UART_SEL_SRC) {
692 		return DIV_TO_RATE(p_rate, div);
693 	} else if (src == CLK_UART_SEL_FRAC) {
694 		fracdiv = readl(&cru->clksel_con[reg]);
695 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
696 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
697 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
698 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
699 		return DIV_TO_RATE(p_rate, div) * n / m;
700 	} else {
701 		return OSC_HZ;
702 	}
703 }
704 
rv1103b_uart_set_rate(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)705 static ulong rv1103b_uart_set_rate(struct rv1103b_clk_priv *priv,
706 				   ulong clk_id, ulong rate)
707 {
708 	struct rv1103b_cru *cru = priv->cru;
709 	u32 reg, uart_src, div;
710 	unsigned long m = 0, n = 0, val;
711 
712 	if (priv->gpll_hz % rate == 0) {
713 		uart_src = CLK_UART_SEL_SRC;
714 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
715 	} else if (rate == OSC_HZ) {
716 		uart_src = CLK_UART_SEL_OSC;
717 		div = 2;
718 	} else {
719 		uart_src = CLK_UART_SEL_FRAC;
720 		div = 2;
721 		rational_best_approximation(rate, priv->gpll_hz / div,
722 					    GENMASK(16 - 1, 0),
723 					    GENMASK(16 - 1, 0),
724 					    &m, &n);
725 	}
726 
727 	switch (clk_id) {
728 	case SCLK_UART0:
729 		reg = 10;
730 		rk_clrsetreg(&cru->clksel_con[5],
731 			     CLK_UART0_SRC_DIV_MASK,
732 			     div << CLK_UART0_SRC_DIV_SHIFT);
733 		rk_clrsetreg(&cru->clksel_con[32],
734 			     CLK_UART0_SEL_MASK,
735 			     uart_src << CLK_UART0_SEL_SHIFT);
736 		break;
737 	case SCLK_UART1:
738 		reg = 11;
739 		rk_clrsetreg(&cru->clksel_con[5],
740 			     CLK_UART1_SRC_DIV_MASK,
741 			     div << CLK_UART1_SRC_DIV_SHIFT);
742 		rk_clrsetreg(&cru->clksel_con[32],
743 			     CLK_UART1_SEL_MASK,
744 			     uart_src << CLK_UART1_SEL_SHIFT);
745 		break;
746 	case SCLK_UART2:
747 		reg = 12;
748 		rk_clrsetreg(&cru->clksel_con[5],
749 			     CLK_UART2_SRC_DIV_MASK,
750 			     div << CLK_UART2_SRC_DIV_SHIFT);
751 		rk_clrsetreg(&cru->clksel_con[32],
752 			     CLK_UART2_SEL_MASK,
753 			     uart_src << CLK_UART2_SEL_SHIFT);
754 		break;
755 	default:
756 		return -ENOENT;
757 	}
758 	if (m && n) {
759 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
760 		writel(val, &cru->clksel_con[reg]);
761 	}
762 
763 	return rv1103b_uart_get_rate(priv, clk_id);
764 }
765 
rv1103b_decom_get_clk(struct rv1103b_clk_priv * priv)766 static ulong rv1103b_decom_get_clk(struct rv1103b_clk_priv *priv)
767 {
768 	struct rv1103b_cru *cru = priv->cru;
769 	u32 sel, con, prate;
770 
771 	con = readl(&cru->clksel_con[35]);
772 	sel = (con & DCLK_DECOM_SEL_MASK) >>
773 	      DCLK_DECOM_SEL_SHIFT;
774 	if (sel == DCLK_DECOM_SEL_480M)
775 		prate = 480 * MHz;
776 	else if (sel == DCLK_DECOM_SEL_400M)
777 		prate = 400 * MHz;
778 	else
779 		prate = 300 * MHz;
780 	return prate;
781 }
782 
rv1103b_decom_set_clk(struct rv1103b_clk_priv * priv,ulong rate)783 static ulong rv1103b_decom_set_clk(struct rv1103b_clk_priv *priv, ulong rate)
784 {
785 	struct rv1103b_cru *cru = priv->cru;
786 	u32 sel;
787 
788 	if (rate >= 480 * MHz)
789 		sel = DCLK_DECOM_SEL_480M;
790 	else if (rate >= 396 * MHz)
791 		sel = DCLK_DECOM_SEL_400M;
792 	else
793 		sel = DCLK_DECOM_SEL_300M;
794 	rk_clrsetreg(&cru->clksel_con[35], DCLK_DECOM_SEL_MASK,
795 		     (sel << DCLK_DECOM_SEL_SHIFT));
796 
797 	return rv1103b_decom_get_clk(priv);
798 }
799 
rv1103b_clk_get_rate(struct clk * clk)800 static ulong rv1103b_clk_get_rate(struct clk *clk)
801 {
802 	struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
803 	ulong rate = 0;
804 
805 	if (!priv->gpll_hz) {
806 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
807 		return -ENOENT;
808 	}
809 
810 	switch (clk->id) {
811 	case PLL_GPLL:
812 		rate = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL], priv->cru,
813 					     GPLL);
814 		break;
815 	case ACLK_PERI_SRC:
816 	case LSCLK_PERI_SRC:
817 	case PCLK_PERI_ROOT:
818 	case PCLK_TOP_ROOT:
819 	case LSCLK_PMU_ROOT:
820 	case PCLK_PMU:
821 		rate = rv1103b_peri_get_clk(priv, clk->id);
822 		break;
823 	case ACLK_CRYPTO:
824 	case HCLK_CRYPTO:
825 	case HCLK_RK_RNG_NS:
826 	case HCLK_RK_RNG_S:
827 	case CLK_CORE_CRYPTO:
828 	case CLK_PKA_CRYPTO:
829 		rate = rv1103b_crypto_get_clk(priv, clk->id);
830 		break;
831 	case CCLK_SDMMC1:
832 	case HCLK_SDMMC1:
833 	case CCLK_SDMMC0:
834 	case HCLK_SDMMC0:
835 	case CCLK_EMMC:
836 	case HCLK_EMMC:
837 	case SCLK_SFC_2X:
838 	case HCLK_SFC:
839 		rate = rv1103b_mmc_get_clk(priv, clk->id);
840 		break;
841 	case CLK_I2C1:
842 	case CLK_I2C2:
843 	case CLK_I2C3:
844 	case CLK_I2C4:
845 	case CLK_I2C_PERI:
846 	case CLK_I2C0:
847 	case CLK_I2C_PMU:
848 		rate = rv1103b_i2c_get_clk(priv, clk->id);
849 		break;
850 	case CLK_SPI0:
851 		rate = rv1103b_spi_get_clk(priv, clk->id);
852 		break;
853 	case CLK_PWM0:
854 	case CLK_PWM0_SRC:
855 	case CLK_PWM1:
856 	case CLK_PWM2:
857 		rate = rv1103b_pwm_get_clk(priv, clk->id);
858 		break;
859 	case CLK_SARADC:
860 	case CLK_TSADC_TSEN:
861 	case CLK_TSADC:
862 		rate = rv1103b_adc_get_clk(priv, clk->id);
863 		break;
864 	case SCLK_UART0:
865 	case SCLK_UART1:
866 	case SCLK_UART2:
867 		rate = rv1103b_uart_get_rate(priv, clk->id);
868 		break;
869 	case DCLK_DECOM_SRC:
870 	case DCLK_DECOM:
871 		rate = rv1103b_decom_get_clk(priv);
872 		break;
873 	case TCLK_WDT_LPMCU:
874 	case TCLK_WDT_HPMCU:
875 	case TCLK_WDT_NS:
876 	case TCLK_WDT_S:
877 		rate = OSC_HZ;
878 		break;
879 	default:
880 		return -ENOENT;
881 	}
882 
883 	return rate;
884 };
885 
rv1103b_clk_set_rate(struct clk * clk,ulong rate)886 static ulong rv1103b_clk_set_rate(struct clk *clk, ulong rate)
887 {
888 	struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
889 	ulong ret = 0;
890 
891 	if (!priv->gpll_hz) {
892 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
893 		return -ENOENT;
894 	}
895 
896 	switch (clk->id) {
897 	case PLL_GPLL:
898 		ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
899 					    GPLL, rate);
900 		break;
901 	case ACLK_PERI_SRC:
902 	case LSCLK_PERI_SRC:
903 	case PCLK_PERI_ROOT:
904 	case PCLK_TOP_ROOT:
905 	case LSCLK_PMU_ROOT:
906 	case PCLK_PMU:
907 		ret = rv1103b_peri_set_clk(priv, clk->id, rate);
908 		break;
909 	case ACLK_CRYPTO:
910 	case HCLK_CRYPTO:
911 	case HCLK_RK_RNG_NS:
912 	case HCLK_RK_RNG_S:
913 	case CLK_CORE_CRYPTO:
914 	case CLK_PKA_CRYPTO:
915 		ret = rv1103b_crypto_set_clk(priv, clk->id, rate);
916 		break;
917 	case CCLK_SDMMC1:
918 	case HCLK_SDMMC1:
919 	case CCLK_SDMMC0:
920 	case HCLK_SDMMC0:
921 	case CCLK_EMMC:
922 	case HCLK_EMMC:
923 	case SCLK_SFC_2X:
924 	case HCLK_SFC:
925 		ret = rv1103b_mmc_set_clk(priv, clk->id, rate);
926 		break;
927 	case CLK_I2C1:
928 	case CLK_I2C2:
929 	case CLK_I2C3:
930 	case CLK_I2C4:
931 	case CLK_I2C_PERI:
932 	case CLK_I2C0:
933 	case CLK_I2C_PMU:
934 		ret = rv1103b_i2c_set_clk(priv, clk->id, rate);
935 		break;
936 	case CLK_SPI0:
937 		ret = rv1103b_spi_set_clk(priv, clk->id, rate);
938 		break;
939 	case CLK_PWM0:
940 	case CLK_PWM0_SRC:
941 	case CLK_PWM1:
942 	case CLK_PWM2:
943 		ret = rv1103b_pwm_set_clk(priv, clk->id, rate);
944 		break;
945 	case CLK_SARADC:
946 	case CLK_TSADC_TSEN:
947 	case CLK_TSADC:
948 		ret = rv1103b_adc_set_clk(priv, clk->id, rate);
949 		break;
950 	case SCLK_UART0:
951 	case SCLK_UART1:
952 	case SCLK_UART2:
953 		ret = rv1103b_uart_set_rate(priv, clk->id, rate);
954 		break;
955 	case DCLK_DECOM_SRC:
956 	case DCLK_DECOM:
957 		rate = rv1103b_decom_set_clk(priv, rate);
958 		break;
959 	default:
960 		return -ENOENT;
961 	}
962 
963 	return ret;
964 };
965 
rv1103b_clk_set_parent(struct clk * clk,struct clk * parent)966 static int rv1103b_clk_set_parent(struct clk *clk, struct clk *parent)
967 {
968 	switch (clk->id) {
969 	default:
970 		return -ENOENT;
971 	}
972 
973 	return 0;
974 }
975 
976 static struct clk_ops rv1103b_clk_ops = {
977 	.get_rate = rv1103b_clk_get_rate,
978 	.set_rate = rv1103b_clk_set_rate,
979 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
980 	.set_parent = rv1103b_clk_set_parent,
981 #endif
982 };
983 
rv1103b_clk_init(struct rv1103b_clk_priv * priv)984 static void rv1103b_clk_init(struct rv1103b_clk_priv *priv)
985 {
986 	int ret;
987 	u32 div;
988 
989 	priv->sync_kernel = false;
990 	priv->gpll_hz = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL],
991 					      priv->cru, GPLL);
992 	if (priv->gpll_hz != GPLL_HZ) {
993 		ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
994 					    GPLL, GPLL_HZ);
995 		if (!ret)
996 			priv->gpll_hz = GPLL_HZ;
997 	}
998     	if (!priv->armclk_enter_hz) {
999 		div = (readl(&priv->cru->clksel_con[37]) &
1000 		       CLK_CORE_GPLL_DIV_MASK) >>
1001 		      CLK_CORE_GPLL_DIV_SHIFT;
1002 		priv->armclk_enter_hz = DIV_TO_RATE(priv->gpll_hz, div);
1003 		priv->armclk_init_hz = priv->armclk_enter_hz;
1004 	}
1005 }
1006 
rv1103b_clk_probe(struct udevice * dev)1007 static int rv1103b_clk_probe(struct udevice *dev)
1008 {
1009 	struct rv1103b_clk_priv *priv = dev_get_priv(dev);
1010 	int ret;
1011 
1012 #ifdef CONFIG_SPL_BUILD
1013         /* fix lsclk_prei div */
1014    	writel(BITS_WITH_WMASK(1, 0x1U, 9),
1015 	       RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(31));
1016         /* fix cpu div */
1017     	writel(BITS_WITH_WMASK(1, 0x7U, 13),
1018 	       RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(37));
1019 	/* fix gpll postdiv1 */
1020 	writel(BITS_WITH_WMASK(1, 0x7U, 12),
1021 	       RV1103B_CRU_BASE + RV1103B_PLL_CON(24));
1022 #endif
1023 
1024 	rv1103b_clk_init(priv);
1025 
1026 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1027 	ret = clk_set_defaults(dev);
1028 	if (ret)
1029 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1030 	else
1031 		priv->sync_kernel = true;
1032 	return 0;
1033 }
1034 
rv1103b_clk_ofdata_to_platdata(struct udevice * dev)1035 static int rv1103b_clk_ofdata_to_platdata(struct udevice *dev)
1036 {
1037 	struct rv1103b_clk_priv *priv = dev_get_priv(dev);
1038 
1039 	priv->cru = dev_read_addr_ptr(dev);
1040 
1041 	return 0;
1042 }
1043 
rv1103b_clk_bind(struct udevice * dev)1044 static int rv1103b_clk_bind(struct udevice *dev)
1045 {
1046 	int ret;
1047 	struct udevice *sys_child, *sf_child;
1048 	struct sysreset_reg *priv;
1049 	struct softreset_reg *sf_priv;
1050 
1051 	/* The reset driver does not have a device node, so bind it here */
1052 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1053 				 &sys_child);
1054 	if (ret) {
1055 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1056 	} else {
1057 		priv = malloc(sizeof(struct sysreset_reg));
1058 		priv->glb_srst_fst_value = offsetof(struct rv1103b_cru,
1059 						    glb_srst_fst);
1060 		priv->glb_srst_snd_value = offsetof(struct rv1103b_cru,
1061 						    glb_srst_snd);
1062 		sys_child->priv = priv;
1063 	}
1064 
1065 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1066 					 dev_ofnode(dev), &sf_child);
1067 	if (ret) {
1068 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1069 	} else {
1070 		sf_priv = malloc(sizeof(struct softreset_reg));
1071 		sf_priv->sf_reset_offset = offsetof(struct rv1103b_cru,
1072 						    peri_softrst_con[0]);
1073 		sf_priv->sf_reset_num = CLK_NR_SRST;
1074 		sf_child->priv = sf_priv;
1075 	}
1076 
1077 	return 0;
1078 }
1079 
1080 static const struct udevice_id rv1103b_clk_ids[] = {
1081 	{ .compatible = "rockchip,rv1103b-cru" },
1082 	{ }
1083 };
1084 
1085 U_BOOT_DRIVER(rockchip_rv1103b_cru) = {
1086 	.name		= "rockchip_rv1103b_cru",
1087 	.id		= UCLASS_CLK,
1088 	.of_match	= rv1103b_clk_ids,
1089 	.priv_auto_alloc_size = sizeof(struct rv1103b_clk_priv),
1090 	.ofdata_to_platdata = rv1103b_clk_ofdata_to_platdata,
1091 	.ops		= &rv1103b_clk_ops,
1092 	.bind		= rv1103b_clk_bind,
1093 	.probe		= rv1103b_clk_probe,
1094 };
1095 
1096 #ifndef CONFIG_SPL_BUILD
1097 /**
1098  * soc_clk_dump() - Print clock frequencies
1099  * Returns zero on success
1100  *
1101  * Implementation for the clk dump command.
1102  */
soc_clk_dump(void)1103 int soc_clk_dump(void)
1104 {
1105 	struct udevice *cru_dev;
1106 	struct rv1103b_clk_priv *priv;
1107 	const struct rv1103b_clk_info *clk_dump;
1108 	struct clk clk;
1109 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1110 	unsigned long rate;
1111 	int i, ret;
1112 
1113 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1114 					  DM_GET_DRIVER(rockchip_rv1103b_cru),
1115 					  &cru_dev);
1116 	if (ret) {
1117 		printf("%s failed to get cru device\n", __func__);
1118 		return ret;
1119 	}
1120 
1121 	priv = dev_get_priv(cru_dev);
1122 	ret = (readl(&priv->cru->core_clksel_con[0]) &
1123 	       CLK_CORE_SRC_SEL_MASK) >>
1124 	      CLK_CORE_SRC_SEL_SHIFT;
1125 	if (ret == CLK_CORE_SRC_SEL_PVTPLL)
1126 		printf("CLK: (arm clk use pvtpll, rate = 1200M)\n");
1127 	else
1128 		printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1129 		       priv->sync_kernel ? "sync kernel" : "uboot",
1130 		       priv->armclk_enter_hz / 1000,
1131 		       priv->armclk_init_hz / 1000,
1132 		       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1133 		       priv->set_armclk_rate ? " KHz" : "N/A");
1134 	for (i = 0; i < clk_count; i++) {
1135 		clk_dump = &clks_dump[i];
1136 		if (clk_dump->name) {
1137 			clk.id = clk_dump->id;
1138 			if (clk_dump->is_cru)
1139 				ret = clk_request(cru_dev, &clk);
1140 			if (ret < 0)
1141 				return ret;
1142 
1143 			rate = clk_get_rate(&clk);
1144 			clk_free(&clk);
1145 			if (i == 0) {
1146 				if (rate < 0)
1147 					printf("  %s %s\n", clk_dump->name,
1148 					       "unknown");
1149 				else
1150 					printf("  %s %lu KHz\n", clk_dump->name,
1151 					       rate / 1000);
1152 			} else {
1153 				if (rate < 0)
1154 					printf("  %s %s\n", clk_dump->name,
1155 					       "unknown");
1156 				else
1157 					printf("  %s %lu KHz\n", clk_dump->name,
1158 					       rate / 1000);
1159 			}
1160 		}
1161 	}
1162 
1163 	return 0;
1164 }
1165 #endif
1166