xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1106.c (revision 1bb4e9bafc0ca58e92f894fcc8eddb0a4ed571d6)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021 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_rv1106.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rv1106-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
23 
24 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
25 static struct rockchip_pll_rate_table rv1106_pll_rates[] = {
26 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
27 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
28 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
29 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
30 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
31 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
32 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
33 	{ /* sentinel */ },
34 };
35 
36 static struct rockchip_pll_clock rv1106_pll_clks[] = {
37 	[APLL] = PLL(pll_rk3328, PLL_APLL, RV1106_PLL_CON(0),
38 		     RV1106_MODE_CON, 0, 10, 0, rv1106_pll_rates),
39 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1106_PLL_CON(16),
40 		     RV1106_SUBDDRMODE_CON, 0, 10, 0, NULL),
41 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1106_PLL_CON(8),
42 		     RV1106_MODE_CON, 2, 10, 0, rv1106_pll_rates),
43 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1106_PLL_CON(24),
44 		     RV1106_MODE_CON, 4, 10, 0, rv1106_pll_rates),
45 };
46 #endif
47 
48 #ifndef CONFIG_SPL_BUILD
49 #define RV1106_CLK_DUMP(_id, _name, _iscru)	\
50 {						\
51 	.id = _id,				\
52 	.name = _name,				\
53 	.is_cru = _iscru,			\
54 }
55 
56 static const struct rv1106_clk_info clks_dump[] = {
57 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
58 	RV1106_CLK_DUMP(PLL_APLL, "apll", true),
59 	RV1106_CLK_DUMP(PLL_DPLL, "dpll", true),
60 	RV1106_CLK_DUMP(PLL_GPLL, "gpll", true),
61 	RV1106_CLK_DUMP(PLL_CPLL, "cpll", true),
62 	RV1106_CLK_DUMP(ACLK_PERI_ROOT, "aclk_peri_root", true),
63 	RV1106_CLK_DUMP(HCLK_PERI_ROOT, "hclK_peri_root", true),
64 	RV1106_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true),
65 	RV1106_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
66 	RV1106_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
67 	RV1106_CLK_DUMP(PCLK_PMU_ROOT, "pclk_pmu_root", true),
68 	RV1106_CLK_DUMP(HCLK_PMU_ROOT, "hclk_pmu_root", true),
69 #endif
70 };
71 #endif
72 
73 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
74 static ulong rv1106_peri_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
75 {
76 	struct rv1106_cru *cru = priv->cru;
77 	u32 con, sel, rate;
78 
79 	switch (clk_id) {
80 	case ACLK_PERI_ROOT:
81 		con = readl(&cru->peri_clksel_con[1]);
82 		sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
83 		if (sel == ACLK_PERI_SEL_400M)
84 			rate = 400 * MHz;
85 		else if (sel == ACLK_PERI_SEL_200M)
86 			rate = 200 * MHz;
87 		else if (sel == ACLK_PERI_SEL_100M)
88 			rate = 100 * MHz;
89 		else
90 			rate = OSC_HZ;
91 		break;
92 	case HCLK_PERI_ROOT:
93 		con = readl(&cru->peri_clksel_con[1]);
94 		sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT;
95 		if (sel == HCLK_PERI_SEL_200M)
96 			rate = 200 * MHz;
97 		else if (sel == HCLK_PERI_SEL_100M)
98 			rate = 100 * MHz;
99 		else if (sel == HCLK_PERI_SEL_50M)
100 			rate = 50 * MHz;
101 		else
102 			rate = OSC_HZ;
103 		break;
104 	case PCLK_PERI_ROOT:
105 		con = readl(&cru->peri_clksel_con[1]);
106 		sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
107 		if (sel == PCLK_PERI_SEL_100M)
108 			rate = 100 * MHz;
109 		else if (sel == PCLK_PERI_SEL_50M)
110 			rate = 50 * MHz;
111 		else
112 			rate = OSC_HZ;
113 		break;
114 	case ACLK_BUS_ROOT:
115 		con = readl(&cru->peri_clksel_con[9]);
116 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
117 		if (sel == ACLK_BUS_SEL_300M)
118 			rate = 300 * MHz;
119 		else if (sel == ACLK_BUS_SEL_200M)
120 			rate = 200 * MHz;
121 		else if (sel == ACLK_BUS_SEL_100M)
122 			rate = 100 * MHz;
123 		else
124 			rate = OSC_HZ;
125 		break;
126 	case PCLK_TOP_ROOT:
127 		con = readl(&cru->clksel_con[24]);
128 		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
129 		if (sel == PCLK_TOP_SEL_100M)
130 			rate = 100 * MHz;
131 		else if (sel == PCLK_TOP_SEL_50M)
132 			rate = 50 * MHz;
133 		else
134 			rate = OSC_HZ;
135 		break;
136 	case PCLK_PMU_ROOT:
137 		con = readl(&cru->pmu_clksel_con[0]);
138 		sel = (con & PCLK_PMU_SEL_MASK) >> PCLK_PMU_SEL_SHIFT;
139 		if (sel == PCLK_PMU_SEL_100M)
140 			rate = 100 * MHz;
141 		else
142 			rate = OSC_HZ;
143 		break;
144 	case HCLK_PMU_ROOT:
145 		con = readl(&cru->pmu_clksel_con[0]);
146 		sel = (con & HCLK_PMU_SEL_MASK) >> HCLK_PMU_SEL_SHIFT;
147 		if (sel == HCLK_PMU_SEL_200M)
148 			rate = 200 * MHz;
149 		else if (sel == HCLK_PMU_SEL_100M)
150 			rate = 100 * MHz;
151 		else
152 			rate = OSC_HZ;
153 		break;
154 	default:
155 		return -ENOENT;
156 	}
157 
158 	return rate;
159 }
160 
161 static ulong rv1106_peri_set_clk(struct rv1106_clk_priv *priv,
162 				 ulong clk_id, ulong rate)
163 {
164 	struct rv1106_cru *cru = priv->cru;
165 	int src_clk;
166 
167 	switch (clk_id) {
168 	case ACLK_PERI_ROOT:
169 		if (rate >= 396 * MHz)
170 			src_clk = ACLK_PERI_SEL_400M;
171 		else if (rate >= 198 * MHz)
172 			src_clk = ACLK_PERI_SEL_200M;
173 		else if (rate >= 99 * MHz)
174 			src_clk = ACLK_PERI_SEL_100M;
175 		else
176 			src_clk = ACLK_PERI_SEL_24M;
177 		rk_clrsetreg(&cru->peri_clksel_con[1],
178 			     ACLK_PERI_SEL_MASK,
179 			     src_clk << ACLK_PERI_SEL_SHIFT);
180 		break;
181 	case HCLK_PERI_ROOT:
182 		if (rate >= 198 * MHz)
183 			src_clk = HCLK_PERI_SEL_200M;
184 		else if (rate >= 99 * MHz)
185 			src_clk = HCLK_PERI_SEL_100M;
186 		else if (rate >= 48 * MHz)
187 			src_clk = HCLK_PERI_SEL_50M;
188 		else
189 			src_clk = HCLK_PERI_SEL_24M;
190 		rk_clrsetreg(&cru->peri_clksel_con[1],
191 			     HCLK_PERI_SEL_MASK,
192 			     src_clk << HCLK_PERI_SEL_SHIFT);
193 		break;
194 	case PCLK_PERI_ROOT:
195 		if (rate >= 99 * MHz)
196 			src_clk = PCLK_PERI_SEL_100M;
197 		else if (rate >= 48 * MHz)
198 			src_clk = PCLK_PERI_SEL_50M;
199 		else
200 			src_clk = PCLK_PERI_SEL_24M;
201 		rk_clrsetreg(&cru->peri_clksel_con[1],
202 			     PCLK_PERI_SEL_MASK,
203 			     src_clk << PCLK_PERI_SEL_SHIFT);
204 		break;
205 	case ACLK_BUS_ROOT:
206 		if (rate >= 297 * MHz)
207 			src_clk = ACLK_BUS_SEL_300M;
208 		else if (rate >= 198 * MHz)
209 			src_clk = ACLK_BUS_SEL_200M;
210 		else if (rate >= 99 * MHz)
211 			src_clk = ACLK_BUS_SEL_100M;
212 		else
213 			src_clk = ACLK_BUS_SEL_24M;
214 		rk_clrsetreg(&cru->peri_clksel_con[9],
215 			     ACLK_BUS_SEL_MASK,
216 			     src_clk << ACLK_BUS_SEL_SHIFT);
217 		break;
218 	case PCLK_TOP_ROOT:
219 		if (rate >= 99 * MHz)
220 			src_clk = PCLK_TOP_SEL_100M;
221 		else if (rate >= 48 * MHz)
222 			src_clk = PCLK_TOP_SEL_50M;
223 		else
224 			src_clk = PCLK_TOP_SEL_24M;
225 		rk_clrsetreg(&cru->clksel_con[24],
226 			     PCLK_TOP_SEL_MASK,
227 			     src_clk << PCLK_TOP_SEL_SHIFT);
228 		break;
229 	case PCLK_PMU_ROOT:
230 		if (rate >= 99 * MHz)
231 			src_clk = PCLK_PMU_SEL_100M;
232 		else
233 			src_clk = PCLK_PMU_SEL_24M;
234 		rk_clrsetreg(&cru->pmu_clksel_con[0],
235 			     PCLK_PMU_SEL_MASK,
236 			     src_clk << PCLK_PMU_SEL_SHIFT);
237 		break;
238 	case HCLK_PMU_ROOT:
239 		if (rate >= 198 * MHz)
240 			src_clk = HCLK_PMU_SEL_200M;
241 		else if (rate >= 99 * MHz)
242 			src_clk = HCLK_PMU_SEL_100M;
243 		else
244 			src_clk = HCLK_PMU_SEL_24M;
245 		rk_clrsetreg(&cru->pmu_clksel_con[0],
246 			     HCLK_PMU_SEL_MASK,
247 			     src_clk << HCLK_PMU_SEL_SHIFT);
248 		break;
249 	default:
250 		printf("do not support this permid freq\n");
251 		return -EINVAL;
252 	}
253 
254 	return rv1106_peri_get_clk(priv, clk_id);
255 }
256 
257 static ulong rv1106_i2c_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
258 {
259 	struct rv1106_cru *cru = priv->cru;
260 	u32 sel, con;
261 	ulong rate;
262 
263 	switch (clk_id) {
264 	case CLK_I2C1:
265 		con = readl(&cru->pmu_clksel_con[0]);
266 		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
267 		if (sel == CLK_I2C1_SEL_200M)
268 			rate = 200 * MHz;
269 		else if (sel == CLK_I2C1_SEL_100M)
270 			rate = 100 * MHz;
271 		else if (sel == CLK_I2C1_SEL_24M)
272 			rate = OSC_HZ;
273 		else
274 			rate = 32768;
275 		return rate;
276 	case CLK_I2C0:
277 		con = readl(&cru->peri_clksel_con[1]);
278 		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
279 		break;
280 	case CLK_I2C2:
281 		con = readl(&cru->peri_clksel_con[1]);
282 		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
283 		break;
284 	case CLK_I2C3:
285 		con = readl(&cru->peri_clksel_con[1]);
286 		sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
287 		break;
288 	case CLK_I2C4:
289 		con = readl(&cru->peri_clksel_con[2]);
290 		sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
291 		break;
292 	default:
293 		return -ENOENT;
294 	}
295 
296 	if (sel == CLK_I2C0_SEL_200M)
297 		rate = 200 * MHz;
298 	else if (sel == CLK_I2C0_SEL_100M)
299 		rate = 100 * MHz;
300 	else if (sel == CLK_I2C0_SEL_50M)
301 		rate = 50 * MHz;
302 	else
303 		rate = OSC_HZ;
304 
305 	return rate;
306 }
307 #endif
308 
309 static ulong rv1106_crypto_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
310 {
311 	struct rv1106_cru *cru = priv->cru;
312 	u32 sel, con;
313 
314 	switch (clk_id) {
315 	case CLK_CORE_CRYPTO:
316 		con = readl(&cru->peri_clksel_con[6]);
317 		sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
318 		      CLK_CORE_CRYPTO_SEL_SHIFT;
319 		break;
320 	case CLK_PKA_CRYPTO:
321 		con = readl(&cru->peri_clksel_con[6]);
322 		sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
323 		      CLK_PKA_CRYPTO_SEL_SHIFT;
324 		break;
325 	default:
326 		return -ENOENT;
327 	}
328 	switch (sel) {
329 	case CLK_CRYPTO_SEL_300M:
330 		return 300 * MHz;
331 	case CLK_CRYPTO_SEL_200M:
332 		return 200 * MHz;
333 	case CLK_CRYPTO_SEL_100M:
334 		return 100 * MHz;
335 	case CLK_CRYPTO_SEL_24M:
336 		return OSC_HZ;
337 	default:
338 		return -ENOENT;
339 	}
340 }
341 
342 static ulong rv1106_crypto_set_clk(struct rv1106_clk_priv *priv,
343 				   ulong clk_id, ulong rate)
344 {
345 	struct rv1106_cru *cru = priv->cru;
346 	u32 sel;
347 
348 	if (rate >= 297 * MHz)
349 		sel = CLK_CRYPTO_SEL_300M;
350 	else if (rate >= 198 * MHz)
351 		sel = CLK_CRYPTO_SEL_200M;
352 	else if (rate >= 99 * MHz)
353 		sel = CLK_CRYPTO_SEL_100M;
354 	else
355 		sel = CLK_CRYPTO_SEL_24M;
356 
357 	switch (clk_id) {
358 	case CLK_CORE_CRYPTO:
359 		rk_clrsetreg(&cru->peri_clksel_con[6],
360 			     CLK_CORE_CRYPTO_SEL_MASK,
361 			     sel << CLK_CORE_CRYPTO_SEL_SHIFT);
362 		break;
363 	case CLK_PKA_CRYPTO:
364 		rk_clrsetreg(&cru->peri_clksel_con[6],
365 			     CLK_PKA_CRYPTO_SEL_MASK,
366 			     sel << CLK_PKA_CRYPTO_SEL_SHIFT);
367 		break;
368 	default:
369 		return -ENOENT;
370 	}
371 	return rv1106_crypto_get_clk(priv, clk_id);
372 }
373 
374 static ulong rv1106_mmc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
375 {
376 	struct rv1106_cru *cru = priv->cru;
377 	u32 div, sel, con, prate;
378 
379 	switch (clk_id) {
380 	case CCLK_SRC_SDMMC:
381 	case HCLK_SDMMC:
382 		con = readl(&cru->vi_clksel_con[1]);
383 		sel = (con & CLK_SDMMC_SEL_MASK) >>
384 		      CLK_SDMMC_SEL_SHIFT;
385 		div = (con & CLK_SDMMC_DIV_MASK) >>
386 		      CLK_SDMMC_DIV_SHIFT;
387 		if (sel == CLK_MMC_SEL_400M)
388 			prate = 400 * MHz;
389 		else
390 			prate = OSC_HZ;
391 		return DIV_TO_RATE(prate, div);
392 	case CCLK_SRC_EMMC:
393 	case HCLK_EMMC:
394 		con = readl(&cru->peri_clksel_con[7]);
395 		sel = (con & CLK_EMMC_SEL_MASK) >>
396 		      CLK_EMMC_SEL_SHIFT;
397 		div = (con & CLK_EMMC_DIV_MASK) >>
398 		      CLK_EMMC_DIV_SHIFT;
399 		if (sel)
400 			prate = OSC_HZ;
401 		else
402 			prate = 400 * MHz;
403 		return DIV_TO_RATE(prate, div);
404 	case SCLK_SFC:
405 	case HCLK_SFC:
406 		con = readl(&cru->peri_clksel_con[7]);
407 		sel = (con & CLK_SFC_SEL_MASK) >>
408 		      CLK_SFC_SEL_SHIFT;
409 		div = (con & CLK_SFC_DIV_MASK) >>
410 		      CLK_SFC_DIV_SHIFT;
411 		if (sel == CLK_SFC_SEL_500M)
412 			prate = 500 * MHz;
413 		else if (sel == CLK_SFC_SEL_300M)
414 			prate = 300 * MHz;
415 		else if (sel == CLK_SFC_SEL_200M)
416 			prate = 200 * MHz;
417 		else
418 			prate = OSC_HZ;
419 		return DIV_TO_RATE(prate, div);
420 	default:
421 		return -ENOENT;
422 	}
423 }
424 
425 static ulong rv1106_mmc_set_clk(struct rv1106_clk_priv *priv,
426 				ulong clk_id, ulong rate)
427 {
428 	struct rv1106_cru *cru = priv->cru;
429 	u32 sel, src_clk_div;
430 	ulong prate = 0;
431 
432 	if ((OSC_HZ % rate) == 0) {
433 		sel = CLK_MMC_SEL_24M;
434 		prate = OSC_HZ;
435 	} else {
436 		sel = CLK_MMC_SEL_400M;
437 		prate = 400 * MHz;
438 	}
439 	src_clk_div = DIV_ROUND_UP(prate, rate);
440 
441 	switch (clk_id) {
442 	case CCLK_SRC_SDMMC:
443 	case HCLK_SDMMC:
444 		if ((OSC_HZ % rate) == 0) {
445 			sel = CLK_MMC_SEL_24M;
446 			prate = OSC_HZ;
447 		} else {
448 			sel = CLK_MMC_SEL_400M;
449 			prate = 400 * MHz;
450 		}
451 		src_clk_div = DIV_ROUND_UP(prate, rate);
452 		rk_clrsetreg(&cru->vi_clksel_con[1],
453 			     CLK_SDMMC_SEL_MASK |
454 			     CLK_SDMMC_DIV_MASK,
455 			     (sel << CLK_SDMMC_SEL_SHIFT) |
456 			     ((src_clk_div - 1) <<
457 			      CLK_SDMMC_DIV_SHIFT));
458 		break;
459 	case CCLK_SRC_EMMC:
460 	case HCLK_EMMC:
461 		if ((OSC_HZ % rate) == 0) {
462 			sel = CLK_MMC_SEL_24M;
463 			prate = OSC_HZ;
464 		} else {
465 			sel = CLK_MMC_SEL_400M;
466 			prate = 400 * MHz;
467 		}
468 		src_clk_div = DIV_ROUND_UP(prate, rate);
469 		rk_clrsetreg(&cru->peri_clksel_con[7],
470 			     CLK_EMMC_SEL_MASK |
471 			     CLK_EMMC_DIV_MASK,
472 			     (sel << CLK_EMMC_SEL_SHIFT) |
473 			     ((src_clk_div - 1) <<
474 			      CLK_EMMC_DIV_SHIFT));
475 		break;
476 	case SCLK_SFC:
477 	case HCLK_SFC:
478 		if ((OSC_HZ % rate) == 0) {
479 			sel = CLK_SFC_SEL_24M;
480 			prate = OSC_HZ;
481 		} else if ((500 * MHz % rate) == 0) {
482 			sel = CLK_SFC_SEL_500M;
483 			prate = 500 * MHz;
484 		} else if ((300 * MHz % rate) == 0) {
485 			sel = CLK_SFC_SEL_300M;
486 			prate = 300 * MHz;
487 		} else {
488 			sel = CLK_SFC_SEL_200M;
489 			prate = 200 * MHz;
490 		}
491 		src_clk_div = DIV_ROUND_UP(prate, rate);
492 		rk_clrsetreg(&cru->peri_clksel_con[7],
493 			     CLK_SFC_SEL_MASK |
494 			     CLK_SFC_DIV_MASK,
495 			     (sel << CLK_SFC_SEL_SHIFT) |
496 			     ((src_clk_div - 1) <<
497 			      CLK_SFC_DIV_SHIFT));
498 		break;
499 	default:
500 		return -ENOENT;
501 	}
502 	return rv1106_mmc_get_clk(priv, clk_id);
503 }
504 
505 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
506 static ulong rv1106_i2c_set_clk(struct rv1106_clk_priv *priv, ulong clk_id,
507 				ulong rate)
508 {
509 	struct rv1106_cru *cru = priv->cru;
510 	int src_clk;
511 
512 	if (rate >= 198 * MHz)
513 		src_clk = CLK_I2C0_SEL_200M;
514 	else if (rate >= 99 * MHz)
515 		src_clk = CLK_I2C0_SEL_100M;
516 	else if (rate >= 48 * MHz)
517 		src_clk = CLK_I2C0_SEL_50M;
518 	else
519 		src_clk = CLK_I2C0_SEL_24M;
520 
521 	switch (clk_id) {
522 	case CLK_I2C1:
523 		if (rate >= 198 * MHz)
524 			src_clk = CLK_I2C1_SEL_200M;
525 		else if (rate >= 99 * MHz)
526 			src_clk = CLK_I2C1_SEL_100M;
527 		else if (rate >= 24 * MHz)
528 			src_clk = CLK_I2C1_SEL_24M;
529 		else
530 			src_clk = CLK_I2C1_SEL_32K;
531 		rk_clrsetreg(&cru->clksel_con[71], CLK_I2C1_SEL_MASK,
532 			     src_clk << CLK_I2C1_SEL_SHIFT);
533 		return rv1106_i2c_get_clk(priv, clk_id);
534 	case CLK_I2C0:
535 		rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C0_SEL_MASK,
536 			     src_clk << CLK_I2C0_SEL_SHIFT);
537 		break;
538 	case CLK_I2C2:
539 		rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C2_SEL_MASK,
540 			     src_clk << CLK_I2C2_SEL_SHIFT);
541 		break;
542 	case CLK_I2C3:
543 		rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C3_SEL_MASK,
544 			     src_clk << CLK_I2C3_SEL_SHIFT);
545 		break;
546 	case CLK_I2C4:
547 		rk_clrsetreg(&cru->peri_clksel_con[2], CLK_I2C4_SEL_MASK,
548 			     src_clk << CLK_I2C4_SEL_SHIFT);
549 		break;
550 	default:
551 		return -ENOENT;
552 	}
553 
554 	return rv1106_i2c_get_clk(priv, clk_id);
555 }
556 #endif
557 
558 static ulong rv1106_spi_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
559 {
560 	struct rv1106_cru *cru = priv->cru;
561 	u32 sel, con, rate;
562 
563 	switch (clk_id) {
564 	case CLK_SPI0:
565 		con = readl(&cru->vepu_clksel_con[0]);
566 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
567 		break;
568 	case CLK_SPI1:
569 		con = readl(&cru->peri_clksel_con[6]);
570 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
571 		break;
572 	default:
573 		return -ENOENT;
574 	}
575 	if (sel == CLK_SPI0_SEL_200M)
576 		rate = 200 * MHz;
577 	else if (sel == CLK_SPI0_SEL_100M)
578 		rate = 100 * MHz;
579 	else if (sel == CLK_SPI0_SEL_50M)
580 		rate = 50 * MHz;
581 	else
582 		rate = OSC_HZ;
583 
584 	return rate;
585 }
586 
587 static ulong rv1106_spi_set_clk(struct rv1106_clk_priv *priv,
588 				ulong clk_id, ulong rate)
589 {
590 	struct rv1106_cru *cru = priv->cru;
591 	int src_clk;
592 
593 	if (rate >= 198 * MHz)
594 		src_clk = CLK_SPI0_SEL_200M;
595 	else if (rate >= 99 * MHz)
596 		src_clk = CLK_SPI0_SEL_100M;
597 	else if (rate >= 48 * MHz)
598 		src_clk = CLK_SPI0_SEL_50M;
599 	else
600 		src_clk = CLK_SPI0_SEL_24M;
601 
602 	switch (clk_id) {
603 	case CLK_SPI0:
604 		rk_clrsetreg(&cru->vepu_clksel_con[0], CLK_SPI0_SEL_MASK,
605 			     src_clk << CLK_SPI0_SEL_SHIFT);
606 		break;
607 	case CLK_SPI1:
608 		rk_clrsetreg(&cru->peri_clksel_con[6], CLK_SPI1_SEL_MASK,
609 			     src_clk << CLK_SPI1_SEL_SHIFT);
610 		break;
611 	default:
612 		return -ENOENT;
613 	}
614 
615 	return rv1106_spi_get_clk(priv, clk_id);
616 }
617 
618 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
619 static ulong rv1106_pwm_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
620 {
621 	struct rv1106_cru *cru = priv->cru;
622 	u32 sel, con;
623 
624 	switch (clk_id) {
625 	case CLK_PWM0_PERI:
626 		con = readl(&cru->peri_clksel_con[11]);
627 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
628 		break;
629 	case CLK_PWM1_PERI:
630 		con = readl(&cru->peri_clksel_con[6]);
631 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
632 		break;
633 	case CLK_PWM2_PERI:
634 		con = readl(&cru->peri_clksel_con[6]);
635 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
636 		break;
637 	default:
638 		return -ENOENT;
639 	}
640 
641 	switch (sel) {
642 	case CLK_PWM_SEL_100M:
643 		return 100 * MHz;
644 	case CLK_PWM_SEL_50M:
645 		return 100 * MHz;
646 	case CLK_PWM_SEL_24M:
647 		return OSC_HZ;
648 	default:
649 		return -ENOENT;
650 	}
651 }
652 
653 static ulong rv1106_pwm_set_clk(struct rv1106_clk_priv *priv,
654 				ulong clk_id, ulong rate)
655 {
656 	struct rv1106_cru *cru = priv->cru;
657 	int src_clk;
658 
659 	if (rate >= 99 * MHz)
660 		src_clk = CLK_PWM_SEL_100M;
661 	else if (rate >= 48 * MHz)
662 		src_clk = CLK_PWM_SEL_50M;
663 	else
664 		src_clk = CLK_PWM_SEL_24M;
665 
666 	switch (clk_id) {
667 	case CLK_PWM0_PERI:
668 		rk_clrsetreg(&cru->peri_clksel_con[11],
669 			     CLK_PWM0_SEL_MASK,
670 			     src_clk << CLK_PWM0_SEL_SHIFT);
671 		break;
672 	case CLK_PWM1_PERI:
673 		rk_clrsetreg(&cru->peri_clksel_con[6],
674 			     CLK_PWM1_SEL_MASK,
675 			     src_clk << CLK_PWM1_SEL_SHIFT);
676 		break;
677 	case CLK_PWM2_PERI:
678 		rk_clrsetreg(&cru->peri_clksel_con[6],
679 			     CLK_PWM2_SEL_MASK,
680 			     src_clk << CLK_PWM2_SEL_SHIFT);
681 		break;
682 	default:
683 		return -ENOENT;
684 	}
685 
686 	return rv1106_pwm_get_clk(priv, clk_id);
687 }
688 #endif
689 
690 static ulong rv1106_adc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
691 {
692 	struct rv1106_cru *cru = priv->cru;
693 	u32 div, con;
694 
695 	switch (clk_id) {
696 	case CLK_SARADC:
697 		con = readl(&cru->peri_clksel_con[6]);
698 		div = (con & CLK_SARADC_DIV_MASK) >>
699 		      CLK_SARADC_DIV_SHIFT;
700 		return DIV_TO_RATE(OSC_HZ, div);
701 	case CLK_TSADC_TSEN:
702 		con = readl(&cru->vo_clksel_con[3]);
703 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
704 		      CLK_TSADC_TSEN_DIV_SHIFT;
705 		return DIV_TO_RATE(OSC_HZ, div);
706 	case CLK_TSADC:
707 		con = readl(&cru->vo_clksel_con[3]);
708 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
709 		return DIV_TO_RATE(OSC_HZ, div);
710 	default:
711 		return -ENOENT;
712 	}
713 }
714 
715 static ulong rv1106_adc_set_clk(struct rv1106_clk_priv *priv,
716 				ulong clk_id, ulong rate)
717 {
718 	struct rv1106_cru *cru = priv->cru;
719 	int src_clk_div;
720 
721 	src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
722 
723 	switch (clk_id) {
724 	case CLK_SARADC:
725 		assert(src_clk_div - 1 <= 7);
726 		rk_clrsetreg(&cru->peri_clksel_con[6],
727 			     CLK_SARADC_DIV_MASK,
728 			     (src_clk_div - 1) <<
729 			     CLK_SARADC_DIV_MASK);
730 		break;
731 	case CLK_TSADC_TSEN:
732 		assert(src_clk_div - 1 <= 128);
733 		rk_clrsetreg(&cru->vo_clksel_con[3],
734 			     CLK_TSADC_TSEN_DIV_MASK,
735 			     (src_clk_div - 1) <<
736 			     CLK_TSADC_TSEN_DIV_SHIFT);
737 		break;
738 	case CLK_TSADC:
739 		assert(src_clk_div - 1 <= 128);
740 		rk_clrsetreg(&cru->vo_clksel_con[3],
741 			     CLK_TSADC_DIV_MASK,
742 			     (src_clk_div - 1) <<
743 			     CLK_TSADC_DIV_SHIFT);
744 		break;
745 	default:
746 		return -ENOENT;
747 	}
748 	return rv1106_adc_get_clk(priv, clk_id);
749 }
750 
751 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
752 /*
753  *
754  * rational_best_approximation(31415, 10000,
755  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
756  *
757  * you may look at given_numerator as a fixed point number,
758  * with the fractional part size described in given_denominator.
759  *
760  * for theoretical background, see:
761  * http://en.wikipedia.org/wiki/Continued_fraction
762  */
763 static void rational_best_approximation(unsigned long given_numerator,
764 					unsigned long given_denominator,
765 					unsigned long max_numerator,
766 					unsigned long max_denominator,
767 					unsigned long *best_numerator,
768 					unsigned long *best_denominator)
769 {
770 	unsigned long n, d, n0, d0, n1, d1;
771 
772 	n = given_numerator;
773 	d = given_denominator;
774 	n0 = 0;
775 	d1 = 0;
776 	n1 = 1;
777 	d0 = 1;
778 	for (;;) {
779 		unsigned long t, a;
780 
781 		if (n1 > max_numerator || d1 > max_denominator) {
782 			n1 = n0;
783 			d1 = d0;
784 			break;
785 		}
786 		if (d == 0)
787 			break;
788 		t = d;
789 		a = n / d;
790 		d = n % d;
791 		n = t;
792 		t = n0 + a * n1;
793 		n0 = n1;
794 		n1 = t;
795 		t = d0 + a * d1;
796 		d0 = d1;
797 		d1 = t;
798 	}
799 	*best_numerator = n1;
800 	*best_denominator = d1;
801 }
802 
803 static ulong rv1106_uart_get_rate(struct rv1106_clk_priv *priv, ulong clk_id)
804 {
805 	struct rv1106_cru *cru = priv->cru;
806 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
807 	unsigned long m, n;
808 
809 	switch (clk_id) {
810 	case SCLK_UART0:
811 		reg = 5;
812 		break;
813 	case SCLK_UART1:
814 		reg = 7;
815 		break;
816 	case SCLK_UART2:
817 		reg = 9;
818 		break;
819 	case SCLK_UART3:
820 		reg = 11;
821 		break;
822 	case SCLK_UART4:
823 		reg = 13;
824 		break;
825 	case SCLK_UART5:
826 		reg = 15;
827 		break;
828 	default:
829 		return -ENOENT;
830 	}
831 	con = readl(&cru->clksel_con[reg + 2]);
832 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
833 	con = readl(&cru->clksel_con[reg]);
834 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
835 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
836 	if (p_src == CLK_UART_SRC_SEL_GPLL)
837 		p_rate = priv->gpll_hz;
838 	else if (p_src == CLK_UART_SRC_SEL_CPLL)
839 		p_rate = priv->cpll_hz;
840 	else
841 		p_rate = 480000000;
842 	if (src == CLK_UART_SEL_SRC) {
843 		return DIV_TO_RATE(p_rate, div);
844 	} else if (src == CLK_UART_SEL_FRAC) {
845 		fracdiv = readl(&cru->clksel_con[reg + 1]);
846 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
847 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
848 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
849 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
850 		return DIV_TO_RATE(p_rate, div) * n / m;
851 	} else {
852 		return OSC_HZ;
853 	}
854 }
855 
856 static ulong rv1106_uart_set_rate(struct rv1106_clk_priv *priv,
857 				  ulong clk_id, ulong rate)
858 {
859 	struct rv1106_cru *cru = priv->cru;
860 	u32 reg, clk_src, uart_src, div;
861 	unsigned long m = 0, n = 0, val;
862 
863 	if (priv->gpll_hz % rate == 0) {
864 		clk_src = CLK_UART_SRC_SEL_GPLL;
865 		uart_src = CLK_UART_SEL_SRC;
866 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
867 	} else if (priv->cpll_hz % rate == 0) {
868 		clk_src = CLK_UART_SRC_SEL_CPLL;
869 		uart_src = CLK_UART_SEL_SRC;
870 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
871 	} else if (rate == OSC_HZ) {
872 		clk_src = CLK_UART_SRC_SEL_GPLL;
873 		uart_src = CLK_UART_SEL_XIN24M;
874 		div = 2;
875 	} else {
876 		clk_src = CLK_UART_SRC_SEL_GPLL;
877 		uart_src = CLK_UART_SEL_FRAC;
878 		div = 2;
879 		rational_best_approximation(rate, priv->gpll_hz / div,
880 					    GENMASK(16 - 1, 0),
881 					    GENMASK(16 - 1, 0),
882 					    &m, &n);
883 	}
884 
885 	switch (clk_id) {
886 	case SCLK_UART0:
887 		reg = 5;
888 		break;
889 	case SCLK_UART1:
890 		reg = 7;
891 		break;
892 	case SCLK_UART2:
893 		reg = 9;
894 		break;
895 	case SCLK_UART3:
896 		reg = 11;
897 		break;
898 	case SCLK_UART4:
899 		reg = 13;
900 		break;
901 	case SCLK_UART5:
902 		reg = 15;
903 		break;
904 	default:
905 		return -ENOENT;
906 	}
907 	rk_clrsetreg(&cru->clksel_con[reg],
908 		     CLK_UART_SRC_SEL_MASK |
909 		     CLK_UART_SRC_DIV_MASK,
910 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
911 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
912 	rk_clrsetreg(&cru->clksel_con[reg + 2],
913 		     CLK_UART_SEL_MASK,
914 		     uart_src << CLK_UART_SEL_SHIFT);
915 	if (m && n) {
916 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
917 		writel(val, &cru->clksel_con[reg + 1]);
918 	}
919 
920 	return rv1106_uart_get_rate(priv, clk_id);
921 }
922 
923 static ulong rv1106_vop_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
924 {
925 	struct rv1106_cru *cru = priv->cru;
926 	u32 div, sel, con;
927 
928 	switch (clk_id) {
929 	case ACLK_VOP_ROOT:
930 	case ACLK_VOP:
931 		con = readl(&cru->vo_clksel_con[1]);
932 		sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT;
933 		if (sel == ACLK_VOP_SEL_300M)
934 			return 300 * MHz;
935 		else if (sel == ACLK_VOP_SEL_200M)
936 			return 200 * MHz;
937 		else if (sel == ACLK_VOP_SEL_100M)
938 			return 100 * MHz;
939 		else
940 			return  OSC_HZ;
941 	case DCLK_VOP_SRC:
942 	case DCLK_VOP:
943 		con = readl(&cru->clksel_con[23]);
944 		sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
945 		div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
946 		if (sel == DCLK_VOP_SEL_GPLL)
947 			return DIV_TO_RATE(priv->gpll_hz, div);
948 		else
949 			return DIV_TO_RATE(priv->cpll_hz, div);
950 	default:
951 		return -ENOENT;
952 	}
953 }
954 
955 static ulong rv1106_vop_set_clk(struct rv1106_clk_priv *priv,
956 				ulong clk_id, ulong rate)
957 {
958 	struct rv1106_cru *cru = priv->cru;
959 	int div, sel;
960 
961 	switch (clk_id) {
962 	case ACLK_VOP_ROOT:
963 	case ACLK_VOP:
964 		if (rate >= 297 * MHz)
965 			sel = ACLK_VOP_SEL_300M;
966 		else if (rate >= 198 * MHz)
967 			sel = ACLK_VOP_SEL_200M;
968 		else if (rate >= 99 * MHz)
969 			sel = ACLK_VOP_SEL_100M;
970 		else
971 			sel = ACLK_VOP_SEL_24M;
972 		rk_clrsetreg(&cru->vo_clksel_con[1],
973 			     ACLK_VOP_SEL_MASK,
974 			     sel << ACLK_VOP_SEL_SHIFT);
975 		break;
976 	case DCLK_VOP_SRC:
977 	case DCLK_VOP:
978 		if ((priv->cpll_hz % rate) == 0) {
979 			sel = DCLK_VOP_SEL_CPLL;
980 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
981 		} else {
982 			sel = DCLK_VOP_SEL_GPLL;
983 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
984 		}
985 		rk_clrsetreg(&cru->clksel_con[23],
986 			     DCLK_VOP_SEL_MASK |
987 			     DCLK_VOP_DIV_MASK,
988 			     sel << DCLK_VOP_SEL_SHIFT |
989 			     (div - 1) << DCLK_VOP_DIV_SHIFT);
990 		break;
991 	default:
992 		return -ENOENT;
993 	}
994 
995 	return rv1106_vop_get_clk(priv, clk_id);
996 }
997 #endif
998 
999 static ulong rv1106_clk_get_rate(struct clk *clk)
1000 {
1001 	struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1002 	ulong rate = 0;
1003 
1004 	if (!priv->gpll_hz) {
1005 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1006 		return -ENOENT;
1007 	}
1008 
1009 	switch (clk->id) {
1010 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1011 	case PLL_APLL:
1012 		rate = rockchip_pll_get_rate(&rv1106_pll_clks[APLL], priv->cru,
1013 					     APLL);
1014 		break;
1015 	case PLL_DPLL:
1016 		rate = rockchip_pll_get_rate(&rv1106_pll_clks[DPLL], priv->cru,
1017 					     DPLL);
1018 		break;
1019 	case PLL_CPLL:
1020 		rate = rockchip_pll_get_rate(&rv1106_pll_clks[CPLL], priv->cru,
1021 					     CPLL);
1022 		break;
1023 	case PLL_GPLL:
1024 		rate = rockchip_pll_get_rate(&rv1106_pll_clks[GPLL], priv->cru,
1025 					     GPLL);
1026 		break;
1027 	case ACLK_PERI_ROOT:
1028 	case HCLK_PERI_ROOT:
1029 	case PCLK_PERI_ROOT:
1030 	case ACLK_BUS_ROOT:
1031 	case PCLK_TOP_ROOT:
1032 	case PCLK_PMU_ROOT:
1033 	case HCLK_PMU_ROOT:
1034 		rate = rv1106_peri_get_clk(priv, clk->id);
1035 		break;
1036 #endif
1037 	case CLK_CORE_CRYPTO:
1038 	case CLK_PKA_CRYPTO:
1039 	case ACLK_CRYPTO:
1040 		rate = rv1106_crypto_get_clk(priv, clk->id);
1041 		break;
1042 	case CCLK_SRC_SDMMC:
1043 	case CCLK_SRC_EMMC:
1044 	case SCLK_SFC:
1045 	case HCLK_SDMMC:
1046 	case HCLK_EMMC:
1047 	case HCLK_SFC:
1048 		rate = rv1106_mmc_get_clk(priv, clk->id);
1049 		break;
1050 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1051 	case CLK_I2C0:
1052 	case CLK_I2C1:
1053 	case CLK_I2C2:
1054 	case CLK_I2C3:
1055 	case CLK_I2C4:
1056 		rate = rv1106_i2c_get_clk(priv, clk->id);
1057 		break;
1058 #endif
1059 	case CLK_SPI0:
1060 	case CLK_SPI1:
1061 		rate = rv1106_spi_get_clk(priv, clk->id);
1062 		break;
1063 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1064 	case CLK_PWM0_PERI:
1065 	case CLK_PWM1_PERI:
1066 	case CLK_PWM2_PERI:
1067 		rate = rv1106_pwm_get_clk(priv, clk->id);
1068 		break;
1069 #endif
1070 	case CLK_SARADC:
1071 	case CLK_TSADC_TSEN:
1072 	case CLK_TSADC:
1073 		rate = rv1106_adc_get_clk(priv, clk->id);
1074 		break;
1075 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1076 	case SCLK_UART0:
1077 	case SCLK_UART1:
1078 	case SCLK_UART2:
1079 	case SCLK_UART3:
1080 	case SCLK_UART4:
1081 	case SCLK_UART5:
1082 		rate = rv1106_uart_get_rate(priv, clk->id);
1083 		break;
1084 	case DCLK_VOP_SRC:
1085 	case DCLK_VOP:
1086 	case ACLK_VOP_ROOT:
1087 	case ACLK_VOP:
1088 		rate = rv1106_vop_get_clk(priv, clk->id);
1089 		break;
1090 #endif
1091 	default:
1092 		return -ENOENT;
1093 	}
1094 
1095 	return rate;
1096 };
1097 
1098 static ulong rv1106_clk_set_rate(struct clk *clk, ulong rate)
1099 {
1100 	struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1101 	ulong ret = 0;
1102 
1103 	if (!priv->gpll_hz) {
1104 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1105 		return -ENOENT;
1106 	}
1107 
1108 	switch (clk->id) {
1109 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1110 	case PLL_APLL:
1111 		ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1112 					    APLL, rate);
1113 		break;
1114 	case PLL_CPLL:
1115 		ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1116 					    CPLL, rate);
1117 		break;
1118 	case PLL_GPLL:
1119 		ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1120 					    GPLL, rate);
1121 		break;
1122 	case ACLK_PERI_ROOT:
1123 	case HCLK_PERI_ROOT:
1124 	case PCLK_PERI_ROOT:
1125 	case ACLK_BUS_ROOT:
1126 	case PCLK_TOP_ROOT:
1127 	case PCLK_PMU_ROOT:
1128 	case HCLK_PMU_ROOT:
1129 		ret = rv1106_peri_set_clk(priv, clk->id, rate);
1130 		break;
1131 #endif
1132 	case CLK_CORE_CRYPTO:
1133 	case CLK_PKA_CRYPTO:
1134 	case ACLK_CRYPTO:
1135 		ret = rv1106_crypto_set_clk(priv, clk->id, rate);
1136 		break;
1137 	case CCLK_SRC_SDMMC:
1138 	case CCLK_SRC_EMMC:
1139 	case SCLK_SFC:
1140 	case HCLK_SDMMC:
1141 	case HCLK_EMMC:
1142 	case HCLK_SFC:
1143 		ret = rv1106_mmc_set_clk(priv, clk->id, rate);
1144 		break;
1145 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1146 	case CLK_I2C0:
1147 	case CLK_I2C1:
1148 	case CLK_I2C2:
1149 	case CLK_I2C3:
1150 	case CLK_I2C4:
1151 		ret = rv1106_i2c_set_clk(priv, clk->id, rate);
1152 		break;
1153 #endif
1154 	case CLK_SPI0:
1155 	case CLK_SPI1:
1156 		ret = rv1106_spi_set_clk(priv, clk->id, rate);
1157 		break;
1158 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1159 	case CLK_PWM0_PERI:
1160 	case CLK_PWM1_PERI:
1161 	case CLK_PWM2_PERI:
1162 		ret = rv1106_pwm_set_clk(priv, clk->id, rate);
1163 		break;
1164 #endif
1165 	case CLK_SARADC:
1166 	case CLK_TSADC_TSEN:
1167 	case CLK_TSADC:
1168 		ret = rv1106_adc_set_clk(priv, clk->id, rate);
1169 		break;
1170 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1171 	case SCLK_UART0:
1172 	case SCLK_UART1:
1173 	case SCLK_UART2:
1174 	case SCLK_UART3:
1175 	case SCLK_UART4:
1176 	case SCLK_UART5:
1177 		ret = rv1106_uart_set_rate(priv, clk->id, rate);
1178 		break;
1179 	case DCLK_VOP_SRC:
1180 	case DCLK_VOP:
1181 	case ACLK_VOP_ROOT:
1182 	case ACLK_VOP:
1183 		rate = rv1106_vop_set_clk(priv, clk->id, rate);
1184 		break;
1185 #endif
1186 	default:
1187 		return -ENOENT;
1188 	}
1189 
1190 	return ret;
1191 };
1192 
1193 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1194 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1195 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1196 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1197 
1198 #define PSECS_PER_SEC 1000000000000LL
1199 /*
1200  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1201  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1202  */
1203 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1204 
1205 int rv1106_mmc_get_phase(struct clk *clk)
1206 {
1207 	struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1208 	struct rv1106_cru *cru = priv->cru;
1209 	u32 raw_value = 0, delay_num;
1210 	u16 degrees = 0;
1211 	ulong rate;
1212 
1213 	rate = rv1106_clk_get_rate(clk);
1214 	if (rate < 0)
1215 		return rate;
1216 
1217 	if (clk->id == SCLK_EMMC_SAMPLE)
1218 		raw_value = readl(&cru->emmc_con[1]);
1219 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1220 		raw_value = readl(&cru->sdmmc_con[1]);
1221 
1222 	raw_value >>= 1;
1223 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1224 
1225 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1226 		/* degrees/delaynum * 10000 */
1227 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1228 					36 * (rate / 1000000);
1229 
1230 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1231 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1232 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1233 	}
1234 
1235 	return degrees % 360;
1236 }
1237 
1238 int rv1106_mmc_set_phase(struct clk *clk, u32 degrees)
1239 {
1240 	struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1241 	struct rv1106_cru *cru = priv->cru;
1242 	u8 nineties, remainder, delay_num;
1243 	u32 raw_value, delay;
1244 	ulong rate;
1245 
1246 	rate = rv1106_clk_get_rate(clk);
1247 	if (rate < 0)
1248 		return rate;
1249 
1250 	nineties = degrees / 90;
1251 	remainder = (degrees % 90);
1252 
1253 	/*
1254 	 * Convert to delay; do a little extra work to make sure we
1255 	 * don't overflow 32-bit / 64-bit numbers.
1256 	 */
1257 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1258 	delay *= remainder;
1259 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1260 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1261 
1262 	delay_num = (u8)min_t(u32, delay, 255);
1263 
1264 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1265 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1266 	raw_value |= nineties;
1267 
1268 	raw_value <<= 1;
1269 	if (clk->id == SCLK_EMMC_SAMPLE)
1270 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1271 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1272 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1273 
1274 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1275 	      degrees, delay_num, raw_value, rv1106_mmc_get_phase(clk));
1276 
1277 	return 0;
1278 }
1279 
1280 static int rv1106_clk_get_phase(struct clk *clk)
1281 {
1282 	int ret;
1283 
1284 	debug("%s %ld\n", __func__, clk->id);
1285 	switch (clk->id) {
1286 	case SCLK_EMMC_SAMPLE:
1287 	case SCLK_SDMMC_SAMPLE:
1288 		ret = rv1106_mmc_get_phase(clk);
1289 		break;
1290 	default:
1291 		return -ENOENT;
1292 	}
1293 	return ret;
1294 }
1295 
1296 static int rv1106_clk_set_phase(struct clk *clk, int degrees)
1297 {
1298 	int ret;
1299 
1300 	debug("%s %ld\n", __func__, clk->id);
1301 	switch (clk->id) {
1302 	case SCLK_EMMC_SAMPLE:
1303 	case SCLK_SDMMC_SAMPLE:
1304 		ret = rv1106_mmc_set_phase(clk, degrees);
1305 		break;
1306 	default:
1307 		return -ENOENT;
1308 	}
1309 
1310 	return ret;
1311 }
1312 
1313 static int rv1106_clk_set_parent(struct clk *clk, struct clk *parent)
1314 {
1315 	switch (clk->id) {
1316 	default:
1317 		return -ENOENT;
1318 	}
1319 
1320 	return 0;
1321 }
1322 
1323 static struct clk_ops rv1106_clk_ops = {
1324 	.get_rate = rv1106_clk_get_rate,
1325 	.set_rate = rv1106_clk_set_rate,
1326 	.get_phase = rv1106_clk_get_phase,
1327 	.set_phase = rv1106_clk_set_phase,
1328 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1329 	.set_parent = rv1106_clk_set_parent,
1330 #endif
1331 };
1332 
1333 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1334 static void rv1106_clk_init(struct rv1106_clk_priv *priv)
1335 {
1336 	int ret;
1337 
1338 	priv->sync_kernel = false;
1339 	if (!priv->armclk_enter_hz) {
1340 		priv->armclk_enter_hz =
1341 			rockchip_pll_get_rate(&rv1106_pll_clks[APLL],
1342 					      priv->cru, APLL);
1343 		priv->armclk_init_hz = priv->armclk_enter_hz;
1344 	}
1345 
1346 	if (priv->armclk_init_hz != APLL_HZ) {
1347 			ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1348 						    APLL, APLL_HZ);
1349 		if (!ret)
1350 			priv->armclk_init_hz = APLL_HZ;
1351 	}
1352 
1353 	if (priv->cpll_hz != CPLL_HZ) {
1354 		ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1355 					    CPLL, CPLL_HZ);
1356 		if (!ret)
1357 			priv->cpll_hz = CPLL_HZ;
1358 	}
1359 
1360 	if (priv->gpll_hz != GPLL_HZ) {
1361 		ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1362 					    GPLL, GPLL_HZ);
1363 		if (!ret)
1364 			priv->gpll_hz = GPLL_HZ;
1365 	}
1366 }
1367 #endif
1368 
1369 static int rv1106_clk_probe(struct udevice *dev)
1370 {
1371 	struct rv1106_clk_priv *priv = dev_get_priv(dev);
1372 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1373 	int ret;
1374 
1375 	rv1106_clk_init(priv);
1376 
1377 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1378 	ret = clk_set_defaults(dev);
1379 	if (ret)
1380 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1381 	else
1382 		priv->sync_kernel = true;
1383 #else
1384 	priv->gpll_hz = GPLL_HZ;
1385 	priv->cpll_hz = CPLL_HZ;
1386 #endif
1387 	return 0;
1388 }
1389 
1390 static int rv1106_clk_ofdata_to_platdata(struct udevice *dev)
1391 {
1392 	struct rv1106_clk_priv *priv = dev_get_priv(dev);
1393 
1394 	priv->cru = dev_read_addr_ptr(dev);
1395 
1396 	return 0;
1397 }
1398 
1399 static int rv1106_clk_bind(struct udevice *dev)
1400 {
1401 	int ret;
1402 	struct udevice *sys_child, *sf_child;
1403 	struct sysreset_reg *priv;
1404 	struct softreset_reg *sf_priv;
1405 
1406 	/* The reset driver does not have a device node, so bind it here */
1407 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1408 				 &sys_child);
1409 	if (ret) {
1410 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1411 	} else {
1412 		priv = malloc(sizeof(struct sysreset_reg));
1413 		priv->glb_srst_fst_value = offsetof(struct rv1106_cru,
1414 						    glb_srst_fst);
1415 		priv->glb_srst_snd_value = offsetof(struct rv1106_cru,
1416 						    glb_srst_snd);
1417 		sys_child->priv = priv;
1418 	}
1419 
1420 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1421 					 dev_ofnode(dev), &sf_child);
1422 	if (ret) {
1423 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1424 	} else {
1425 		sf_priv = malloc(sizeof(struct softreset_reg));
1426 		sf_priv->sf_reset_offset = offsetof(struct rv1106_cru,
1427 						    pmu_softrst_con[0]);
1428 		sf_priv->sf_reset_num = 31745;
1429 		sf_child->priv = sf_priv;
1430 	}
1431 
1432 	return 0;
1433 }
1434 
1435 static const struct udevice_id rv1106_clk_ids[] = {
1436 	{ .compatible = "rockchip,rv1106-cru" },
1437 	{ }
1438 };
1439 
1440 U_BOOT_DRIVER(rockchip_rv1106_cru) = {
1441 	.name		= "rockchip_rv1106_cru",
1442 	.id		= UCLASS_CLK,
1443 	.of_match	= rv1106_clk_ids,
1444 	.priv_auto_alloc_size = sizeof(struct rv1106_clk_priv),
1445 	.ofdata_to_platdata = rv1106_clk_ofdata_to_platdata,
1446 	.ops		= &rv1106_clk_ops,
1447 	.bind		= rv1106_clk_bind,
1448 	.probe		= rv1106_clk_probe,
1449 };
1450 
1451 #ifndef CONFIG_SPL_BUILD
1452 /**
1453  * soc_clk_dump() - Print clock frequencies
1454  * Returns zero on success
1455  *
1456  * Implementation for the clk dump command.
1457  */
1458 int soc_clk_dump(void)
1459 {
1460 	struct udevice *cru_dev;
1461 	struct rv1106_clk_priv *priv;
1462 	const struct rv1106_clk_info *clk_dump;
1463 	struct clk clk;
1464 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1465 	unsigned long rate;
1466 	int i, ret;
1467 
1468 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1469 					  DM_GET_DRIVER(rockchip_rv1106_cru),
1470 					  &cru_dev);
1471 	if (ret) {
1472 		printf("%s failed to get cru device\n", __func__);
1473 		return ret;
1474 	}
1475 
1476 	priv = dev_get_priv(cru_dev);
1477 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1478 	       priv->sync_kernel ? "sync kernel" : "uboot",
1479 	       priv->armclk_enter_hz / 1000,
1480 	       priv->armclk_init_hz / 1000,
1481 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1482 	       priv->set_armclk_rate ? " KHz" : "N/A");
1483 	for (i = 0; i < clk_count; i++) {
1484 		clk_dump = &clks_dump[i];
1485 		if (clk_dump->name) {
1486 			clk.id = clk_dump->id;
1487 			if (clk_dump->is_cru)
1488 				ret = clk_request(cru_dev, &clk);
1489 			if (ret < 0)
1490 				return ret;
1491 
1492 			rate = clk_get_rate(&clk);
1493 			clk_free(&clk);
1494 			if (i == 0) {
1495 				if (rate < 0)
1496 					printf("  %s %s\n", clk_dump->name,
1497 					       "unknown");
1498 				else
1499 					printf("  %s %lu KHz\n", clk_dump->name,
1500 					       rate / 1000);
1501 			} else {
1502 				if (rate < 0)
1503 					printf("  %s %s\n", clk_dump->name,
1504 					       "unknown");
1505 				else
1506 					printf("  %s %lu KHz\n", clk_dump->name,
1507 					       rate / 1000);
1508 			}
1509 		}
1510 	}
1511 
1512 	return 0;
1513 }
1514 #endif
1515