xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1126b.c (revision d1e7b9e1d9259b6a26a1dc310b724936b8d5e55e)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2025 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_rv1126b.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rockchip,rv1126b-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
23 
24 #ifdef CONFIG_SPL_BUILD
25 #ifndef BITS_WITH_WMASK
26 #define BITS_WITH_WMASK(bits, msk, shift) \
27 	((bits) << (shift)) | ((msk) << ((shift) + 16))
28 #endif
29 #endif
30 
31 static struct rockchip_pll_rate_table rv1126b_pll_rates[] = {
32 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
33 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
34 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
35 	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
36 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
37 	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
38 	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
39 	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
40 	{ /* sentinel */ },
41 };
42 
43 static struct rockchip_pll_clock rv1126b_pll_clks[] = {
44 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126B_PLL_CON(8),
45 		     RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates),
46 	[AUPLL] = PLL(pll_rk3328, PLL_AUPLL, RV1126B_PLL_CON(0),
47 		     RV1126B_MODE_CON, 0, 10, 0, rv1126b_pll_rates),
48 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126B_PERIPLL_CON(0),
49 		     RV1126B_MODE_CON, 4, 10, 0, rv1126b_pll_rates),
50 };
51 
52 #ifndef CONFIG_SPL_BUILD
53 #define RV1126B_CLK_DUMP(_id, _name, _iscru)	\
54 {						\
55 	.id = _id,				\
56 	.name = _name,				\
57 	.is_cru = _iscru,			\
58 }
59 
60 static const struct rv1126b_clk_info clks_dump[] = {
61 	RV1126B_CLK_DUMP(PLL_GPLL, "gpll", true),
62 	RV1126B_CLK_DUMP(PLL_AUPLL, "aupll", true),
63 	RV1126B_CLK_DUMP(PLL_CPLL, "cpll", true),
64 	RV1126B_CLK_DUMP(ACLK_PERI_ROOT, "aclk_peri_root", true),
65 	RV1126B_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true),
66 	RV1126B_CLK_DUMP(ACLK_TOP_ROOT, "aclk_top_root", true),
67 	RV1126B_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
68 	RV1126B_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
69 	RV1126B_CLK_DUMP(HCLK_BUS_ROOT, "hclk_bus_root", true),
70 	RV1126B_CLK_DUMP(PCLK_BUS_ROOT, "pclk_bus_root", true),
71 	RV1126B_CLK_DUMP(BUSCLK_PMU_SRC, "busclk_pmu_src", true),
72 };
73 #endif
74 
75 static ulong rv1126b_peri_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
76 {
77 	struct rv1126b_cru *cru = priv->cru;
78 	u32 con, sel, rate;
79 
80 	switch (clk_id) {
81 	case ACLK_PERI_ROOT:
82 		con = readl(&cru->clksel_con[47]);
83 		sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
84 		if (sel == ACLK_PERI_SEL_200M)
85 			rate = 200 * MHz;
86 		else
87 			rate = OSC_HZ;
88 		break;
89 	case PCLK_PERI_ROOT:
90 		con = readl(&cru->clksel_con[47]);
91 		sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
92 		if (sel == PCLK_PERI_SEL_100M)
93 			rate = 100 * MHz;
94 		else
95 			rate = OSC_HZ;
96 		break;
97 	case ACLK_TOP_ROOT:
98 		con = readl(&cru->clksel_con[44]);
99 		sel = (con & ACLK_TOP_SEL_MASK) >> ACLK_TOP_SEL_SHIFT;
100 		if (sel == ACLK_TOP_SEL_600M)
101 			rate = 600 * MHz;
102 		else if (sel == ACLK_TOP_SEL_400M)
103 			rate = 400 * MHz;
104 		else
105 			rate = 200 * MHz;
106 		break;
107 	case PCLK_TOP_ROOT:
108 	case PCLK_BUS_ROOT:
109 	case BUSCLK_PMU_SRC:
110 		rate = 100 * MHz;
111 		break;
112 	case ACLK_BUS_ROOT:
113 		con = readl(&cru->clksel_con[44]);
114 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
115 		if (sel == ACLK_BUS_SEL_400M)
116 			rate = 400 * MHz;
117 		else if (sel == ACLK_BUS_SEL_300M)
118 			rate = 300 * MHz;
119 		else
120 			rate = 200 * MHz;
121 		break;
122 	case HCLK_BUS_ROOT:
123 		con = readl(&cru->clksel_con[44]);
124 		sel = (con & HCLK_BUS_SEL_MASK) >> HCLK_BUS_SEL_SHIFT;
125 		if (sel == HCLK_BUS_SEL_200M)
126 			rate = 200 * MHz;
127 		else
128 			rate = 100 * MHz;
129 		break;
130 	default:
131 		return -ENOENT;
132 	}
133 
134 	return rate;
135 }
136 
137 static ulong rv1126b_peri_set_clk(struct rv1126b_clk_priv *priv,
138 				  ulong clk_id, ulong rate)
139 {
140 	struct rv1126b_cru *cru = priv->cru;
141 	int src_clk;
142 
143 	switch (clk_id) {
144 	case ACLK_PERI_ROOT:
145 		if (rate >= 198 * MHz)
146 			src_clk = ACLK_PERI_SEL_200M;
147 		else
148 			src_clk = ACLK_PERI_SEL_24M;
149 		rk_clrsetreg(&cru->clksel_con[47],
150 			     ACLK_PERI_SEL_MASK,
151 			     src_clk << ACLK_PERI_SEL_SHIFT);
152 		break;
153 	case PCLK_PERI_ROOT:
154 		if (rate >= 99 * MHz)
155 			src_clk = PCLK_PERI_SEL_100M;
156 		else
157 			src_clk = PCLK_PERI_SEL_24M;
158 		rk_clrsetreg(&cru->clksel_con[47],
159 			     PCLK_PERI_SEL_MASK,
160 			     src_clk << PCLK_PERI_SEL_SHIFT);
161 		break;
162 	case ACLK_TOP_ROOT:
163 		if (rate >= 594 * MHz)
164 			src_clk = ACLK_TOP_SEL_600M;
165 		else if (rate >= 396 * MHz)
166 			src_clk = ACLK_TOP_SEL_400M;
167 		else
168 			src_clk = ACLK_TOP_SEL_200M;
169 		rk_clrsetreg(&cru->clksel_con[44],
170 			     ACLK_TOP_SEL_MASK,
171 			     src_clk << ACLK_TOP_SEL_SHIFT);
172 		break;
173 	case PCLK_TOP_ROOT:
174 	case PCLK_BUS_ROOT:
175 	case BUSCLK_PMU_SRC:
176 		break;
177 	case ACLK_BUS_ROOT:
178 		if (rate >= 396 * MHz)
179 			src_clk = ACLK_BUS_SEL_400M;
180 		else if (rate >= 297 * MHz)
181 			src_clk = ACLK_BUS_SEL_300M;
182 		else
183 			src_clk = ACLK_BUS_SEL_200M;
184 		rk_clrsetreg(&cru->clksel_con[44],
185 			     ACLK_BUS_SEL_MASK,
186 			     src_clk << ACLK_BUS_SEL_SHIFT);
187 		break;
188 	case HCLK_BUS_ROOT:
189 		if (rate >= 198 * MHz)
190 			src_clk = HCLK_BUS_SEL_200M;
191 		else
192 			src_clk = HCLK_BUS_SEL_100M;
193 		rk_clrsetreg(&cru->clksel_con[44],
194 			     HCLK_BUS_SEL_MASK,
195 			     src_clk << HCLK_BUS_SEL_SHIFT);
196 		break;
197 	default:
198 		printf("do not support this permid freq\n");
199 		return -EINVAL;
200 	}
201 
202 	return rv1126b_peri_get_clk(priv, clk_id);
203 }
204 
205 static ulong rv1126b_i2c_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
206 {
207 	struct rv1126b_cru *cru = priv->cru;
208 	u32 sel, con;
209 	ulong rate;
210 
211 	switch (clk_id) {
212 	case CLK_I2C0:
213 	case CLK_I2C1:
214 	case CLK_I2C3:
215 	case CLK_I2C4:
216 	case CLK_I2C5:
217 	case CLK_I2C_BUS_SRC:
218 		con = readl(&cru->clksel_con[50]);
219 		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
220 		if (sel == CLK_I2C_SEL_200M)
221 			rate = 200 * MHz;
222 		else
223 			rate = OSC_HZ;
224 		break;
225 	case CLK_I2C2:
226 		con = readl(&cru->pmu_clksel_con[2]);
227 		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
228 		if (sel == CLK_I2C2_SEL_100M)
229 			rate = 100 * MHz;
230 		else if (sel == CLK_I2C2_SEL_RCOSC)
231 			rate = RC_OSC_HZ;
232 		else
233 			rate = OSC_HZ;
234 		break;
235 	default:
236 		return -ENOENT;
237 	}
238 
239 	return rate;
240 }
241 
242 static ulong rv1126b_i2c_set_clk(struct rv1126b_clk_priv *priv, ulong clk_id,
243 				 ulong rate)
244 {
245 	struct rv1126b_cru *cru = priv->cru;
246 	int src_clk;
247 
248 	switch (clk_id) {
249 	case CLK_I2C0:
250 	case CLK_I2C1:
251 	case CLK_I2C3:
252 	case CLK_I2C4:
253 	case CLK_I2C5:
254 	case CLK_I2C_BUS_SRC:
255 		if (rate == OSC_HZ)
256 			src_clk = CLK_I2C_SEL_24M;
257 		else
258 			src_clk = CLK_I2C_SEL_200M;
259 		rk_clrsetreg(&cru->clksel_con[50], CLK_I2C_SEL_MASK,
260 			     src_clk << CLK_I2C_SEL_SHIFT);
261 		break;
262 	case CLK_I2C2:
263 		if (rate == OSC_HZ)
264 			src_clk = CLK_I2C2_SEL_24M;
265 		else if (rate == RC_OSC_HZ)
266 			src_clk = CLK_I2C2_SEL_RCOSC;
267 		else
268 			src_clk = CLK_I2C2_SEL_100M;
269 		rk_clrsetreg(&cru->pmu_clksel_con[2], CLK_I2C2_SEL_MASK,
270 			     src_clk << CLK_I2C2_SEL_SHIFT);
271 		break;
272 	default:
273 		return -ENOENT;
274 	}
275 	return rv1126b_i2c_get_clk(priv, clk_id);
276 }
277 
278 static ulong rv1126b_crypto_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
279 {
280 	struct rv1126b_cru *cru = priv->cru;
281 	u32 sel, con, rate;
282 
283 	switch (clk_id) {
284 	case PCLK_RKCE:
285 		return rv1126b_peri_get_clk(priv, PCLK_BUS_ROOT);
286 	case HCLK_NS_RKCE:
287 		return rv1126b_peri_get_clk(priv, HCLK_BUS_ROOT);
288 	case ACLK_RKCE_SRC:
289 	case ACLK_NSRKCE:
290 		con = readl(&cru->clksel_con[50]);
291 		sel = (con & ACLK_RKCE_SEL_MASK) >>
292 		      ACLK_RKCE_SEL_SHIFT;
293 		if (sel == ACLK_RKCE_SEL_200M)
294 			rate = 200 * MHz;
295 		else
296 			rate = OSC_HZ;
297 		break;
298 	case CLK_PKA_RKCE_SRC:
299 	case CLK_PKA_NSRKCE:
300 		con = readl(&cru->clksel_con[50]);
301 		sel = (con & CLK_PKA_RKCE_SEL_MASK) >>
302 		      CLK_PKA_RKCE_SEL_SHIFT;
303 		if (sel == CLK_PKA_RKCE_SEL_300M)
304 			rate = 300 * MHz;
305 		else
306 			rate = 200 * MHz;
307 		break;
308 	default:
309 		return -ENOENT;
310 	}
311 	return rate;
312 }
313 
314 static ulong rv1126b_crypto_set_clk(struct rv1126b_clk_priv *priv,
315 				    ulong clk_id, ulong rate)
316 {
317 	struct rv1126b_cru *cru = priv->cru;
318 	u32 sel;
319 
320 	switch (clk_id) {
321 	case PCLK_RKCE:
322 		break;
323 	case HCLK_NS_RKCE:
324 		rv1126b_peri_set_clk(priv, HCLK_BUS_ROOT, rate);
325 	case ACLK_RKCE_SRC:
326 	case ACLK_NSRKCE:
327 		if (rate >= 198 * MHz)
328 			sel = ACLK_RKCE_SEL_200M;
329 		else
330 			sel = ACLK_RKCE_SEL_24M;
331 		rk_clrsetreg(&cru->clksel_con[50],
332 			     ACLK_RKCE_SEL_MASK,
333 			     (sel << ACLK_RKCE_SEL_SHIFT));
334 		break;
335 	case CLK_PKA_RKCE_SRC:
336 	case CLK_PKA_NSRKCE:
337 		if (rate >= 297 * MHz)
338 			sel = CLK_PKA_RKCE_SEL_300M;
339 		else
340 			sel = CLK_PKA_RKCE_SEL_200M;
341 		rk_clrsetreg(&cru->clksel_con[50],
342 			     CLK_PKA_RKCE_SEL_MASK,
343 			     (sel << CLK_PKA_RKCE_SEL_SHIFT));
344 		break;
345 	default:
346 		return -ENOENT;
347 	}
348 	return rv1126b_crypto_get_clk(priv, clk_id);
349 }
350 
351 static ulong rv1126b_mmc_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
352 {
353 	struct rv1126b_cru *cru = priv->cru;
354 	u32 div, sel, con, prate;
355 
356 	switch (clk_id) {
357 	case CCLK_SDMMC0:
358 	case HCLK_SDMMC0:
359 		con = readl(&cru->clksel_con[45]);
360 		sel = (con & CLK_SDMMC_SEL_MASK) >>
361 		      CLK_SDMMC_SEL_SHIFT;
362 		div = (con & CLK_SDMMC_DIV_MASK) >>
363 		      CLK_SDMMC_DIV_SHIFT;
364 		if (sel == CLK_SDMMC_SEL_GPLL)
365 			prate = priv->gpll_hz;
366 		else if (sel == CLK_SDMMC_SEL_CPLL)
367 			prate = priv->cpll_hz;
368 		else
369 			prate = OSC_HZ;
370 		return DIV_TO_RATE(prate, div);
371 	case CCLK_SDMMC1:
372 	case HCLK_SDMMC1:
373 		con = readl(&cru->clksel_con[46]);
374 		sel = (con & CLK_SDMMC_SEL_MASK) >>
375 		      CLK_SDMMC_SEL_SHIFT;
376 		div = (con & CLK_SDMMC_DIV_MASK) >>
377 		      CLK_SDMMC_DIV_SHIFT;
378 		if (sel == CLK_SDMMC_SEL_GPLL)
379 			prate = priv->gpll_hz;
380 		else if (sel == CLK_SDMMC_SEL_CPLL)
381 			prate = priv->cpll_hz;
382 		else
383 			prate = OSC_HZ;
384 		return DIV_TO_RATE(prate, div);
385 	case CCLK_EMMC:
386 	case HCLK_EMMC:
387 		con = readl(&cru->clksel_con[47]);
388 		sel = (con & CLK_SDMMC_SEL_MASK) >>
389 		      CLK_SDMMC_SEL_SHIFT;
390 		div = (con & CLK_SDMMC_DIV_MASK) >>
391 		      CLK_SDMMC_DIV_SHIFT;
392 		if (sel == CLK_SDMMC_SEL_GPLL)
393 			prate = priv->gpll_hz;
394 		else if (sel == CLK_SDMMC_SEL_CPLL)
395 			prate = priv->cpll_hz;
396 		else
397 			prate = OSC_HZ;
398 		return DIV_TO_RATE(prate, div);
399 	case SCLK_2X_FSPI0:
400 	case HCLK_FSPI0:
401 	case HCLK_XIP_FSPI0:
402 		con = readl(&cru->clksel_con[48]);
403 		sel = (con & CLK_SDMMC_SEL_MASK) >>
404 		      CLK_SDMMC_SEL_SHIFT;
405 		div = (con & CLK_SDMMC_DIV_MASK) >>
406 		      CLK_SDMMC_DIV_SHIFT;
407 		if (sel == CLK_SDMMC_SEL_GPLL)
408 			prate = priv->gpll_hz;
409 		else if (sel == CLK_SDMMC_SEL_CPLL)
410 			prate = priv->cpll_hz;
411 		else
412 			prate = OSC_HZ;
413 		return DIV_TO_RATE(prate, div);
414 	case SCLK_1X_FSPI1:
415 	case HCLK_FSPI1:
416 	case HCLK_XIP_FSPI1:
417 		con = readl(&cru->pmu1_clksel_con[0]);
418 		sel = (con & SCLK_1X_FSPI1_SEL_MASK) >>
419 		     SCLK_1X_FSPI1_SEL_SHIFT;
420 		div = (con & SCLK_1X_FSPI1_DIV_MASK) >>
421 		      SCLK_1X_FSPI1_DIV_SHIFT;
422 		if (sel == SCLK_1X_FSPI1_SEL_100M)
423 			prate = 100 * MHz;
424 		else if (sel == SCLK_1X_FSPI1_SEL_RCOSC)
425 			prate = RC_OSC_HZ;
426 		else
427 			prate = OSC_HZ;
428 		return DIV_TO_RATE(prate, div);
429 	default:
430 		return -ENOENT;
431 	}
432 }
433 
434 static ulong rv1126b_mmc_set_clk(struct rv1126b_clk_priv *priv,
435 				 ulong clk_id, ulong rate)
436 {
437 	struct rv1126b_cru *cru = priv->cru;
438 	u32 sel, src_clk_div;
439 	ulong prate = 0;
440 
441 	if ((OSC_HZ % rate) == 0) {
442 		sel = CLK_SDMMC_SEL_24M;
443 		prate = OSC_HZ;
444 	} else if ((priv->cpll_hz % rate) == 0) {
445 		sel = CLK_SDMMC_SEL_CPLL;
446 		prate = priv->cpll_hz;
447 	} else {
448 		sel = CLK_SDMMC_SEL_GPLL;
449 		prate = priv->gpll_hz;
450 	}
451 	src_clk_div = DIV_ROUND_UP(prate, rate);
452 
453 	switch (clk_id) {
454 	case CCLK_SDMMC0:
455 	case HCLK_SDMMC0:
456 		src_clk_div = DIV_ROUND_UP(prate, rate);
457 		rk_clrsetreg(&cru->clksel_con[45],
458 			     CLK_SDMMC_SEL_MASK |
459 			     CLK_SDMMC_DIV_MASK,
460 			     (sel << CLK_SDMMC_SEL_SHIFT) |
461 			     ((src_clk_div - 1) <<
462 			      CLK_SDMMC_DIV_SHIFT));
463 		break;
464 	case CCLK_SDMMC1:
465 	case HCLK_SDMMC1:
466 		src_clk_div = DIV_ROUND_UP(prate, rate);
467 		rk_clrsetreg(&cru->clksel_con[46],
468 			     CLK_SDMMC_SEL_MASK |
469 			     CLK_SDMMC_DIV_MASK,
470 			     (sel << CLK_SDMMC_SEL_SHIFT) |
471 			     ((src_clk_div - 1) <<
472 			      CLK_SDMMC_DIV_SHIFT));
473 		break;
474 	case CCLK_EMMC:
475 	case HCLK_EMMC:
476 		src_clk_div = DIV_ROUND_UP(prate, rate);
477 		rk_clrsetreg(&cru->clksel_con[47],
478 			     CLK_SDMMC_SEL_MASK |
479 			     CLK_SDMMC_DIV_MASK,
480 			     (sel << CLK_SDMMC_SEL_SHIFT) |
481 			     ((src_clk_div - 1) <<
482 			      CLK_SDMMC_DIV_SHIFT));
483 		break;
484 	case SCLK_2X_FSPI0:
485 	case HCLK_FSPI0:
486 	case HCLK_XIP_FSPI0:
487 		src_clk_div = DIV_ROUND_UP(prate, rate);
488 		rk_clrsetreg(&cru->clksel_con[48],
489 			     CLK_SDMMC_SEL_MASK |
490 			     CLK_SDMMC_DIV_MASK,
491 			     (sel << CLK_SDMMC_SEL_SHIFT) |
492 			     ((src_clk_div - 1) <<
493 			      CLK_SDMMC_DIV_SHIFT));
494 		break;
495 	case SCLK_1X_FSPI1:
496 	case HCLK_FSPI1:
497 	case HCLK_XIP_FSPI1:
498 		if ((OSC_HZ % rate) == 0) {
499 			sel = SCLK_1X_FSPI1_SEL_24M;
500 			prate = OSC_HZ;
501 		} else if ((100 * MHz % rate) == 0) {
502 			sel = SCLK_1X_FSPI1_SEL_100M;
503 			prate = priv->cpll_hz;
504 		} else {
505 			sel = SCLK_1X_FSPI1_SEL_RCOSC;
506 			prate = RC_OSC_HZ;
507 		}
508 		src_clk_div = DIV_ROUND_UP(prate, rate);
509 		rk_clrsetreg(&cru->pmu1_clksel_con[0],
510 			     SCLK_1X_FSPI1_SEL_MASK |
511 			     SCLK_1X_FSPI1_DIV_MASK,
512 			     (sel << SCLK_1X_FSPI1_SEL_SHIFT) |
513 			     ((src_clk_div - 1) <<
514 			      SCLK_1X_FSPI1_DIV_SHIFT));
515 		break;
516 	default:
517 		return -ENOENT;
518 	}
519 	return rv1126b_mmc_get_clk(priv, clk_id);
520 }
521 
522 static ulong rv1126b_spi_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
523 {
524 	struct rv1126b_cru *cru = priv->cru;
525 	u32 sel, con, rate;
526 
527 	switch (clk_id) {
528 	case CLK_SPI0:
529 		con = readl(&cru->clksel_con[50]);
530 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
531 		break;
532 	case CLK_SPI1:
533 		con = readl(&cru->clksel_con[50]);
534 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
535 		break;
536 	default:
537 		return -ENOENT;
538 	}
539 	if (sel == CLK_SPI0_SEL_200M)
540 		rate = 200 * MHz;
541 	else if (sel == CLK_SPI0_SEL_100M)
542 		rate = 100 * MHz;
543 	else if (sel == CLK_SPI0_SEL_50M)
544 		rate = 50 * MHz;
545 	else
546 		rate = OSC_HZ;
547 
548 	return rate;
549 }
550 
551 static ulong rv1126b_spi_set_clk(struct rv1126b_clk_priv *priv,
552 				 ulong clk_id, ulong rate)
553 {
554 	struct rv1126b_cru *cru = priv->cru;
555 	int src_clk;
556 
557 	if (rate >= 198 * MHz)
558 		src_clk = CLK_SPI0_SEL_200M;
559 	else if (rate >= 99 * MHz)
560 		src_clk = CLK_SPI0_SEL_100M;
561 	else if (rate >= 48 * MHz)
562 		src_clk = CLK_SPI0_SEL_50M;
563 	else
564 		src_clk = CLK_SPI0_SEL_24M;
565 
566 	switch (clk_id) {
567 	case CLK_SPI0:
568 		rk_clrsetreg(&cru->clksel_con[50], CLK_SPI0_SEL_MASK,
569 			     src_clk << CLK_SPI0_SEL_SHIFT);
570 		break;
571 	case CLK_SPI1:
572 		rk_clrsetreg(&cru->clksel_con[50], CLK_SPI1_SEL_MASK,
573 			     src_clk << CLK_SPI1_SEL_SHIFT);
574 		break;
575 	default:
576 		return -ENOENT;
577 	}
578 
579 	return rv1126b_spi_get_clk(priv, clk_id);
580 }
581 
582 static ulong rv1126b_pwm_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
583 {
584 	struct rv1126b_cru *cru = priv->cru;
585 	u32 sel, div, con;
586 
587 	switch (clk_id) {
588 	case CLK_PWM0:
589 		con = readl(&cru->clksel_con[50]);
590 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
591 		break;
592 	case CLK_PWM2:
593 		con = readl(&cru->clksel_con[50]);
594 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
595 		break;
596 	case CLK_PWM3:
597 		con = readl(&cru->clksel_con[50]);
598 		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
599 		break;
600 	case CLK_PWM1:
601 		con = readl(&cru->pmu_clksel_con[2]);
602 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
603 		div = (con & CLK_PWM1_DIV_MASK) >>
604 		      CLK_PWM1_DIV_SHIFT;
605 		if (sel == CLK_PWM1_SEL_100M)
606 			return DIV_TO_RATE(100 * MHz, div);
607 		else if (sel == CLK_PWM1_SEL_RCOSC)
608 			return DIV_TO_RATE(RC_OSC_HZ, div);
609 		else
610 			return DIV_TO_RATE(OSC_HZ, div);
611 	default:
612 		return -ENOENT;
613 	}
614 
615 	switch (sel) {
616 	case CLK_PWM_SEL_100M:
617 		return 100 * MHz;
618 	case CLK_PWM_SEL_24M:
619 		return OSC_HZ;
620 	default:
621 		return -ENOENT;
622 	}
623 }
624 
625 static ulong rv1126b_pwm_set_clk(struct rv1126b_clk_priv *priv,
626 				 ulong clk_id, ulong rate)
627 {
628 	struct rv1126b_cru *cru = priv->cru;
629 	int src_clk, src_clk_div, prate;
630 
631 	if (rate >= 99 * MHz)
632 		src_clk = CLK_PWM_SEL_100M;
633 	else
634 		src_clk = CLK_PWM_SEL_24M;
635 
636 	switch (clk_id) {
637 	case CLK_PWM0:
638 		rk_clrsetreg(&cru->clksel_con[50],
639 			     CLK_PWM0_SEL_MASK,
640 			     src_clk << CLK_PWM0_SEL_SHIFT);
641 		break;
642 	case CLK_PWM2:
643 		rk_clrsetreg(&cru->clksel_con[50],
644 			     CLK_PWM2_SEL_MASK,
645 			     src_clk << CLK_PWM2_SEL_SHIFT);
646 		break;
647 	case CLK_PWM3:
648 		rk_clrsetreg(&cru->clksel_con[50],
649 			     CLK_PWM3_SEL_MASK,
650 			     src_clk << CLK_PWM3_SEL_SHIFT);
651 		break;
652 	case CLK_PWM1:
653 		if ((OSC_HZ % rate) == 0) {
654 			src_clk = CLK_PWM1_SEL_24M;
655 			prate = OSC_HZ;
656 		} else if ((100 * MHz % rate) == 0) {
657 			src_clk = CLK_PWM1_SEL_100M;
658 			prate = priv->cpll_hz;
659 		} else {
660 			src_clk = CLK_PWM1_SEL_RCOSC;
661 			prate = RC_OSC_HZ;
662 		}
663 		src_clk_div = DIV_ROUND_UP(prate, rate);
664 		rk_clrsetreg(&cru->pmu1_clksel_con[2],
665 			     CLK_PWM1_SEL_MASK |
666 			     CLK_PWM1_DIV_MASK,
667 			     (src_clk << CLK_PWM1_SEL_SHIFT) |
668 			     ((src_clk_div - 1) <<
669 			      CLK_PWM1_DIV_SHIFT));
670 		break;
671 
672 	default:
673 		return -ENOENT;
674 	}
675 
676 	return rv1126b_pwm_get_clk(priv, clk_id);
677 }
678 
679 static ulong rv1126b_adc_get_clk(struct rv1126b_clk_priv *priv, ulong clk_id)
680 {
681 	struct rv1126b_cru *cru = priv->cru;
682 	u32 sel, div, con;
683 
684 	switch (clk_id) {
685 	case CLK_SARADC0:
686 	case CLK_SARADC0_SRC:
687 		con = readl(&cru->clksel_con[63]);
688 		sel = (con & CLK_SARADC0_SEL_MASK) >> CLK_SARADC0_SEL_SHIFT;
689 		div = (con & CLK_SARADC0_DIV_MASK) >>
690 		      CLK_SARADC0_DIV_SHIFT;
691 		break;
692 	case CLK_SARADC1:
693 	case CLK_SARADC1_SRC:
694 		con = readl(&cru->clksel_con[63]);
695 		sel = (con & CLK_SARADC1_SEL_MASK) >> CLK_SARADC1_SEL_SHIFT;
696 		div = (con & CLK_SARADC1_DIV_MASK) >>
697 		      CLK_SARADC1_DIV_SHIFT;
698 		break;
699 	case CLK_SARADC2:
700 	case CLK_SARADC2_SRC:
701 		con = readl(&cru->clksel_con[63]);
702 		sel = (con & CLK_SARADC2_SEL_MASK) >> CLK_SARADC2_SEL_SHIFT;
703 		div = (con & CLK_SARADC2_DIV_MASK) >>
704 		      CLK_SARADC2_DIV_SHIFT;
705 		break;
706 	case CLK_TSADC:
707 	case CLK_TSADC_PHYCTRL:
708 		return OSC_HZ;
709 	default:
710 		return -ENOENT;
711 	}
712 
713 	if (sel == CLK_SARADC_SEL_200M)
714 		return DIV_TO_RATE(200 * MHz, div);
715 	else
716 		return DIV_TO_RATE(OSC_HZ, div);
717 }
718 
719 static ulong rv1126b_adc_set_clk(struct rv1126b_clk_priv *priv,
720 				 ulong clk_id, ulong rate)
721 {
722 	struct rv1126b_cru *cru = priv->cru;
723 	int src_clk_sel, src_clk_div, prate;
724 
725 	if ((OSC_HZ % rate) == 0) {
726 		src_clk_sel = CLK_SARADC_SEL_24M;
727 		prate = OSC_HZ;
728 	} else {
729 		src_clk_sel = CLK_SARADC_SEL_200M;
730 		prate = 200 * MHz;
731 	}
732 	src_clk_div = DIV_ROUND_UP(prate, rate);
733 
734 	switch (clk_id) {
735 	case CLK_SARADC0:
736 	case CLK_SARADC0_SRC:
737 		assert(src_clk_div - 1 <= 7);
738 		rk_clrsetreg(&cru->clksel_con[63],
739 			     CLK_SARADC0_SEL_MASK |
740 			     CLK_SARADC0_DIV_MASK,
741 			     (src_clk_sel << CLK_SARADC0_SEL_SHIFT) |
742 			     ((src_clk_div - 1) <<
743 			      CLK_SARADC0_DIV_SHIFT));
744 		break;
745 	case CLK_SARADC1:
746 	case CLK_SARADC1_SRC:
747 		assert(src_clk_div - 1 <= 7);
748 		rk_clrsetreg(&cru->clksel_con[63],
749 			     CLK_SARADC1_SEL_MASK |
750 			     CLK_SARADC1_DIV_MASK,
751 			     (src_clk_sel << CLK_SARADC1_SEL_SHIFT) |
752 			     ((src_clk_div - 1) <<
753 			      CLK_SARADC1_DIV_SHIFT));
754 		break;
755 	case CLK_SARADC2:
756 	case CLK_SARADC2_SRC:
757 		assert(src_clk_div - 1 <= 7);
758 		rk_clrsetreg(&cru->clksel_con[63],
759 			     CLK_SARADC2_SEL_MASK |
760 			     CLK_SARADC2_DIV_MASK,
761 			     (src_clk_sel << CLK_SARADC2_SEL_SHIFT) |
762 			     ((src_clk_div - 1) <<
763 			      CLK_SARADC2_DIV_SHIFT));
764 		break;
765 	case CLK_TSADC:
766 	case CLK_TSADC_PHYCTRL:
767 		break;
768 	default:
769 		return -ENOENT;
770 	}
771 	return rv1126b_adc_get_clk(priv, clk_id);
772 }
773 
774 /*
775  *
776  * rational_best_approximation(31415, 10000,
777  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
778  *
779  * you may look at given_numerator as a fixed point number,
780  * with the fractional part size described in given_denominator.
781  *
782  * for theoretical background, see:
783  * http://en.wikipedia.org/wiki/Continued_fraction
784  */
785 static void rational_best_approximation(unsigned long given_numerator,
786 					unsigned long given_denominator,
787 					unsigned long max_numerator,
788 					unsigned long max_denominator,
789 					unsigned long *best_numerator,
790 					unsigned long *best_denominator)
791 {
792 	unsigned long n, d, n0, d0, n1, d1;
793 
794 	n = given_numerator;
795 	d = given_denominator;
796 	n0 = 0;
797 	d1 = 0;
798 	n1 = 1;
799 	d0 = 1;
800 	for (;;) {
801 		unsigned long t, a;
802 
803 		if (n1 > max_numerator || d1 > max_denominator) {
804 			n1 = n0;
805 			d1 = d0;
806 			break;
807 		}
808 		if (d == 0)
809 			break;
810 		t = d;
811 		a = n / d;
812 		d = n % d;
813 		n = t;
814 		t = n0 + a * n1;
815 		n0 = n1;
816 		n1 = t;
817 		t = d0 + a * d1;
818 		d0 = d1;
819 		d1 = t;
820 	}
821 	*best_numerator = n1;
822 	*best_denominator = d1;
823 }
824 
825 static ulong rv1126b_frac_get_rate(struct rv1126b_clk_priv *priv, ulong clk_id)
826 {
827 	struct rv1126b_cru *cru = priv->cru;
828 	u32 reg, reg_h, src, con, p_rate;
829 	unsigned long m, n, m_l, n_l, m_h, n_h;
830 
831 	switch (clk_id) {
832 	case CLK_CM_FRAC0:
833 		con = readl(&cru->clksel_con[10]);
834 		src = (con & CLK_CM_FRAC0_SRC_SEL_MASK) >>
835 		      CLK_CM_FRAC0_SRC_SEL_SHIFT;
836 		reg = readl(&cru->clksel_con[25]);
837 		reg_h = readl(&cru->clk_cm_frac0_div_h);
838 		break;
839 	case CLK_CM_FRAC1:
840 		con = readl(&cru->clksel_con[10]);
841 		src = (con & CLK_CM_FRAC1_SRC_SEL_MASK) >>
842 		      CLK_CM_FRAC1_SRC_SEL_SHIFT;
843 		reg = readl(&cru->clksel_con[26]);
844 		reg_h = readl(&cru->clk_cm_frac1_div_h);
845 		break;
846 	case CLK_CM_FRAC2:
847 		con = readl(&cru->clksel_con[10]);
848 		src = (con & CLK_CM_FRAC2_SRC_SEL_MASK) >>
849 		      CLK_CM_FRAC2_SRC_SEL_SHIFT;
850 		reg = readl(&cru->clksel_con[27]);
851 		reg_h = readl(&cru->clk_cm_frac2_div_h);
852 		break;
853 	case CLK_UART_FRAC0:
854 		con = readl(&cru->clksel_con[10]);
855 		src = (con & CLK_UART_FRAC0_SRC_SEL_MASK) >>
856 		      CLK_UART_FRAC0_SRC_SEL_SHIFT;
857 		reg = readl(&cru->clksel_con[28]);
858 		reg_h = readl(&cru->clk_uart_frac0_div_h);
859 		break;
860 	case CLK_UART_FRAC1:
861 		con = readl(&cru->clksel_con[10]);
862 		src = (con & CLK_UART_FRAC1_SRC_SEL_MASK) >>
863 		      CLK_UART_FRAC1_SRC_SEL_SHIFT;
864 		reg = readl(&cru->clksel_con[29]);
865 		reg_h = readl(&cru->clk_uart_frac1_div_h);
866 		break;
867 	case CLK_AUDIO_FRAC0:
868 		con = readl(&cru->clksel_con[10]);
869 		src = (con & CLK_AUDIO_FRAC0_SRC_SEL_MASK) >>
870 		      CLK_AUDIO_FRAC0_SRC_SEL_SHIFT;
871 		reg = readl(&cru->clksel_con[30]);
872 		reg_h = readl(&cru->clk_audio_frac0_div_h);
873 		break;
874 	case CLK_AUDIO_FRAC1:
875 		con = readl(&cru->clksel_con[10]);
876 		src = (con & CLK_AUDIO_FRAC1_SRC_SEL_MASK) >>
877 		      CLK_AUDIO_FRAC1_SRC_SEL_SHIFT;
878 		reg = readl(&cru->clksel_con[31]);
879 		reg_h = readl(&cru->clk_audio_frac1_div_h);
880 		break;
881 
882 	default:
883 		return -ENOENT;
884 	}
885 
886 	switch (src) {
887 	case CLK_FRAC_SRC_SEL_24M:
888 		p_rate = OSC_HZ;
889 		break;
890 	case CLK_FRAC_SRC_SEL_GPLL:
891 		p_rate = priv->gpll_hz;
892 		break;
893 	case CLK_FRAC_SRC_SEL_AUPLL:
894 		p_rate = priv->aupll_hz;
895 		break;
896 	case CLK_FRAC_SRC_SEL_CPLL:
897 		p_rate = priv->cpll_hz;
898 		break;
899 	default:
900 		return -ENOENT;
901 	}
902 
903 	n_l = reg & CLK_FRAC_NUMERATOR_MASK;
904 	n_l >>= CLK_FRAC_NUMERATOR_SHIFT;
905 	m_l = reg & CLK_FRAC_DENOMINATOR_MASK;
906 	m_l >>= CLK_FRAC_DENOMINATOR_SHIFT;
907 	n_h = reg_h & CLK_FRAC_H_NUMERATOR_MASK;
908 	n_h >>= CLK_FRAC_H_NUMERATOR_SHIFT;
909 	m_h = reg_h & CLK_FRAC_H_DENOMINATOR_MASK;
910 	m_h >>= CLK_FRAC_H_DENOMINATOR_SHIFT;
911 	n = n_l | (n_h << 16);
912 	m = m_l | (m_h << 16);
913 	return p_rate * n / m;
914 }
915 
916 static ulong rv1126b_frac_set_rate(struct rv1126b_clk_priv *priv,
917 				   ulong clk_id, ulong rate)
918 {
919 	struct rv1126b_cru *cru = priv->cru;
920 	u32 src, p_rate, val;
921 	unsigned long m, n, m_l, n_l, m_h, n_h;
922 
923 	if ((OSC_HZ % rate) == 0) {
924 		src = CLK_FRAC_SRC_SEL_24M;
925 		p_rate = OSC_HZ;
926 	} else if ((priv->aupll_hz % rate) == 0) {
927 		src = CLK_FRAC_SRC_SEL_AUPLL;
928 		p_rate = priv->aupll_hz;
929 	} else if ((priv->cpll_hz % rate) == 0) {
930 		src = CLK_FRAC_SRC_SEL_CPLL;
931 		p_rate = priv->cpll_hz;
932 	} else {
933 		src = CLK_FRAC_SRC_SEL_GPLL;
934 		p_rate = priv->gpll_hz;
935 	}
936 
937 	rational_best_approximation(rate, p_rate,
938 				    GENMASK(24 - 1, 0),
939 				    GENMASK(24 - 1, 0),
940 				    &m, &n);
941 
942 	if (m < 4 && m != 0) {
943 		if (n % 2 == 0)
944 			val = 1;
945 		else
946 			val = DIV_ROUND_UP(4, m);
947 
948 		n *= val;
949 		m *= val;
950 		if (n > 0xffffff)
951 			n = 0xffffff;
952 	}
953 
954 	n_l = n & 0xffff;
955 	m_l = m & 0xffff;
956 	n_h = (n & 0xff0000) >> 16;
957 	m_h = (m & 0xff0000) >> 16;
958 
959 	switch (clk_id) {
960 	case CLK_CM_FRAC0:
961 		rk_clrsetreg(&cru->clksel_con[10],
962 			     CLK_CM_FRAC0_SRC_SEL_MASK,
963 			     (src << CLK_CM_FRAC0_SRC_SEL_SHIFT));
964 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
965 		writel(val, &cru->clk_cm_frac0_div_h);
966 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
967 		writel(val, &cru->clksel_con[25]);
968 		break;
969 	case CLK_CM_FRAC1:
970 		rk_clrsetreg(&cru->clksel_con[10],
971 			     CLK_CM_FRAC1_SRC_SEL_MASK,
972 			     (src << CLK_CM_FRAC1_SRC_SEL_SHIFT));
973 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
974 		writel(val, &cru->clk_cm_frac1_div_h);
975 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
976 		writel(val, &cru->clksel_con[26]);
977 		break;
978 	case CLK_CM_FRAC2:
979 		rk_clrsetreg(&cru->clksel_con[10],
980 			     CLK_CM_FRAC2_SRC_SEL_MASK,
981 			     (src << CLK_CM_FRAC2_SRC_SEL_SHIFT));
982 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
983 		writel(val, &cru->clk_cm_frac2_div_h);
984 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
985 		writel(val, &cru->clksel_con[27]);
986 		break;
987 	case CLK_UART_FRAC0:
988 		rk_clrsetreg(&cru->clksel_con[10],
989 			     CLK_UART_FRAC0_SRC_SEL_MASK,
990 			     (src << CLK_UART_FRAC0_SRC_SEL_SHIFT));
991 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
992 		writel(val, &cru->clk_uart_frac0_div_h);
993 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
994 		writel(val, &cru->clksel_con[28]);
995 		break;
996 	case CLK_UART_FRAC1:
997 		rk_clrsetreg(&cru->clksel_con[10],
998 			     CLK_UART_FRAC1_SRC_SEL_MASK,
999 			     (src << CLK_UART_FRAC1_SRC_SEL_SHIFT));
1000 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
1001 		writel(val, &cru->clk_uart_frac1_div_h);
1002 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
1003 		writel(val, &cru->clksel_con[29]);
1004 		break;
1005 	case CLK_AUDIO_FRAC0:
1006 		rk_clrsetreg(&cru->clksel_con[10],
1007 			     CLK_AUDIO_FRAC0_SRC_SEL_MASK,
1008 			     (src << CLK_AUDIO_FRAC0_SRC_SEL_SHIFT));
1009 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
1010 		writel(val, &cru->clk_audio_frac0_div_h);
1011 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
1012 		writel(val, &cru->clksel_con[30]);
1013 		break;
1014 	case CLK_AUDIO_FRAC1:
1015 		rk_clrsetreg(&cru->clksel_con[10],
1016 			     CLK_AUDIO_FRAC0_SRC_SEL_MASK,
1017 			     (src << CLK_AUDIO_FRAC0_SRC_SEL_SHIFT));
1018 		val = m_h << CLK_FRAC_H_NUMERATOR_SHIFT | n_h;
1019 		writel(val, &cru->clk_audio_frac1_div_h);
1020 		val = m_l << CLK_FRAC_NUMERATOR_SHIFT | n_l;
1021 		writel(val, &cru->clksel_con[31]);
1022 		break;
1023 
1024 	default:
1025 		return -ENOENT;
1026 	}
1027 
1028 	return rv1126b_frac_get_rate(priv, clk_id);
1029 }
1030 
1031 static ulong rv1126b_uart_get_rate(struct rv1126b_clk_priv *priv, ulong clk_id)
1032 {
1033 	struct rv1126b_cru *cru = priv->cru;
1034 	u32 con, div, src, p_rate;
1035 
1036 	switch (clk_id) {
1037 	case SCLK_UART0:
1038 		con = readl(&cru->pmu_clksel_con[3]);
1039 		src = (con & SCLK_UART0_SEL_MASK) >> SCLK_UART0_SEL_SHIFT;
1040 		if (src == SCLK_UART0_SEL_UART0_SRC)
1041 			return rv1126b_uart_get_rate(priv, SCLK_UART0_SRC);
1042 		else if (src == SCLK_UART0_SEL_UART0_SRC)
1043 			return RC_OSC_HZ;
1044 		else
1045 			return OSC_HZ;
1046 	case SCLK_UART0_SRC:
1047 		con = readl(&cru->clksel_con[12]);
1048 		src = (con & SCLK_UART0_SRC_SEL_MASK) >>
1049 		      SCLK_UART0_SRC_SEL_SHIFT;
1050 		div = (con & SCLK_UART0_SRC_DIV_MASK) >>
1051 		      SCLK_UART0_SRC_DIV_SHIFT;
1052 		break;
1053 	case SCLK_UART1:
1054 		con = readl(&cru->clksel_con[12]);
1055 		src = (con & SCLK_UART1_SEL_MASK) >> SCLK_UART1_SEL_SHIFT;
1056 		div = (con & SCLK_UART1_DIV_MASK) >> SCLK_UART1_DIV_SHIFT;
1057 		break;
1058 	case SCLK_UART2:
1059 		con = readl(&cru->clksel_con[13]);
1060 		src = (con & SCLK_UART2_SEL_MASK) >> SCLK_UART2_SEL_SHIFT;
1061 		div = (con & SCLK_UART2_DIV_MASK) >> SCLK_UART2_DIV_SHIFT;
1062 		break;
1063 	case SCLK_UART3:
1064 		con = readl(&cru->clksel_con[13]);
1065 		src = (con & SCLK_UART3_SEL_MASK) >> SCLK_UART3_SEL_SHIFT;
1066 		div = (con & SCLK_UART3_DIV_MASK) >> SCLK_UART3_DIV_SHIFT;
1067 		break;
1068 	case SCLK_UART4:
1069 		con = readl(&cru->clksel_con[14]);
1070 		src = (con & SCLK_UART4_SEL_MASK) >> SCLK_UART4_SEL_SHIFT;
1071 		div = (con & SCLK_UART4_DIV_MASK) >> SCLK_UART4_DIV_SHIFT;
1072 		break;
1073 	case SCLK_UART5:
1074 		con = readl(&cru->clksel_con[14]);
1075 		src = (con & SCLK_UART5_SEL_MASK) >> SCLK_UART5_SEL_SHIFT;
1076 		div = (con & SCLK_UART5_DIV_MASK) >> SCLK_UART5_DIV_SHIFT;
1077 		break;
1078 	case SCLK_UART6:
1079 		con = readl(&cru->clksel_con[15]);
1080 		src = (con & SCLK_UART6_SEL_MASK) >> SCLK_UART6_SEL_SHIFT;
1081 		div = (con & SCLK_UART6_DIV_MASK) >> SCLK_UART6_DIV_SHIFT;
1082 		break;
1083 	case SCLK_UART7:
1084 		con = readl(&cru->clksel_con[15]);
1085 		src = (con & SCLK_UART7_SEL_MASK) >> SCLK_UART7_SEL_SHIFT;
1086 		div = (con & SCLK_UART7_DIV_MASK) >> SCLK_UART7_DIV_SHIFT;
1087 		break;
1088 
1089 	default:
1090 		return -ENOENT;
1091 	}
1092 
1093 	switch (src) {
1094 	case SCLK_UART_SEL_OSC:
1095 		p_rate = OSC_HZ;
1096 		break;
1097 	case SCLK_UART_SEL_CM_FRAC0:
1098 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC0);
1099 		break;
1100 	case SCLK_UART_SEL_CM_FRAC1:
1101 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC1);
1102 		break;
1103 	case SCLK_UART_SEL_CM_FRAC2:
1104 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC2);
1105 		break;
1106 	case SCLK_UART_SEL_UART_FRAC0:
1107 		p_rate = rv1126b_frac_get_rate(priv, CLK_UART_FRAC0);
1108 		break;
1109 	case SCLK_UART_SEL_UART_FRAC1:
1110 		p_rate = rv1126b_frac_get_rate(priv, CLK_UART_FRAC1);
1111 		break;
1112 	default:
1113 		return -ENOENT;
1114 	}
1115 
1116 	return DIV_TO_RATE(p_rate, div);
1117 }
1118 
1119 static ulong rv1126b_uart_set_rate(struct rv1126b_clk_priv *priv,
1120 				   ulong clk_id, ulong rate)
1121 {
1122 	struct rv1126b_cru *cru = priv->cru;
1123 	u32 uart_src, div, p_rate;
1124 
1125 	if (rv1126b_frac_get_rate(priv, CLK_CM_FRAC0) % rate == 0) {
1126 		uart_src = SCLK_UART_SEL_CM_FRAC0;
1127 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC0);
1128 	} else if (rv1126b_frac_get_rate(priv, CLK_CM_FRAC1) % rate == 0) {
1129 		uart_src = SCLK_UART_SEL_CM_FRAC1;
1130 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC1);
1131 	} else if (rv1126b_frac_get_rate(priv, CLK_CM_FRAC2) % rate == 0) {
1132 		uart_src = SCLK_UART_SEL_CM_FRAC2;
1133 		p_rate = rv1126b_frac_get_rate(priv, CLK_CM_FRAC2);
1134 	} else if (rv1126b_frac_get_rate(priv, CLK_UART_FRAC0) % rate == 0) {
1135 		uart_src = SCLK_UART_SEL_UART_FRAC0;
1136 		p_rate = rv1126b_frac_get_rate(priv, CLK_UART_FRAC0);
1137 	} else if (rv1126b_frac_get_rate(priv, CLK_UART_FRAC1) % rate == 0) {
1138 		uart_src = SCLK_UART_SEL_UART_FRAC1;
1139 		p_rate = rv1126b_frac_get_rate(priv, CLK_UART_FRAC1);
1140 	} else {
1141 		uart_src = SCLK_UART_SEL_OSC;
1142 		p_rate = OSC_HZ;
1143 	}
1144 
1145 	div = DIV_ROUND_UP(p_rate, rate);
1146 
1147 	switch (clk_id) {
1148 	case SCLK_UART0:
1149 		if (rate == OSC_HZ)
1150 			uart_src = SCLK_UART0_SEL_OSC;
1151 		else if (rate == RC_OSC_HZ)
1152 			uart_src = SCLK_UART0_SEL_RCOSC;
1153 		else
1154 			uart_src = SCLK_UART0_SEL_UART0_SRC;
1155 		rk_clrsetreg(&cru->pmu_clksel_con[3],
1156 			     SCLK_UART0_SEL_MASK,
1157 			     uart_src << SCLK_UART0_SEL_SHIFT);
1158 		if (uart_src == SCLK_UART0_SEL_UART0_SRC)
1159 			rv1126b_uart_set_rate(priv, SCLK_UART0_SRC, rate);
1160 		break;
1161 	case SCLK_UART0_SRC:
1162 		rk_clrsetreg(&cru->clksel_con[12],
1163 			     SCLK_UART0_SRC_SEL_MASK |
1164 			     SCLK_UART0_SRC_DIV_MASK,
1165 			     (uart_src << SCLK_UART0_SRC_SEL_SHIFT) |
1166 			     ((div - 1) <<
1167 			      SCLK_UART0_SRC_DIV_SHIFT));
1168 		break;
1169 	case SCLK_UART1:
1170 		rk_clrsetreg(&cru->clksel_con[12],
1171 			     SCLK_UART1_SEL_MASK |
1172 			     SCLK_UART1_DIV_MASK,
1173 			     (uart_src << SCLK_UART1_SEL_SHIFT) |
1174 			     ((div - 1) <<
1175 			      SCLK_UART1_DIV_SHIFT));
1176 		break;
1177 	case SCLK_UART2:
1178 		rk_clrsetreg(&cru->clksel_con[13],
1179 			     SCLK_UART2_SEL_MASK |
1180 			     SCLK_UART2_DIV_MASK,
1181 			     (uart_src << SCLK_UART2_SEL_SHIFT) |
1182 			     ((div - 1) <<
1183 			      SCLK_UART2_DIV_SHIFT));
1184 		break;
1185 	case SCLK_UART3:
1186 		rk_clrsetreg(&cru->clksel_con[13],
1187 			     SCLK_UART3_SEL_MASK |
1188 			     SCLK_UART3_DIV_MASK,
1189 			     (uart_src << SCLK_UART3_SEL_SHIFT) |
1190 			     ((div - 1) <<
1191 			      SCLK_UART3_DIV_SHIFT));
1192 		break;
1193 	case SCLK_UART4:
1194 		rk_clrsetreg(&cru->clksel_con[14],
1195 			     SCLK_UART4_SEL_MASK |
1196 			     SCLK_UART4_DIV_MASK,
1197 			     (uart_src << SCLK_UART4_SEL_SHIFT) |
1198 			     ((div - 1) <<
1199 			      SCLK_UART4_DIV_SHIFT));
1200 		break;
1201 	case SCLK_UART5:
1202 		rk_clrsetreg(&cru->clksel_con[14],
1203 			     SCLK_UART5_SEL_MASK |
1204 			     SCLK_UART5_DIV_MASK,
1205 			     (uart_src << SCLK_UART5_SEL_SHIFT) |
1206 			     ((div - 1) <<
1207 			      SCLK_UART5_DIV_SHIFT));
1208 		break;
1209 	case SCLK_UART6:
1210 		rk_clrsetreg(&cru->clksel_con[15],
1211 			     SCLK_UART6_SEL_MASK |
1212 			     SCLK_UART6_DIV_MASK,
1213 			     (uart_src << SCLK_UART6_SEL_SHIFT) |
1214 			     ((div - 1) <<
1215 			      SCLK_UART6_DIV_SHIFT));
1216 		break;
1217 	case SCLK_UART7:
1218 		rk_clrsetreg(&cru->clksel_con[15],
1219 			     SCLK_UART7_SEL_MASK |
1220 			     SCLK_UART7_DIV_MASK,
1221 			     (uart_src << SCLK_UART7_SEL_SHIFT) |
1222 			     ((div - 1) <<
1223 			      SCLK_UART7_DIV_SHIFT));
1224 		break;
1225 	default:
1226 		return -ENOENT;
1227 	}
1228 
1229 	return rv1126b_uart_get_rate(priv, clk_id);
1230 }
1231 
1232 static ulong rv1126b_wdt_get_rate(struct rv1126b_clk_priv *priv, ulong clk_id)
1233 {
1234 	struct rv1126b_cru *cru = priv->cru;
1235 	u32 sel, con;
1236 
1237 	switch (clk_id) {
1238 	case TCLK_WDT_NS_SRC:
1239 	case TCLK_WDT_NS:
1240 		con = readl(&cru->clksel_con[46]);
1241 		sel = (con & TCLK_WDT_NS_SEL_MASK) >>
1242 		      TCLK_WDT_NS_SEL_SHIFT;
1243 		break;
1244 	case TCLK_WDT_S:
1245 		con = readl(&cru->clksel_con[46]);
1246 		sel = (con & TCLK_WDT_S_SEL_MASK) >>
1247 		      TCLK_WDT_S_SEL_SHIFT;
1248 		break;
1249 	case TCLK_WDT_HPMCU:
1250 		con = readl(&cru->clksel_con[46]);
1251 		sel = (con & TCLK_WDT_HPMCU_SEL_MASK) >>
1252 		      TCLK_WDT_HPMCU_SEL_SHIFT;
1253 		break;
1254 	case TCLK_WDT_LPMCU:
1255 		con = readl(&cru->pmu_clksel_con[3]);
1256 		sel = (con & TCLK_WDT_LPMCU_SEL_MASK) >>
1257 		      TCLK_WDT_LPMCU_SEL_SHIFT;
1258 		if (sel == TCLK_WDT_LPMCU_SEL_100M)
1259 			return 100 * MHz;
1260 		else if (sel == TCLK_WDT_LPMCU_SEL_RCOSC)
1261 			return RC_OSC_HZ;
1262 		else if (sel == TCLK_WDT_LPMCU_SEL_OSC)
1263 			return OSC_HZ;
1264 		else
1265 			return 32768;
1266 	default:
1267 		return -ENOENT;
1268 	}
1269 
1270 	if (sel == TCLK_WDT_SEL_100M)
1271 		return 100 * MHz;
1272 	else
1273 		return OSC_HZ;
1274 }
1275 
1276 static ulong rv1126b_wdt_set_rate(struct rv1126b_clk_priv *priv,
1277 				  ulong clk_id, ulong rate)
1278 {
1279 	struct rv1126b_cru *cru = priv->cru;
1280 	int src_clk_sel;
1281 
1282 	if (rate == OSC_HZ)
1283 		src_clk_sel = TCLK_WDT_SEL_OSC;
1284 	else
1285 		src_clk_sel = TCLK_WDT_SEL_100M;
1286 
1287 	switch (clk_id) {
1288 	case TCLK_WDT_NS_SRC:
1289 		rk_clrsetreg(&cru->clksel_con[46],
1290 			     TCLK_WDT_NS_SEL_MASK,
1291 			     (src_clk_sel << TCLK_WDT_NS_SEL_SHIFT));
1292 		break;
1293 	case TCLK_WDT_S:
1294 		rk_clrsetreg(&cru->clksel_con[46],
1295 			     TCLK_WDT_NS_SEL_MASK,
1296 			     (src_clk_sel << TCLK_WDT_NS_SEL_SHIFT));
1297 		break;
1298 	case TCLK_WDT_HPMCU:
1299 		rk_clrsetreg(&cru->clksel_con[46],
1300 			     TCLK_WDT_HPMCU_SEL_MASK,
1301 			     (src_clk_sel << TCLK_WDT_HPMCU_SEL_SHIFT));
1302 		break;
1303 	case TCLK_WDT_LPMCU:
1304 		if (rate == OSC_HZ)
1305 			src_clk_sel = TCLK_WDT_LPMCU_SEL_OSC;
1306 		else if (rate == RC_OSC_HZ)
1307 			src_clk_sel = TCLK_WDT_LPMCU_SEL_RCOSC;
1308 		else if (rate == 1000000)
1309 			src_clk_sel = TCLK_WDT_LPMCU_SEL_100M;
1310 		else
1311 			src_clk_sel = TCLK_WDT_LPMCU_SEL_32K;
1312 		rk_clrsetreg(&cru->pmu_clksel_con[3],
1313 			     TCLK_WDT_LPMCU_SEL_MASK,
1314 			     (src_clk_sel << TCLK_WDT_LPMCU_SEL_SHIFT));
1315 		break;
1316 	default:
1317 		return -ENOENT;
1318 	}
1319 	return rv1126b_wdt_get_rate(priv, clk_id);
1320 }
1321 
1322 static ulong rv1126b_vop_get_rate(struct rv1126b_clk_priv *priv, ulong clk_id)
1323 {
1324 	struct rv1126b_cru *cru = priv->cru;
1325 	u32 sel, div, con, p_rate;
1326 
1327 	switch (clk_id) {
1328 	case DCLK_VOP:
1329 		con = readl(&cru->clksel_con[43]);
1330 		sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1331 		div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1332 		break;
1333 	default:
1334 		return -ENOENT;
1335 	}
1336 	if (sel == DCLK_VOP_SEL_CPLL)
1337 		p_rate = priv->cpll_hz;
1338 	else
1339 		p_rate = priv->gpll_hz;
1340 
1341 	return DIV_TO_RATE(p_rate, div);
1342 }
1343 
1344 static ulong rv1126b_vop_set_rate(struct rv1126b_clk_priv *priv,
1345 				 ulong clk_id, ulong rate)
1346 {
1347 	struct rv1126b_cru *cru = priv->cru;
1348 	int src_clk, div, p_rate;
1349 
1350 	if (!(priv->cpll_hz % rate)) {
1351 		src_clk = DCLK_VOP_SEL_CPLL;
1352 		p_rate = priv->cpll_hz;
1353 	} else {
1354 		src_clk = DCLK_VOP_SEL_GPLL;
1355 		p_rate = priv->gpll_hz;
1356 	}
1357 
1358 	div = DIV_ROUND_UP(p_rate, rate);
1359 	switch (clk_id) {
1360 	case DCLK_VOP:
1361 		rk_clrsetreg(&cru->clksel_con[43], DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1362 			     (src_clk << DCLK_VOP_SEL_SHIFT) |
1363 			     ((div - 1) << DCLK_VOP_DIV_SHIFT) );
1364 		break;
1365 	default:
1366 		return -ENOENT;
1367 	}
1368 
1369 	return rv1126b_vop_get_rate(priv, clk_id);
1370 }
1371 
1372 static ulong rv1126b_clk_get_rate(struct clk *clk)
1373 {
1374 	struct rv1126b_clk_priv *priv = dev_get_priv(clk->dev);
1375 	ulong rate = 0;
1376 
1377 	if (!priv->gpll_hz) {
1378 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1379 		return -ENOENT;
1380 	}
1381 
1382 	switch (clk->id) {
1383 	case PLL_GPLL:
1384 		rate = rockchip_pll_get_rate(&rv1126b_pll_clks[GPLL], priv->cru,
1385 					     GPLL);
1386 		break;
1387 	case PLL_AUPLL:
1388 		rate = rockchip_pll_get_rate(&rv1126b_pll_clks[AUPLL],
1389 					     priv->cru, AUPLL);
1390 		break;
1391 	case PLL_CPLL:
1392 		rate = rockchip_pll_get_rate(&rv1126b_pll_clks[CPLL], priv->cru,
1393 					     CPLL);
1394 		break;
1395 	case ACLK_PERI_ROOT:
1396 	case PCLK_PERI_ROOT:
1397 	case ACLK_TOP_ROOT:
1398 	case PCLK_TOP_ROOT:
1399 	case PCLK_BUS_ROOT:
1400 	case BUSCLK_PMU_SRC:
1401 	case ACLK_BUS_ROOT:
1402 	case HCLK_BUS_ROOT:
1403 		rate = rv1126b_peri_get_clk(priv, clk->id);
1404 		break;
1405 	case PCLK_RKCE:
1406 	case HCLK_NS_RKCE:
1407 	case ACLK_RKCE_SRC:
1408 	case ACLK_NSRKCE:
1409 	case CLK_PKA_RKCE_SRC:
1410 	case CLK_PKA_NSRKCE:
1411 		rate = rv1126b_crypto_get_clk(priv, clk->id);
1412 		break;
1413 	case CCLK_SDMMC0:
1414 	case HCLK_SDMMC0:
1415 	case CCLK_SDMMC1:
1416 	case HCLK_SDMMC1:
1417 	case CCLK_EMMC:
1418 	case HCLK_EMMC:
1419 	case SCLK_2X_FSPI0:
1420 	case HCLK_FSPI0:
1421 	case HCLK_XIP_FSPI0:
1422 	case SCLK_1X_FSPI1:
1423 	case HCLK_FSPI1:
1424 	case HCLK_XIP_FSPI1:
1425 		rate = rv1126b_mmc_get_clk(priv, clk->id);
1426 		break;
1427 	case CLK_I2C0:
1428 	case CLK_I2C1:
1429 	case CLK_I2C3:
1430 	case CLK_I2C4:
1431 	case CLK_I2C5:
1432 	case CLK_I2C2:
1433 	case CLK_I2C_BUS_SRC:
1434 		rate = rv1126b_i2c_get_clk(priv, clk->id);
1435 		break;
1436 	case CLK_SPI0:
1437 	case CLK_SPI1:
1438 		rate = rv1126b_spi_get_clk(priv, clk->id);
1439 		break;
1440 	case CLK_PWM0:
1441 	case CLK_PWM2:
1442 	case CLK_PWM3:
1443 	case CLK_PWM1:
1444 		rate = rv1126b_pwm_get_clk(priv, clk->id);
1445 		break;
1446 	case CLK_SARADC0:
1447 	case CLK_SARADC0_SRC:
1448 	case CLK_SARADC1:
1449 	case CLK_SARADC1_SRC:
1450 	case CLK_SARADC2:
1451 	case CLK_SARADC2_SRC:
1452 	case CLK_TSADC:
1453 	case CLK_TSADC_PHYCTRL:
1454 		rate = rv1126b_adc_get_clk(priv, clk->id);
1455 		break;
1456 	case CLK_CM_FRAC0:
1457 	case CLK_CM_FRAC1:
1458 	case CLK_CM_FRAC2:
1459 	case CLK_UART_FRAC0:
1460 	case CLK_UART_FRAC1:
1461 	case CLK_AUDIO_FRAC0:
1462 	case CLK_AUDIO_FRAC1:
1463 		rate = rv1126b_frac_get_rate(priv, clk->id);
1464 		break;
1465 	case SCLK_UART0:
1466 	case SCLK_UART0_SRC:
1467 	case SCLK_UART1:
1468 	case SCLK_UART2:
1469 	case SCLK_UART3:
1470 	case SCLK_UART4:
1471 	case SCLK_UART5:
1472 	case SCLK_UART6:
1473 	case SCLK_UART7:
1474 		rate = rv1126b_uart_get_rate(priv, clk->id);
1475 		break;
1476 	case DCLK_DECOM:
1477 		rate = 400 * MHz;
1478 		break;
1479 	case TCLK_WDT_NS_SRC:
1480 	case TCLK_WDT_NS:
1481 	case TCLK_WDT_S:
1482 	case TCLK_WDT_HPMCU:
1483 	case TCLK_WDT_LPMCU:
1484 		rate = rv1126b_wdt_get_rate(priv, clk->id);
1485 		break;
1486 	case DCLK_VOP:
1487 		rate = rv1126b_vop_get_rate(priv, clk->id);
1488 		break;
1489 
1490 	default:
1491 		return -ENOENT;
1492 	}
1493 
1494 	return rate;
1495 };
1496 
1497 static ulong rv1126b_clk_set_rate(struct clk *clk, ulong rate)
1498 {
1499 	struct rv1126b_clk_priv *priv = dev_get_priv(clk->dev);
1500 	ulong ret = 0;
1501 
1502 	if (!priv->gpll_hz) {
1503 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1504 		return -ENOENT;
1505 	}
1506 
1507 	switch (clk->id) {
1508 	case PLL_GPLL:
1509 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[GPLL], priv->cru,
1510 					    GPLL, rate);
1511 		break;
1512 	case PLL_AUPLL:
1513 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[AUPLL], priv->cru,
1514 					    AUPLL, rate);
1515 		break;
1516 	case PLL_CPLL:
1517 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[CPLL], priv->cru,
1518 					    CPLL, rate);
1519 		break;
1520 	case ACLK_PERI_ROOT:
1521 	case PCLK_PERI_ROOT:
1522 	case ACLK_TOP_ROOT:
1523 	case PCLK_TOP_ROOT:
1524 	case PCLK_BUS_ROOT:
1525 	case BUSCLK_PMU_SRC:
1526 	case ACLK_BUS_ROOT:
1527 	case HCLK_BUS_ROOT:
1528 		ret = rv1126b_peri_set_clk(priv, clk->id, rate);
1529 		break;
1530 	case PCLK_RKCE:
1531 	case HCLK_NS_RKCE:
1532 	case ACLK_RKCE_SRC:
1533 	case ACLK_NSRKCE:
1534 	case CLK_PKA_RKCE_SRC:
1535 	case CLK_PKA_NSRKCE:
1536 		ret = rv1126b_crypto_set_clk(priv, clk->id, rate);
1537 		break;
1538 	case CCLK_SDMMC0:
1539 	case HCLK_SDMMC0:
1540 	case CCLK_SDMMC1:
1541 	case HCLK_SDMMC1:
1542 	case CCLK_EMMC:
1543 	case HCLK_EMMC:
1544 	case SCLK_2X_FSPI0:
1545 	case HCLK_FSPI0:
1546 	case HCLK_XIP_FSPI0:
1547 	case SCLK_1X_FSPI1:
1548 	case HCLK_FSPI1:
1549 	case HCLK_XIP_FSPI1:
1550 		ret = rv1126b_mmc_set_clk(priv, clk->id, rate);
1551 		break;
1552 	case CLK_I2C0:
1553 	case CLK_I2C1:
1554 	case CLK_I2C3:
1555 	case CLK_I2C4:
1556 	case CLK_I2C5:
1557 	case CLK_I2C2:
1558 	case CLK_I2C_BUS_SRC:
1559 		ret = rv1126b_i2c_set_clk(priv, clk->id, rate);
1560 		break;
1561 	case CLK_SPI0:
1562 	case CLK_SPI1:
1563 		ret = rv1126b_spi_set_clk(priv, clk->id, rate);
1564 		break;
1565 	case CLK_PWM0:
1566 	case CLK_PWM2:
1567 	case CLK_PWM3:
1568 	case CLK_PWM1:
1569 		ret = rv1126b_pwm_set_clk(priv, clk->id, rate);
1570 		break;
1571 	case CLK_SARADC0:
1572 	case CLK_SARADC0_SRC:
1573 	case CLK_SARADC1:
1574 	case CLK_SARADC1_SRC:
1575 	case CLK_SARADC2:
1576 	case CLK_SARADC2_SRC:
1577 	case CLK_TSADC:
1578 	case CLK_TSADC_PHYCTRL:
1579 		ret = rv1126b_adc_set_clk(priv, clk->id, rate);
1580 		break;
1581 	case CLK_CM_FRAC0:
1582 	case CLK_CM_FRAC1:
1583 	case CLK_CM_FRAC2:
1584 	case CLK_UART_FRAC0:
1585 	case CLK_UART_FRAC1:
1586 	case CLK_AUDIO_FRAC0:
1587 	case CLK_AUDIO_FRAC1:
1588 		ret = rv1126b_frac_set_rate(priv, clk->id, rate);
1589 		break;
1590 	case SCLK_UART0:
1591 	case SCLK_UART0_SRC:
1592 	case SCLK_UART1:
1593 	case SCLK_UART2:
1594 	case SCLK_UART3:
1595 	case SCLK_UART4:
1596 	case SCLK_UART5:
1597 	case SCLK_UART6:
1598 	case SCLK_UART7:
1599 		ret = rv1126b_uart_set_rate(priv, clk->id, rate);
1600 		break;
1601 	case DCLK_DECOM:
1602 		break;
1603 	case TCLK_WDT_NS_SRC:
1604 	case TCLK_WDT_NS:
1605 	case TCLK_WDT_S:
1606 	case TCLK_WDT_HPMCU:
1607 	case TCLK_WDT_LPMCU:
1608 		ret = rv1126b_wdt_set_rate(priv, clk->id, rate);
1609 		break;
1610 	case DCLK_VOP:
1611 		ret = rv1126b_vop_set_rate(priv, clk->id, rate);
1612 		break;
1613 
1614 	default:
1615 		return -ENOENT;
1616 	}
1617 
1618 	return ret;
1619 };
1620 
1621 static int rv1126b_clk_set_parent(struct clk *clk, struct clk *parent)
1622 {
1623 	switch (clk->id) {
1624 	default:
1625 		return -ENOENT;
1626 	}
1627 
1628 	return 0;
1629 }
1630 
1631 static int rv1126b_clk_enable(struct clk *clk)
1632 {
1633 	ulong ret = 0;
1634 
1635 	switch (clk->id) {
1636 #ifdef CONFIG_SPL_BUILD
1637 	case PCLK_KEY_READER_S:
1638 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 13),
1639 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1640 		break;
1641 	case HCLK_KL_RKCE_S:
1642 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 9),
1643 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1644 		break;
1645 	case HCLK_RKCE_S:
1646 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 8),
1647 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1648 		break;
1649 	case HCLK_RKRNG_S:
1650 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 14),
1651 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1652 		break;
1653 	case CLK_PKA_RKCE_S:
1654 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 13),
1655 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1656 		break;
1657 	case ACLK_RKCE_S:
1658 		ret = writel(BITS_WITH_WMASK(0, 0x1U, 12),
1659 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1660 		break;
1661 #endif
1662 	default:
1663 		return -ENOENT;
1664 	}
1665 	return ret;
1666 }
1667 
1668 static int rv1126b_clk_disable(struct clk *clk)
1669 {
1670 	ulong ret = 0;
1671 
1672 	switch (clk->id) {
1673 #ifdef CONFIG_SPL_BUILD
1674 	case PCLK_KEY_READER_S:
1675 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 13),
1676 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1677 		break;
1678 	case HCLK_KL_RKCE_S:
1679 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 9),
1680 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1681 		break;
1682 	case HCLK_RKCE_S:
1683 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 8),
1684 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(0));
1685 		break;
1686 	case HCLK_RKRNG_S:
1687 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 14),
1688 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1689 		break;
1690 	case CLK_PKA_RKCE_S:
1691 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 13),
1692 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1693 		break;
1694 	case ACLK_RKCE_S:
1695 		ret = writel(BITS_WITH_WMASK(1, 0x1U, 12),
1696 			     RV1126B_CRU_BASE + RV1126B_SBUSCLKGATE_CON(2));
1697 		break;
1698 #endif
1699 	default:
1700 		return -ENOENT;
1701 	}
1702 	return ret;
1703 }
1704 
1705 static struct clk_ops rv1126b_clk_ops = {
1706 	.get_rate = rv1126b_clk_get_rate,
1707 	.set_rate = rv1126b_clk_set_rate,
1708 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1709 	.set_parent = rv1126b_clk_set_parent,
1710 #endif
1711 	.enable = rv1126b_clk_enable,
1712 	.disable = rv1126b_clk_disable,
1713 };
1714 
1715 static void rv1126b_clk_init(struct rv1126b_clk_priv *priv)
1716 {
1717 	int ret;
1718 
1719 	priv->sync_kernel = false;
1720 	priv->gpll_hz = rockchip_pll_get_rate(&rv1126b_pll_clks[GPLL],
1721 					      priv->cru, GPLL);
1722 	if (priv->gpll_hz != GPLL_HZ) {
1723 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[GPLL], priv->cru,
1724 					    GPLL, GPLL_HZ);
1725 		if (!ret)
1726 			priv->gpll_hz = GPLL_HZ;
1727 	}
1728 	priv->aupll_hz = rockchip_pll_get_rate(&rv1126b_pll_clks[AUPLL],
1729 					       priv->cru, AUPLL);
1730 	if (priv->aupll_hz != AUPLL_HZ) {
1731 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[AUPLL], priv->cru,
1732 					    AUPLL, AUPLL_HZ);
1733 		if (!ret)
1734 			priv->aupll_hz = AUPLL_HZ;
1735 	}
1736 	priv->cpll_hz = rockchip_pll_get_rate(&rv1126b_pll_clks[CPLL],
1737 					      priv->cru, CPLL);
1738 	if (priv->cpll_hz != CPLL_HZ) {
1739 		ret = rockchip_pll_set_rate(&rv1126b_pll_clks[CPLL], priv->cru,
1740 					    CPLL, CPLL_HZ);
1741 		if (!ret)
1742 			priv->cpll_hz = CPLL_HZ;
1743 	}
1744 }
1745 
1746 static int rv1126b_clk_probe(struct udevice *dev)
1747 {
1748 	struct rv1126b_clk_priv *priv = dev_get_priv(dev);
1749 	int ret;
1750 
1751 #ifdef CONFIG_SPL_BUILD
1752 	/* fix gpll and some clks modify by maskrom */
1753 	writel(BITS_WITH_WMASK(9, 0x1fU, 5),
1754 	       RV1126B_CRU_BASE + RV1126B_CLKSEL_CON(1));
1755 	writel(BITS_WITH_WMASK(1, 0x1U, 15),
1756 	       RV1126B_CRU_BASE + RV1126B_CLKSEL_CON(1));
1757 	writel(BITS_WITH_WMASK(5, 0x1fU, 5),
1758 	       RV1126B_CRU_BASE + RV1126B_CLKSEL_CON(2));
1759 	writel(BITS_WITH_WMASK(1, 0x7U, 0),
1760 	       RV1126B_CRU_BASE + RV1126B_CLKSEL_CON(60));
1761 	writel(BITS_WITH_WMASK(1, 0x7U, 6),
1762 	       RV1126B_CRU_BASE + RV1126B_PLL_CON(9));
1763 	writel(BITS_WITH_WMASK(1, 0x3U, 4),
1764 	       RV1126B_CRU_BASE + RV1126B_MODE_CON);
1765 	/* Set clk_pka_rkce to 198M */
1766 	writel(BITS_WITH_WMASK(1, 0x1U, 12),
1767 	       RV1126B_CRU_BASE + RV1126B_CLKSEL_CON(50));
1768 #endif
1769 
1770 	rv1126b_clk_init(priv);
1771 
1772 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1773 	ret = clk_set_defaults(dev);
1774 	if (ret)
1775 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1776 	else
1777 		priv->sync_kernel = true;
1778 	return 0;
1779 }
1780 
1781 static int rv1126b_clk_ofdata_to_platdata(struct udevice *dev)
1782 {
1783 	struct rv1126b_clk_priv *priv = dev_get_priv(dev);
1784 
1785 	priv->cru = dev_read_addr_ptr(dev);
1786 
1787 	return 0;
1788 }
1789 
1790 static int rv1126b_clk_bind(struct udevice *dev)
1791 {
1792 	int ret;
1793 	struct udevice *sys_child, *sf_child;
1794 	struct sysreset_reg *priv;
1795 	struct softreset_reg *sf_priv;
1796 
1797 	/* The reset driver does not have a device node, so bind it here */
1798 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1799 				 &sys_child);
1800 	if (ret) {
1801 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1802 	} else {
1803 		priv = malloc(sizeof(struct sysreset_reg));
1804 		priv->glb_srst_fst_value = offsetof(struct rv1126b_cru,
1805 						    glb_srst_fst);
1806 		priv->glb_srst_snd_value = offsetof(struct rv1126b_cru,
1807 						    glb_srst_snd);
1808 		sys_child->priv = priv;
1809 	}
1810 
1811 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1812 					 dev_ofnode(dev), &sf_child);
1813 	if (ret) {
1814 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1815 	} else {
1816 		sf_priv = malloc(sizeof(struct softreset_reg));
1817 		sf_priv->sf_reset_offset = offsetof(struct rv1126b_cru,
1818 						    softrst_con[0]);
1819 		sf_priv->sf_reset_num = CLK_NR_SRST;
1820 		sf_child->priv = sf_priv;
1821 	}
1822 
1823 	return 0;
1824 }
1825 
1826 static const struct udevice_id rv1126b_clk_ids[] = {
1827 	{ .compatible = "rockchip,rv1126b-cru" },
1828 	{ }
1829 };
1830 
1831 U_BOOT_DRIVER(rockchip_rv1126b_cru) = {
1832 	.name		= "rockchip_rv1126b_cru",
1833 	.id		= UCLASS_CLK,
1834 	.of_match	= rv1126b_clk_ids,
1835 	.priv_auto_alloc_size = sizeof(struct rv1126b_clk_priv),
1836 	.ofdata_to_platdata = rv1126b_clk_ofdata_to_platdata,
1837 	.ops		= &rv1126b_clk_ops,
1838 	.bind		= rv1126b_clk_bind,
1839 	.probe		= rv1126b_clk_probe,
1840 };
1841 
1842 #ifndef CONFIG_SPL_BUILD
1843 /**
1844  * soc_clk_dump() - Print clock frequencies
1845  * Returns zero on success
1846  *
1847  * Implementation for the clk dump command.
1848  */
1849 int soc_clk_dump(void)
1850 {
1851 	struct udevice *cru_dev;
1852 	struct rv1126b_clk_priv *priv;
1853 	const struct rv1126b_clk_info *clk_dump;
1854 	struct clk clk;
1855 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1856 	unsigned long rate;
1857 	int i, ret;
1858 
1859 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1860 					  DM_GET_DRIVER(rockchip_rv1126b_cru),
1861 					  &cru_dev);
1862 	if (ret) {
1863 		printf("%s failed to get cru device\n", __func__);
1864 		return ret;
1865 	}
1866 
1867 	priv = dev_get_priv(cru_dev);
1868 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1869 	       priv->sync_kernel ? "sync kernel" : "uboot",
1870 	       priv->armclk_enter_hz / 1000,
1871 	       priv->armclk_init_hz / 1000,
1872 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1873 	       priv->set_armclk_rate ? " KHz" : "N/A");
1874 	for (i = 0; i < clk_count; i++) {
1875 		clk_dump = &clks_dump[i];
1876 		if (clk_dump->name) {
1877 			clk.id = clk_dump->id;
1878 			if (clk_dump->is_cru)
1879 				ret = clk_request(cru_dev, &clk);
1880 			if (ret < 0)
1881 				return ret;
1882 
1883 			rate = clk_get_rate(&clk);
1884 			clk_free(&clk);
1885 			if (i == 0) {
1886 				if (rate < 0)
1887 					printf("  %s %s\n", clk_dump->name,
1888 					       "unknown");
1889 				else
1890 					printf("  %s %lu KHz\n", clk_dump->name,
1891 					       rate / 1000);
1892 			} else {
1893 				if (rate < 0)
1894 					printf("  %s %s\n", clk_dump->name,
1895 					       "unknown");
1896 				else
1897 					printf("  %s %lu KHz\n", clk_dump->name,
1898 					       rate / 1000);
1899 			}
1900 		}
1901 	}
1902 
1903 	return 0;
1904 }
1905 #endif
1906