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