xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3568.c (revision ee008497bf7dd8c2b4e5b29d197016de4fe5b7b6)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Fuzhou 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_rk3568.h>
15 #include <asm/arch/grf_rk3568.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rk3568-cru.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
24 {								\
25 	.rate	= _rate##U,					\
26 	.aclk_div = _aclk_div,					\
27 	.pclk_div = _pclk_div,					\
28 }
29 
30 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
31 
32 static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = {
33 	RK3568_CPUCLK_RATE(1416000000, 1, 5),
34 	RK3568_CPUCLK_RATE(1296000000, 1, 5),
35 	RK3568_CPUCLK_RATE(1200000000, 1, 3),
36 	RK3568_CPUCLK_RATE(1104000000, 1, 3),
37 	RK3568_CPUCLK_RATE(1008000000, 1, 3),
38 	RK3568_CPUCLK_RATE(912000000, 1, 3),
39 	RK3568_CPUCLK_RATE(816000000, 1, 3),
40 	RK3568_CPUCLK_RATE(600000000, 1, 1),
41 	RK3568_CPUCLK_RATE(408000000, 1, 1),
42 	{ /* sentinel */ },
43 };
44 
45 static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
46 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
47 	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
48 	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
49 	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
50 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
51 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
52 	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
53 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
54 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
55 	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
56 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
57 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
58 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
59 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
60 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
61 	RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
62 	RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
63 	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
64 	{ /* sentinel */ },
65 };
66 
67 static struct rockchip_pll_clock rk3568_pll_clks[] = {
68 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0),
69 		     RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates),
70 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8),
71 		     RK3568_MODE_CON, 2, 10, 0, NULL),
72 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24),
73 		     RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates),
74 	[GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16),
75 		     RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates),
76 	[NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32),
77 		     RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates),
78 	[VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40),
79 		     RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates),
80 	[PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0),
81 		     RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates),
82 	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16),
83 		     RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates),
84 };
85 
86 #ifndef CONFIG_SPL_BUILD
87 #define RK3568_CLK_DUMP(_id, _name, _iscru)	\
88 {						\
89 	.id = _id,				\
90 	.name = _name,				\
91 	.is_cru = _iscru,			\
92 }
93 
94 static const struct rk3568_clk_info clks_dump[] = {
95 	RK3568_CLK_DUMP(PLL_APLL, "apll", true),
96 	RK3568_CLK_DUMP(PLL_DPLL, "dpll", true),
97 	RK3568_CLK_DUMP(PLL_GPLL, "gpll", true),
98 	RK3568_CLK_DUMP(PLL_CPLL, "cpll", true),
99 	RK3568_CLK_DUMP(PLL_NPLL, "npll", true),
100 	RK3568_CLK_DUMP(PLL_VPLL, "vpll", true),
101 	RK3568_CLK_DUMP(PLL_HPLL, "hpll", false),
102 	RK3568_CLK_DUMP(PLL_PPLL, "ppll", false),
103 	RK3568_CLK_DUMP(ARMCLK, "armclk", true),
104 	RK3568_CLK_DUMP(ACLK_BUS, "aclk_bus", true),
105 	RK3568_CLK_DUMP(PCLK_BUS, "pclk_bus", true),
106 	RK3568_CLK_DUMP(ACLK_TOP_HIGH, "aclk_top_high", true),
107 	RK3568_CLK_DUMP(ACLK_TOP_LOW, "aclk_top_low", true),
108 	RK3568_CLK_DUMP(HCLK_TOP, "hclk_top", true),
109 	RK3568_CLK_DUMP(PCLK_TOP, "pclk_top", true),
110 	RK3568_CLK_DUMP(ACLK_PERIMID, "aclk_perimid", true),
111 	RK3568_CLK_DUMP(HCLK_PERIMID, "hclk_perimid", true),
112 	RK3568_CLK_DUMP(PCLK_PMU, "pclk_pmu", false),
113 };
114 #endif
115 
116 static ulong __maybe_unused
117 rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
118 			ulong pll_id, ulong rate)
119 {
120 	struct udevice *pmucru_dev;
121 	struct rk3568_pmuclk_priv *pmu_priv;
122 	int ret;
123 
124 	ret = uclass_get_device_by_driver(UCLASS_CLK,
125 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
126 					  &pmucru_dev);
127 	if (ret) {
128 		printf("%s: could not find pmucru device\n", __func__);
129 		return ret;
130 	}
131 	pmu_priv = dev_get_priv(pmucru_dev);
132 
133 	rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
134 			      pmu_priv->pmucru, pll_id, rate);
135 
136 	return 0;
137 }
138 
139 static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
140 				     ulong pll_id)
141 {
142 	struct udevice *pmucru_dev;
143 	struct rk3568_pmuclk_priv *pmu_priv;
144 	int ret;
145 
146 	ret = uclass_get_device_by_driver(UCLASS_CLK,
147 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
148 					  &pmucru_dev);
149 	if (ret) {
150 		printf("%s: could not find pmucru device\n", __func__);
151 		return ret;
152 	}
153 	pmu_priv = dev_get_priv(pmucru_dev);
154 
155 	return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
156 				      pmu_priv->pmucru, pll_id);
157 }
158 
159 /*
160  *
161  * rational_best_approximation(31415, 10000,
162  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
163  *
164  * you may look at given_numerator as a fixed point number,
165  * with the fractional part size described in given_denominator.
166  *
167  * for theoretical background, see:
168  * http://en.wikipedia.org/wiki/Continued_fraction
169  */
170 static void rational_best_approximation(unsigned long given_numerator,
171 					unsigned long given_denominator,
172 					unsigned long max_numerator,
173 					unsigned long max_denominator,
174 					unsigned long *best_numerator,
175 					unsigned long *best_denominator)
176 {
177 	unsigned long n, d, n0, d0, n1, d1;
178 
179 	n = given_numerator;
180 	d = given_denominator;
181 	n0 = 0;
182 	d1 = 0;
183 	n1 = 1;
184 	d0 = 1;
185 	for (;;) {
186 		unsigned long t, a;
187 
188 		if (n1 > max_numerator || d1 > max_denominator) {
189 			n1 = n0;
190 			d1 = d0;
191 			break;
192 		}
193 		if (d == 0)
194 			break;
195 		t = d;
196 		a = n / d;
197 		d = n % d;
198 		n = t;
199 		t = n0 + a * n1;
200 		n0 = n1;
201 		n1 = t;
202 		t = d0 + a * d1;
203 		d0 = d1;
204 		d1 = t;
205 	}
206 	*best_numerator = n1;
207 	*best_denominator = d1;
208 }
209 
210 static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
211 {
212 	struct rk3568_pmucru *pmucru = priv->pmucru;
213 	unsigned long m, n;
214 	u32 fracdiv;
215 
216 	fracdiv = readl(&pmucru->pmu_clksel_con[1]);
217 	m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
218 	m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
219 	n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
220 	n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
221 
222 	return OSC_HZ * m / n;
223 }
224 
225 static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
226 				      ulong rate)
227 {
228 	struct rk3568_pmucru *pmucru = priv->pmucru;
229 	unsigned long m, n, val;
230 
231 	rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
232 		     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
233 
234 	rational_best_approximation(rate, OSC_HZ,
235 				    GENMASK(16 - 1, 0),
236 				    GENMASK(16 - 1, 0),
237 				    &m, &n);
238 	val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
239 	writel(val, &pmucru->pmu_clksel_con[1]);
240 
241 	return rk3568_rtc32k_get_pmuclk(priv);
242 }
243 
244 static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
245 				   ulong clk_id)
246 {
247 	struct rk3568_pmucru *pmucru = priv->pmucru;
248 	u32 div, con;
249 
250 	switch (clk_id) {
251 	case CLK_I2C0:
252 		con = readl(&pmucru->pmu_clksel_con[3]);
253 		div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
254 		break;
255 	default:
256 		return -ENOENT;
257 	}
258 
259 	return DIV_TO_RATE(priv->ppll_hz, div);
260 }
261 
262 static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
263 				   ulong clk_id, ulong rate)
264 {
265 	struct rk3568_pmucru *pmucru = priv->pmucru;
266 	int src_clk_div;
267 
268 	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
269 	assert(src_clk_div - 1 <= 127);
270 
271 	switch (clk_id) {
272 	case CLK_I2C0:
273 		rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
274 			     (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
275 		break;
276 	default:
277 		return -ENOENT;
278 	}
279 
280 	return rk3568_i2c_get_pmuclk(priv, clk_id);
281 }
282 
283 static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
284 				   ulong clk_id)
285 {
286 	struct rk3568_pmucru *pmucru = priv->pmucru;
287 	u32 div, sel, con, parent;
288 
289 	switch (clk_id) {
290 	case CLK_PWM0:
291 		con = readl(&pmucru->pmu_clksel_con[6]);
292 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
293 		div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
294 		if (sel == CLK_PWM0_SEL_XIN24M)
295 			parent = OSC_HZ;
296 		else
297 			parent = priv->ppll_hz;
298 		break;
299 	default:
300 		return -ENOENT;
301 	}
302 
303 	return DIV_TO_RATE(parent, div);
304 }
305 
306 static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
307 				   ulong clk_id, ulong rate)
308 {
309 	struct rk3568_pmucru *pmucru = priv->pmucru;
310 	int src_clk_div;
311 
312 	switch (clk_id) {
313 	case CLK_PWM0:
314 		if (rate == OSC_HZ) {
315 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
316 				     CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
317 				     (CLK_PWM0_SEL_XIN24M <<
318 				      CLK_PWM0_SEL_SHIFT) |
319 				     0 << CLK_PWM0_SEL_SHIFT);
320 		} else {
321 			src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
322 			assert(src_clk_div - 1 <= 127);
323 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
324 				     CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
325 				     (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) |
326 				     (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
327 		}
328 		break;
329 	default:
330 		return -ENOENT;
331 	}
332 
333 	return rk3568_pwm_get_pmuclk(priv, clk_id);
334 }
335 
336 static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
337 {
338 	struct rk3568_pmucru *pmucru = priv->pmucru;
339 	u32 div, con, sel, parent;
340 
341 	con = readl(&pmucru->pmu_clksel_con[2]);
342 	sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
343 	div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
344 	if (sel)
345 		parent = GPLL_HZ;
346 	else
347 		parent = priv->ppll_hz;
348 
349 	return DIV_TO_RATE(parent, div);
350 }
351 
352 static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
353 				   ulong rate)
354 {
355 	struct rk3568_pmucru *pmucru = priv->pmucru;
356 	int src_clk_div;
357 
358 	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
359 	assert(src_clk_div - 1 <= 31);
360 
361 	rk_clrsetreg(&pmucru->pmu_clksel_con[2],
362 		     PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
363 		     (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) |
364 		     ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
365 
366 	return rk3568_pmu_get_pmuclk(priv);
367 }
368 
369 static ulong rk3568_pmuclk_get_rate(struct clk *clk)
370 {
371 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
372 	ulong rate = 0;
373 
374 	if (!priv->ppll_hz) {
375 		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
376 		return -ENOENT;
377 	}
378 
379 	debug("%s %ld\n", __func__, clk->id);
380 	switch (clk->id) {
381 	case PLL_PPLL:
382 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
383 					     priv->pmucru, PPLL);
384 		break;
385 	case PLL_HPLL:
386 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
387 					     priv->pmucru, HPLL);
388 		break;
389 	case CLK_RTC_32K:
390 	case CLK_RTC32K_FRAC:
391 		rate = rk3568_rtc32k_get_pmuclk(priv);
392 		break;
393 	case CLK_I2C0:
394 		rate = rk3568_i2c_get_pmuclk(priv, clk->id);
395 		break;
396 	case CLK_PWM0:
397 		rate = rk3568_pwm_get_pmuclk(priv, clk->id);
398 		break;
399 	case PCLK_PMU:
400 		rate = rk3568_pmu_get_pmuclk(priv);
401 		break;
402 	default:
403 		return -ENOENT;
404 	}
405 
406 	return rate;
407 }
408 
409 static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
410 {
411 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
412 	ulong ret = 0;
413 
414 	if (!priv->ppll_hz) {
415 		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
416 		return -ENOENT;
417 	}
418 
419 	debug("%s %ld %ld\n", __func__, clk->id, rate);
420 	switch (clk->id) {
421 	case PLL_PPLL:
422 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
423 					    priv->pmucru, PPLL, rate);
424 		priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
425 						      priv->pmucru, PPLL);
426 		break;
427 	case PLL_HPLL:
428 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL],
429 					    priv->pmucru, HPLL, rate);
430 		priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
431 						      priv->pmucru, HPLL);
432 		break;
433 	case CLK_RTC_32K:
434 	case CLK_RTC32K_FRAC:
435 		ret = rk3568_rtc32k_set_pmuclk(priv, rate);
436 		break;
437 	case CLK_I2C0:
438 		ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
439 		break;
440 	case CLK_PWM0:
441 		ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
442 		break;
443 	case PCLK_PMU:
444 		ret = rk3568_pmu_set_pmuclk(priv, rate);
445 		break;
446 	default:
447 		return -ENOENT;
448 	}
449 
450 	return ret;
451 }
452 
453 static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
454 {
455 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
456 	struct rk3568_pmucru *pmucru = priv->pmucru;
457 
458 	if (parent->id == CLK_RTC32K_FRAC)
459 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
460 			     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
461 	else
462 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
463 			     RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
464 
465 	return 0;
466 }
467 
468 static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
469 {
470 	switch (clk->id) {
471 	case CLK_RTC_32K:
472 		return rk3568_rtc32k_set_parent(clk, parent);
473 	default:
474 		return -ENOENT;
475 	}
476 }
477 
478 static struct clk_ops rk3568_pmuclk_ops = {
479 	.get_rate = rk3568_pmuclk_get_rate,
480 	.set_rate = rk3568_pmuclk_set_rate,
481 	.set_parent = rk3568_pmuclk_set_parent,
482 };
483 
484 static int rk3568_pmuclk_probe(struct udevice *dev)
485 {
486 	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
487 	int ret = 0;
488 
489 	if (priv->ppll_hz != PPLL_HZ) {
490 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
491 					    priv->pmucru,
492 					    PPLL, PPLL_HZ);
493 		if (!ret)
494 			priv->ppll_hz = PPLL_HZ;
495 	}
496 
497 	/* Ungate PCIe30phy refclk_m and refclk_n */
498 	rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
499 	return 0;
500 }
501 
502 static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
503 {
504 	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
505 
506 	priv->pmucru = dev_read_addr_ptr(dev);
507 
508 	return 0;
509 }
510 
511 static int rk3568_pmuclk_bind(struct udevice *dev)
512 {
513 	int ret = 0;
514 	struct udevice *sf_child;
515 	struct softreset_reg *sf_priv;
516 
517 	ret = device_bind_driver_to_node(dev, "rockchip_reset",
518 					 "reset", dev_ofnode(dev),
519 					 &sf_child);
520 	if (ret) {
521 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
522 	} else {
523 		sf_priv = malloc(sizeof(struct softreset_reg));
524 		sf_priv->sf_reset_offset = offsetof(struct rk3568_pmucru,
525 						    pmu_softrst_con[0]);
526 		sf_priv->sf_reset_num = 1;
527 		sf_child->priv = sf_priv;
528 	}
529 
530 	return 0;
531 }
532 
533 static const struct udevice_id rk3568_pmuclk_ids[] = {
534 	{ .compatible = "rockchip,rk3568-pmucru" },
535 	{ }
536 };
537 
538 U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
539 	.name		= "rockchip_rk3568_pmucru",
540 	.id		= UCLASS_CLK,
541 	.of_match	= rk3568_pmuclk_ids,
542 	.priv_auto_alloc_size = sizeof(struct rk3568_pmuclk_priv),
543 	.ofdata_to_platdata = rk3568_pmuclk_ofdata_to_platdata,
544 	.ops		= &rk3568_pmuclk_ops,
545 	.bind		= rk3568_pmuclk_bind,
546 	.probe		= rk3568_pmuclk_probe,
547 };
548 
549 static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
550 {
551 	struct rk3568_cru *cru = priv->cru;
552 	const struct rockchip_cpu_rate_table *rate;
553 	ulong old_rate;
554 
555 	rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
556 	if (!rate) {
557 		printf("%s unsupported rate\n", __func__);
558 		return -EINVAL;
559 	}
560 
561 	rk_clrsetreg(&cru->clksel_con[0],
562 		     CLK_CORE_PRE_SEL_MASK,
563 		     (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
564 	rk_clrsetreg(&cru->clksel_con[2],
565 		     SCLK_CORE_PRE_SEL_MASK |
566 		     SCLK_CORE_SRC_SEL_MASK |
567 		     SCLK_CORE_SRC_DIV_MASK,
568 		     (SCLK_CORE_PRE_SEL_SRC <<
569 		      SCLK_CORE_PRE_SEL_SHIFT) |
570 		     (SCLK_CORE_SRC_SEL_APLL <<
571 		      SCLK_CORE_SRC_SEL_SHIFT) |
572 		     (1 << SCLK_CORE_SRC_DIV_SHIFT));
573 
574 	/*
575 	 * set up dependent divisors for DBG and ACLK clocks.
576 	 */
577 	old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
578 					 priv->cru, APLL);
579 	if (old_rate > hz) {
580 		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
581 					  priv->cru, APLL, hz))
582 			return -EINVAL;
583 		rk_clrsetreg(&cru->clksel_con[3],
584 			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
585 			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
586 			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
587 		rk_clrsetreg(&cru->clksel_con[4],
588 			     PERIPHCLK_CORE_PRE_DIV_MASK |
589 			     PCLK_CORE_PRE_DIV_MASK,
590 			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
591 			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
592 		rk_clrsetreg(&cru->clksel_con[5],
593 			     ACLK_CORE_NDFT_DIV_MASK,
594 			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
595 	} else if (old_rate < hz) {
596 		rk_clrsetreg(&cru->clksel_con[3],
597 			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
598 			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
599 			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
600 		rk_clrsetreg(&cru->clksel_con[4],
601 			     PERIPHCLK_CORE_PRE_DIV_MASK |
602 			     PCLK_CORE_PRE_DIV_MASK,
603 			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
604 			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
605 		rk_clrsetreg(&cru->clksel_con[5],
606 			     ACLK_CORE_NDFT_DIV_MASK,
607 			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
608 		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
609 					  priv->cru, APLL, hz))
610 			return -EINVAL;
611 	}
612 
613 	return 0;
614 }
615 
616 static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
617 				      ulong clk_id)
618 {
619 	struct rk3568_cru *cru = priv->cru;
620 	int div, mask, shift, con;
621 
622 	switch (clk_id) {
623 	case CPLL_500M:
624 		con = 78;
625 		mask = CPLL_500M_DIV_MASK;
626 		shift = CPLL_500M_DIV_SHIFT;
627 		break;
628 	case CPLL_333M:
629 		con = 79;
630 		mask = CPLL_333M_DIV_MASK;
631 		shift = CPLL_333M_DIV_SHIFT;
632 		break;
633 	case CPLL_250M:
634 		con = 79;
635 		mask = CPLL_250M_DIV_MASK;
636 		shift = CPLL_250M_DIV_SHIFT;
637 		break;
638 	case CPLL_125M:
639 		con = 80;
640 		mask = CPLL_125M_DIV_MASK;
641 		shift = CPLL_125M_DIV_SHIFT;
642 		break;
643 	case CPLL_100M:
644 		con = 82;
645 		mask = CPLL_100M_DIV_MASK;
646 		shift = CPLL_100M_DIV_SHIFT;
647 		break;
648 	case CPLL_62P5M:
649 		con = 80;
650 		mask = CPLL_62P5M_DIV_MASK;
651 		shift = CPLL_62P5M_DIV_SHIFT;
652 		break;
653 	case CPLL_50M:
654 		con = 81;
655 		mask = CPLL_50M_DIV_MASK;
656 		shift = CPLL_50M_DIV_SHIFT;
657 		break;
658 	case CPLL_25M:
659 		con = 81;
660 		mask = CPLL_25M_DIV_MASK;
661 		shift = CPLL_25M_DIV_SHIFT;
662 		break;
663 	default:
664 		return -ENOENT;
665 	}
666 
667 	div = (readl(&cru->clksel_con[con]) & mask) >> shift;
668 	return DIV_TO_RATE(priv->cpll_hz, div);
669 }
670 
671 static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
672 				      ulong clk_id, ulong rate)
673 {
674 	struct rk3568_cru *cru = priv->cru;
675 	int div, mask, shift, con;
676 
677 	switch (clk_id) {
678 	case CPLL_500M:
679 		con = 78;
680 		mask = CPLL_500M_DIV_MASK;
681 		shift = CPLL_500M_DIV_SHIFT;
682 		break;
683 	case CPLL_333M:
684 		con = 79;
685 		mask = CPLL_333M_DIV_MASK;
686 		shift = CPLL_333M_DIV_SHIFT;
687 		break;
688 	case CPLL_250M:
689 		con = 79;
690 		mask = CPLL_250M_DIV_MASK;
691 		shift = CPLL_250M_DIV_SHIFT;
692 		break;
693 	case CPLL_125M:
694 		con = 80;
695 		mask = CPLL_125M_DIV_MASK;
696 		shift = CPLL_125M_DIV_SHIFT;
697 		break;
698 	case CPLL_100M:
699 		con = 82;
700 		mask = CPLL_100M_DIV_MASK;
701 		shift = CPLL_100M_DIV_SHIFT;
702 		break;
703 	case CPLL_62P5M:
704 		con = 80;
705 		mask = CPLL_62P5M_DIV_MASK;
706 		shift = CPLL_62P5M_DIV_SHIFT;
707 		break;
708 	case CPLL_50M:
709 		con = 81;
710 		mask = CPLL_50M_DIV_MASK;
711 		shift = CPLL_50M_DIV_SHIFT;
712 		break;
713 	case CPLL_25M:
714 		con = 81;
715 		mask = CPLL_25M_DIV_MASK;
716 		shift = CPLL_25M_DIV_SHIFT;
717 		break;
718 	default:
719 		return -ENOENT;
720 	}
721 
722 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
723 	assert(div - 1 <= 31);
724 	rk_clrsetreg(&cru->clksel_con[con],
725 		     mask, (div - 1) << shift);
726 	return rk3568_cpll_div_get_rate(priv, clk_id);
727 }
728 
729 static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
730 {
731 	struct rk3568_cru *cru = priv->cru;
732 	u32 con, sel, rate;
733 
734 	switch (clk_id) {
735 	case ACLK_BUS:
736 		con = readl(&cru->clksel_con[50]);
737 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
738 		if (sel == ACLK_BUS_SEL_200M)
739 			rate = 200 * MHz;
740 		else if (sel == ACLK_BUS_SEL_150M)
741 			rate = 150 * MHz;
742 		else if (sel == ACLK_BUS_SEL_100M)
743 			rate = 100 * MHz;
744 		else
745 			rate = OSC_HZ;
746 		break;
747 	case PCLK_BUS:
748 	case PCLK_WDT_NS:
749 		con = readl(&cru->clksel_con[50]);
750 		sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
751 		if (sel == PCLK_BUS_SEL_100M)
752 			rate = 100 * MHz;
753 		else if (sel == PCLK_BUS_SEL_75M)
754 			rate = 75 * MHz;
755 		else if (sel == PCLK_BUS_SEL_50M)
756 			rate = 50 * MHz;
757 		else
758 			rate = OSC_HZ;
759 		break;
760 	default:
761 		return -ENOENT;
762 	}
763 
764 	return rate;
765 }
766 
767 static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
768 				ulong clk_id, ulong rate)
769 {
770 	struct rk3568_cru *cru = priv->cru;
771 	int src_clk;
772 
773 	switch (clk_id) {
774 	case ACLK_BUS:
775 		if (rate == 200 * MHz)
776 			src_clk = ACLK_BUS_SEL_200M;
777 		else if (rate == 150 * MHz)
778 			src_clk = ACLK_BUS_SEL_150M;
779 		else if (rate == 100 * MHz)
780 			src_clk = ACLK_BUS_SEL_100M;
781 		else
782 			src_clk = ACLK_BUS_SEL_24M;
783 		rk_clrsetreg(&cru->clksel_con[50],
784 			     ACLK_BUS_SEL_MASK,
785 			     src_clk << ACLK_BUS_SEL_SHIFT);
786 		break;
787 	case PCLK_BUS:
788 	case PCLK_WDT_NS:
789 		if (rate == 100 * MHz)
790 			src_clk = PCLK_BUS_SEL_100M;
791 		else if (rate == 75 * MHz)
792 			src_clk = PCLK_BUS_SEL_75M;
793 		else if (rate == 50 * MHz)
794 			src_clk = PCLK_BUS_SEL_50M;
795 		else
796 			src_clk = PCLK_BUS_SEL_24M;
797 		rk_clrsetreg(&cru->clksel_con[50],
798 			     PCLK_BUS_SEL_MASK,
799 			     src_clk << PCLK_BUS_SEL_SHIFT);
800 		break;
801 
802 	default:
803 		printf("do not support this bus freq\n");
804 		return -EINVAL;
805 	}
806 
807 	return rk3568_bus_get_clk(priv, clk_id);
808 }
809 
810 static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
811 {
812 	struct rk3568_cru *cru = priv->cru;
813 	u32 con, sel, rate;
814 
815 	switch (clk_id) {
816 	case ACLK_PERIMID:
817 		con = readl(&cru->clksel_con[10]);
818 		sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
819 		if (sel == ACLK_PERIMID_SEL_300M)
820 			rate = 300 * MHz;
821 		else if (sel == ACLK_PERIMID_SEL_200M)
822 			rate = 200 * MHz;
823 		else if (sel == ACLK_PERIMID_SEL_100M)
824 			rate = 100 * MHz;
825 		else
826 			rate = OSC_HZ;
827 		break;
828 	case HCLK_PERIMID:
829 		con = readl(&cru->clksel_con[10]);
830 		sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
831 		if (sel == HCLK_PERIMID_SEL_150M)
832 			rate = 150 * MHz;
833 		else if (sel == HCLK_PERIMID_SEL_100M)
834 			rate = 100 * MHz;
835 		else if (sel == HCLK_PERIMID_SEL_75M)
836 			rate = 75 * MHz;
837 		else
838 			rate = OSC_HZ;
839 		break;
840 	default:
841 		return -ENOENT;
842 	}
843 
844 	return rate;
845 }
846 
847 static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
848 				    ulong clk_id, ulong rate)
849 {
850 	struct rk3568_cru *cru = priv->cru;
851 	int src_clk;
852 
853 	switch (clk_id) {
854 	case ACLK_PERIMID:
855 		if (rate == 300 * MHz)
856 			src_clk = ACLK_PERIMID_SEL_300M;
857 		else if (rate == 200 * MHz)
858 			src_clk = ACLK_PERIMID_SEL_200M;
859 		else if (rate == 100 * MHz)
860 			src_clk = ACLK_PERIMID_SEL_100M;
861 		else
862 			src_clk = ACLK_PERIMID_SEL_24M;
863 		rk_clrsetreg(&cru->clksel_con[10],
864 			     ACLK_PERIMID_SEL_MASK,
865 			     src_clk << ACLK_PERIMID_SEL_SHIFT);
866 		break;
867 	case HCLK_PERIMID:
868 		if (rate == 150 * MHz)
869 			src_clk = HCLK_PERIMID_SEL_150M;
870 		else if (rate == 100 * MHz)
871 			src_clk = HCLK_PERIMID_SEL_100M;
872 		else if (rate == 75 * MHz)
873 			src_clk = HCLK_PERIMID_SEL_75M;
874 		else
875 			src_clk = HCLK_PERIMID_SEL_24M;
876 		rk_clrsetreg(&cru->clksel_con[10],
877 			     HCLK_PERIMID_SEL_MASK,
878 			     src_clk << HCLK_PERIMID_SEL_SHIFT);
879 		break;
880 
881 	default:
882 		printf("do not support this permid freq\n");
883 		return -EINVAL;
884 	}
885 
886 	return rk3568_perimid_get_clk(priv, clk_id);
887 }
888 
889 static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
890 {
891 	struct rk3568_cru *cru = priv->cru;
892 	u32 con, sel, rate;
893 
894 	switch (clk_id) {
895 	case ACLK_TOP_HIGH:
896 		con = readl(&cru->clksel_con[73]);
897 		sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
898 		if (sel == ACLK_TOP_HIGH_SEL_500M)
899 			rate = 500 * MHz;
900 		else if (sel == ACLK_TOP_HIGH_SEL_400M)
901 			rate = 400 * MHz;
902 		else if (sel == ACLK_TOP_HIGH_SEL_300M)
903 			rate = 300 * MHz;
904 		else
905 			rate = OSC_HZ;
906 		break;
907 	case ACLK_TOP_LOW:
908 		con = readl(&cru->clksel_con[73]);
909 		sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
910 		if (sel == ACLK_TOP_LOW_SEL_400M)
911 			rate = 400 * MHz;
912 		else if (sel == ACLK_TOP_LOW_SEL_300M)
913 			rate = 300 * MHz;
914 		else if (sel == ACLK_TOP_LOW_SEL_200M)
915 			rate = 200 * MHz;
916 		else
917 			rate = OSC_HZ;
918 		break;
919 	case HCLK_TOP:
920 		con = readl(&cru->clksel_con[73]);
921 		sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
922 		if (sel == HCLK_TOP_SEL_150M)
923 			rate = 150 * MHz;
924 		else if (sel == HCLK_TOP_SEL_100M)
925 			rate = 100 * MHz;
926 		else if (sel == HCLK_TOP_SEL_75M)
927 			rate = 75 * MHz;
928 		else
929 			rate = OSC_HZ;
930 		break;
931 	case PCLK_TOP:
932 		con = readl(&cru->clksel_con[73]);
933 		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
934 		if (sel == PCLK_TOP_SEL_100M)
935 			rate = 100 * MHz;
936 		else if (sel == PCLK_TOP_SEL_75M)
937 			rate = 75 * MHz;
938 		else if (sel == PCLK_TOP_SEL_50M)
939 			rate = 50 * MHz;
940 		else
941 			rate = OSC_HZ;
942 		break;
943 	default:
944 		return -ENOENT;
945 	}
946 
947 	return rate;
948 }
949 
950 static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
951 				ulong clk_id, ulong rate)
952 {
953 	struct rk3568_cru *cru = priv->cru;
954 	int src_clk;
955 
956 	switch (clk_id) {
957 	case ACLK_TOP_HIGH:
958 		if (rate == 500 * MHz)
959 			src_clk = ACLK_TOP_HIGH_SEL_500M;
960 		else if (rate == 400 * MHz)
961 			src_clk = ACLK_TOP_HIGH_SEL_400M;
962 		else if (rate == 300 * MHz)
963 			src_clk = ACLK_TOP_HIGH_SEL_300M;
964 		else
965 			src_clk = ACLK_TOP_HIGH_SEL_24M;
966 		rk_clrsetreg(&cru->clksel_con[73],
967 			     ACLK_TOP_HIGH_SEL_MASK,
968 			     src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
969 		break;
970 	case ACLK_TOP_LOW:
971 		if (rate == 400 * MHz)
972 			src_clk = ACLK_TOP_LOW_SEL_400M;
973 		else if (rate == 300 * MHz)
974 			src_clk = ACLK_TOP_LOW_SEL_300M;
975 		else if (rate == 200 * MHz)
976 			src_clk = ACLK_TOP_LOW_SEL_200M;
977 		else
978 			src_clk = ACLK_TOP_LOW_SEL_24M;
979 		rk_clrsetreg(&cru->clksel_con[73],
980 			     ACLK_TOP_LOW_SEL_MASK,
981 			     src_clk << ACLK_TOP_LOW_SEL_SHIFT);
982 		break;
983 	case HCLK_TOP:
984 		if (rate == 150 * MHz)
985 			src_clk = HCLK_TOP_SEL_150M;
986 		else if (rate == 100 * MHz)
987 			src_clk = HCLK_TOP_SEL_100M;
988 		else if (rate == 75 * MHz)
989 			src_clk = HCLK_TOP_SEL_75M;
990 		else
991 			src_clk = HCLK_TOP_SEL_24M;
992 		rk_clrsetreg(&cru->clksel_con[73],
993 			     HCLK_TOP_SEL_MASK,
994 			     src_clk << HCLK_TOP_SEL_SHIFT);
995 		break;
996 	case PCLK_TOP:
997 		if (rate == 100 * MHz)
998 			src_clk = PCLK_TOP_SEL_100M;
999 		else if (rate == 75 * MHz)
1000 			src_clk = PCLK_TOP_SEL_75M;
1001 		else if (rate == 50 * MHz)
1002 			src_clk = PCLK_TOP_SEL_50M;
1003 		else
1004 			src_clk = PCLK_TOP_SEL_24M;
1005 		rk_clrsetreg(&cru->clksel_con[73],
1006 			     PCLK_TOP_SEL_MASK,
1007 			     src_clk << PCLK_TOP_SEL_SHIFT);
1008 		break;
1009 
1010 	default:
1011 		printf("do not support this permid freq\n");
1012 		return -EINVAL;
1013 	}
1014 
1015 	return rk3568_top_get_clk(priv, clk_id);
1016 }
1017 
1018 static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1019 {
1020 	struct rk3568_cru *cru = priv->cru;
1021 	u32 sel, con;
1022 	ulong rate;
1023 
1024 	switch (clk_id) {
1025 	case CLK_I2C1:
1026 	case CLK_I2C2:
1027 	case CLK_I2C3:
1028 	case CLK_I2C4:
1029 	case CLK_I2C5:
1030 		con = readl(&cru->clksel_con[71]);
1031 		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
1032 		if (sel == CLK_I2C_SEL_200M)
1033 			rate = 200 * MHz;
1034 		else if (sel == CLK_I2C_SEL_100M)
1035 			rate = 100 * MHz;
1036 		else if (sel == CLK_I2C_SEL_CPLL_100M)
1037 			rate = 100 * MHz;
1038 		else
1039 			rate = OSC_HZ;
1040 		break;
1041 	default:
1042 		return -ENOENT;
1043 	}
1044 
1045 	return rate;
1046 }
1047 
1048 static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1049 				ulong rate)
1050 {
1051 	struct rk3568_cru *cru = priv->cru;
1052 	int src_clk;
1053 
1054 	if (rate == 200 * MHz)
1055 		src_clk = CLK_I2C_SEL_200M;
1056 	else if (rate == 100 * MHz)
1057 		src_clk = CLK_I2C_SEL_100M;
1058 	else
1059 		src_clk = CLK_I2C_SEL_24M;
1060 
1061 	switch (clk_id) {
1062 	case CLK_I2C1:
1063 	case CLK_I2C2:
1064 	case CLK_I2C3:
1065 	case CLK_I2C4:
1066 	case CLK_I2C5:
1067 		rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1068 			     src_clk << CLK_I2C_SEL_SHIFT);
1069 		break;
1070 	default:
1071 		return -ENOENT;
1072 	}
1073 
1074 	return rk3568_i2c_get_clk(priv, clk_id);
1075 }
1076 
1077 static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1078 {
1079 	struct rk3568_cru *cru = priv->cru;
1080 	u32 sel, con;
1081 
1082 	con = readl(&cru->clksel_con[72]);
1083 
1084 	switch (clk_id) {
1085 	case CLK_SPI0:
1086 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1087 		break;
1088 	case CLK_SPI1:
1089 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1090 		break;
1091 	case CLK_SPI2:
1092 		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1093 		break;
1094 	case CLK_SPI3:
1095 		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1096 		break;
1097 	default:
1098 		return -ENOENT;
1099 	}
1100 
1101 	switch (sel) {
1102 	case CLK_SPI_SEL_200M:
1103 		return 200 * MHz;
1104 	case CLK_SPI_SEL_24M:
1105 		return OSC_HZ;
1106 	case CLK_SPI_SEL_CPLL_100M:
1107 		return 100 * MHz;
1108 	default:
1109 		return -ENOENT;
1110 	}
1111 }
1112 
1113 static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1114 				ulong clk_id, ulong rate)
1115 {
1116 	struct rk3568_cru *cru = priv->cru;
1117 	int src_clk;
1118 
1119 	if (rate == 200 * MHz)
1120 		src_clk = CLK_SPI_SEL_200M;
1121 	else if (rate == 100 * MHz)
1122 		src_clk = CLK_SPI_SEL_CPLL_100M;
1123 	else
1124 		src_clk = CLK_SPI_SEL_24M;
1125 
1126 	switch (clk_id) {
1127 	case CLK_SPI0:
1128 		rk_clrsetreg(&cru->clksel_con[72],
1129 			     CLK_SPI0_SEL_MASK,
1130 			     src_clk << CLK_SPI0_SEL_SHIFT);
1131 		break;
1132 	case CLK_SPI1:
1133 		rk_clrsetreg(&cru->clksel_con[72],
1134 			     CLK_SPI1_SEL_MASK,
1135 			     src_clk << CLK_SPI1_SEL_SHIFT);
1136 		break;
1137 	case CLK_SPI2:
1138 		rk_clrsetreg(&cru->clksel_con[72],
1139 			     CLK_SPI2_SEL_MASK,
1140 			     src_clk << CLK_SPI2_SEL_SHIFT);
1141 		break;
1142 	case CLK_SPI3:
1143 		rk_clrsetreg(&cru->clksel_con[72],
1144 			     CLK_SPI3_SEL_MASK,
1145 			     src_clk << CLK_SPI3_SEL_SHIFT);
1146 		break;
1147 	default:
1148 		return -ENOENT;
1149 	}
1150 
1151 	return rk3568_spi_get_clk(priv, clk_id);
1152 }
1153 
1154 static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1155 {
1156 	struct rk3568_cru *cru = priv->cru;
1157 	u32 sel, con;
1158 
1159 	con = readl(&cru->clksel_con[72]);
1160 
1161 	switch (clk_id) {
1162 	case CLK_PWM1:
1163 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1164 		break;
1165 	case CLK_PWM2:
1166 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1167 		break;
1168 	case CLK_PWM3:
1169 		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1170 		break;
1171 	default:
1172 		return -ENOENT;
1173 	}
1174 
1175 	switch (sel) {
1176 	case CLK_PWM_SEL_100M:
1177 		return 100 * MHz;
1178 	case CLK_PWM_SEL_24M:
1179 		return OSC_HZ;
1180 	case CLK_PWM_SEL_CPLL_100M:
1181 		return 100 * MHz;
1182 	default:
1183 		return -ENOENT;
1184 	}
1185 }
1186 
1187 static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1188 				ulong clk_id, ulong rate)
1189 {
1190 	struct rk3568_cru *cru = priv->cru;
1191 	int src_clk;
1192 
1193 	if (rate == 100 * MHz)
1194 		src_clk = CLK_PWM_SEL_100M;
1195 	else
1196 		src_clk = CLK_PWM_SEL_24M;
1197 
1198 	switch (clk_id) {
1199 	case CLK_PWM1:
1200 		rk_clrsetreg(&cru->clksel_con[72],
1201 			     CLK_PWM1_SEL_MASK,
1202 			     src_clk << CLK_PWM1_SEL_SHIFT);
1203 		break;
1204 	case CLK_PWM2:
1205 		rk_clrsetreg(&cru->clksel_con[72],
1206 			     CLK_PWM2_SEL_MASK,
1207 			     src_clk << CLK_PWM2_SEL_SHIFT);
1208 		break;
1209 	case CLK_PWM3:
1210 		rk_clrsetreg(&cru->clksel_con[72],
1211 			     CLK_PWM3_SEL_MASK,
1212 			     src_clk << CLK_PWM3_SEL_SHIFT);
1213 		break;
1214 	default:
1215 		return -ENOENT;
1216 	}
1217 
1218 	return rk3568_pwm_get_clk(priv, clk_id);
1219 }
1220 
1221 static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1222 {
1223 	struct rk3568_cru *cru = priv->cru;
1224 	u32 div, sel, con, prate;
1225 
1226 	switch (clk_id) {
1227 	case CLK_SARADC:
1228 		return OSC_HZ;
1229 	case CLK_TSADC_TSEN:
1230 		con = readl(&cru->clksel_con[51]);
1231 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
1232 		      CLK_TSADC_TSEN_DIV_SHIFT;
1233 		sel = (con & CLK_TSADC_TSEN_SEL_MASK) >>
1234 		      CLK_TSADC_TSEN_SEL_SHIFT;
1235 		if (sel == CLK_TSADC_TSEN_SEL_24M)
1236 			prate = OSC_HZ;
1237 		else
1238 			prate = 100 * MHz;
1239 		return DIV_TO_RATE(prate, div);
1240 	case CLK_TSADC:
1241 		con = readl(&cru->clksel_con[51]);
1242 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
1243 		prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1244 		return DIV_TO_RATE(prate, div);
1245 	default:
1246 		return -ENOENT;
1247 	}
1248 }
1249 
1250 static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1251 				ulong clk_id, ulong rate)
1252 {
1253 	struct rk3568_cru *cru = priv->cru;
1254 	int src_clk_div;
1255 	ulong prate = 0;
1256 
1257 	switch (clk_id) {
1258 	case CLK_SARADC:
1259 		return OSC_HZ;
1260 	case CLK_TSADC_TSEN:
1261 		if (!(OSC_HZ % rate)) {
1262 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
1263 			assert(src_clk_div - 1 <= 7);
1264 			rk_clrsetreg(&cru->clksel_con[51],
1265 				     CLK_TSADC_TSEN_SEL_MASK |
1266 				     CLK_TSADC_TSEN_DIV_MASK,
1267 				     (CLK_TSADC_TSEN_SEL_24M <<
1268 				      CLK_TSADC_TSEN_SEL_SHIFT) |
1269 				     (src_clk_div - 1) <<
1270 				     CLK_TSADC_TSEN_DIV_SHIFT);
1271 		} else {
1272 			src_clk_div = DIV_ROUND_UP(100 * MHz, rate);
1273 			assert(src_clk_div - 1 <= 7);
1274 			rk_clrsetreg(&cru->clksel_con[51],
1275 				     CLK_TSADC_TSEN_SEL_MASK |
1276 				     CLK_TSADC_TSEN_DIV_MASK,
1277 				     (CLK_TSADC_TSEN_SEL_100M <<
1278 				      CLK_TSADC_TSEN_SEL_SHIFT) |
1279 				     (src_clk_div - 1) <<
1280 				     CLK_TSADC_TSEN_DIV_SHIFT);
1281 		}
1282 		break;
1283 	case CLK_TSADC:
1284 			prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1285 			src_clk_div = DIV_ROUND_UP(prate, rate);
1286 			assert(src_clk_div - 1 <= 128);
1287 			rk_clrsetreg(&cru->clksel_con[51],
1288 				     CLK_TSADC_DIV_MASK,
1289 				     (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1290 		break;
1291 	default:
1292 		return -ENOENT;
1293 	}
1294 	return rk3568_adc_get_clk(priv, clk_id);
1295 }
1296 
1297 static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1298 {
1299 	struct rk3568_cru *cru = priv->cru;
1300 	u32 sel, con;
1301 
1302 	switch (clk_id) {
1303 	case ACLK_SECURE_FLASH:
1304 	case ACLK_CRYPTO_NS:
1305 		con = readl(&cru->clksel_con[27]);
1306 		sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >>
1307 		      ACLK_SECURE_FLASH_SEL_SHIFT;
1308 		if (sel == ACLK_SECURE_FLASH_SEL_200M)
1309 			return 200 * MHz;
1310 		else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1311 			return 150 * MHz;
1312 		else if (sel == ACLK_SECURE_FLASH_SEL_100M)
1313 			return 100 * MHz;
1314 		else
1315 			return 24 * MHz;
1316 	case HCLK_SECURE_FLASH:
1317 	case HCLK_CRYPTO_NS:
1318 	case CLK_CRYPTO_NS_RNG:
1319 		con = readl(&cru->clksel_con[27]);
1320 		sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >>
1321 		      HCLK_SECURE_FLASH_SEL_SHIFT;
1322 		if (sel == HCLK_SECURE_FLASH_SEL_150M)
1323 			return 150 * MHz;
1324 		else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1325 			return 100 * MHz;
1326 		else if (sel == HCLK_SECURE_FLASH_SEL_75M)
1327 			return 75 * MHz;
1328 		else
1329 			return 24 * MHz;
1330 	case CLK_CRYPTO_NS_CORE:
1331 		con = readl(&cru->clksel_con[27]);
1332 		sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >>
1333 		      CLK_CRYPTO_CORE_SEL_SHIFT;
1334 		if (sel == CLK_CRYPTO_CORE_SEL_200M)
1335 			return 200 * MHz;
1336 		else if (sel == CLK_CRYPTO_CORE_SEL_150M)
1337 			return 150 * MHz;
1338 		else
1339 			return 100 * MHz;
1340 	case CLK_CRYPTO_NS_PKA:
1341 		con = readl(&cru->clksel_con[27]);
1342 		sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >>
1343 		      CLK_CRYPTO_PKA_SEL_SHIFT;
1344 		if (sel == CLK_CRYPTO_PKA_SEL_300M)
1345 			return 300 * MHz;
1346 		else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1347 			return 200 * MHz;
1348 		else
1349 			return 100 * MHz;
1350 	default:
1351 		return -ENOENT;
1352 	}
1353 }
1354 
1355 static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1356 				    ulong clk_id, ulong rate)
1357 {
1358 	struct rk3568_cru *cru = priv->cru;
1359 	u32 src_clk, mask, shift;
1360 
1361 	switch (clk_id) {
1362 	case ACLK_SECURE_FLASH:
1363 	case ACLK_CRYPTO_NS:
1364 		mask = ACLK_SECURE_FLASH_SEL_MASK;
1365 		shift = ACLK_SECURE_FLASH_SEL_SHIFT;
1366 		if (rate == 200 * MHz)
1367 			src_clk = ACLK_SECURE_FLASH_SEL_200M;
1368 		else if (rate == 150 * MHz)
1369 			src_clk = ACLK_SECURE_FLASH_SEL_150M;
1370 		else if (rate == 100 * MHz)
1371 			src_clk = ACLK_SECURE_FLASH_SEL_100M;
1372 		else
1373 			src_clk = ACLK_SECURE_FLASH_SEL_24M;
1374 		break;
1375 	case HCLK_SECURE_FLASH:
1376 	case HCLK_CRYPTO_NS:
1377 	case CLK_CRYPTO_NS_RNG:
1378 		mask = HCLK_SECURE_FLASH_SEL_MASK;
1379 		shift = HCLK_SECURE_FLASH_SEL_SHIFT;
1380 		if (rate == 150 * MHz)
1381 			src_clk = HCLK_SECURE_FLASH_SEL_150M;
1382 		else if (rate == 100 * MHz)
1383 			src_clk = HCLK_SECURE_FLASH_SEL_100M;
1384 		else if (rate == 75 * MHz)
1385 			src_clk = HCLK_SECURE_FLASH_SEL_75M;
1386 		else
1387 			src_clk = HCLK_SECURE_FLASH_SEL_24M;
1388 		break;
1389 	case CLK_CRYPTO_NS_CORE:
1390 		mask = CLK_CRYPTO_CORE_SEL_MASK;
1391 		shift = CLK_CRYPTO_CORE_SEL_SHIFT;
1392 		if (rate == 200 * MHz)
1393 			src_clk = CLK_CRYPTO_CORE_SEL_200M;
1394 		else if (rate == 150 * MHz)
1395 			src_clk = CLK_CRYPTO_CORE_SEL_150M;
1396 		else
1397 			src_clk = CLK_CRYPTO_CORE_SEL_100M;
1398 		break;
1399 	case CLK_CRYPTO_NS_PKA:
1400 		mask = CLK_CRYPTO_PKA_SEL_MASK;
1401 		shift = CLK_CRYPTO_PKA_SEL_SHIFT;
1402 		if (rate == 300 * MHz)
1403 			src_clk = CLK_CRYPTO_PKA_SEL_300M;
1404 		else if (rate == 200 * MHz)
1405 			src_clk = CLK_CRYPTO_PKA_SEL_200M;
1406 		else
1407 			src_clk = CLK_CRYPTO_PKA_SEL_100M;
1408 		break;
1409 	default:
1410 		return -ENOENT;
1411 	}
1412 
1413 	rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1414 
1415 	return rk3568_crypto_get_rate(priv, clk_id);
1416 }
1417 
1418 static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1419 {
1420 	struct rk3568_cru *cru = priv->cru;
1421 	u32 sel, con;
1422 
1423 	switch (clk_id) {
1424 	case HCLK_SDMMC0:
1425 	case CLK_SDMMC0:
1426 		con = readl(&cru->clksel_con[30]);
1427 		sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1428 		break;
1429 	case CLK_SDMMC1:
1430 		con = readl(&cru->clksel_con[30]);
1431 		sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1432 		break;
1433 	case CLK_SDMMC2:
1434 		con = readl(&cru->clksel_con[32]);
1435 		sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1436 		break;
1437 	default:
1438 		return -ENOENT;
1439 	}
1440 
1441 	switch (sel) {
1442 	case CLK_SDMMC_SEL_24M:
1443 		return OSC_HZ;
1444 	case CLK_SDMMC_SEL_400M:
1445 		return 400 * MHz;
1446 	case CLK_SDMMC_SEL_300M:
1447 		return 300 * MHz;
1448 	case CLK_SDMMC_SEL_100M:
1449 		return 100 * MHz;
1450 	case CLK_SDMMC_SEL_50M:
1451 		return 50 * MHz;
1452 	case CLK_SDMMC_SEL_750K:
1453 		return 750 * KHz;
1454 	default:
1455 		return -ENOENT;
1456 	}
1457 }
1458 
1459 static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1460 				  ulong clk_id, ulong rate)
1461 {
1462 	struct rk3568_cru *cru = priv->cru;
1463 	int src_clk;
1464 
1465 	switch (rate) {
1466 	case OSC_HZ:
1467 		src_clk = CLK_SDMMC_SEL_24M;
1468 		break;
1469 	case 400 * MHz:
1470 		src_clk = CLK_SDMMC_SEL_400M;
1471 		break;
1472 	case 300 * MHz:
1473 		src_clk = CLK_SDMMC_SEL_300M;
1474 		break;
1475 	case 100 * MHz:
1476 		src_clk = CLK_SDMMC_SEL_100M;
1477 		break;
1478 	case 52 * MHz:
1479 	case 50 * MHz:
1480 		src_clk = CLK_SDMMC_SEL_50M;
1481 		break;
1482 	case 750 * KHz:
1483 	case 400 * KHz:
1484 		src_clk = CLK_SDMMC_SEL_750K;
1485 		break;
1486 	default:
1487 		return -ENOENT;
1488 	}
1489 
1490 	switch (clk_id) {
1491 	case HCLK_SDMMC0:
1492 	case CLK_SDMMC0:
1493 		rk_clrsetreg(&cru->clksel_con[30],
1494 			     CLK_SDMMC0_SEL_MASK,
1495 			     src_clk << CLK_SDMMC0_SEL_SHIFT);
1496 		break;
1497 	case CLK_SDMMC1:
1498 		rk_clrsetreg(&cru->clksel_con[30],
1499 			     CLK_SDMMC1_SEL_MASK,
1500 			     src_clk << CLK_SDMMC1_SEL_SHIFT);
1501 		break;
1502 	case CLK_SDMMC2:
1503 		rk_clrsetreg(&cru->clksel_con[32],
1504 			     CLK_SDMMC2_SEL_MASK,
1505 			     src_clk << CLK_SDMMC2_SEL_SHIFT);
1506 		break;
1507 	default:
1508 		return -ENOENT;
1509 	}
1510 
1511 	return rk3568_sdmmc_get_clk(priv, clk_id);
1512 }
1513 
1514 static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1515 {
1516 	struct rk3568_cru *cru = priv->cru;
1517 	u32 sel, con;
1518 
1519 	con = readl(&cru->clksel_con[28]);
1520 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1521 	switch (sel) {
1522 	case SCLK_SFC_SEL_24M:
1523 		return OSC_HZ;
1524 	case SCLK_SFC_SEL_50M:
1525 		return 50 * MHz;
1526 	case SCLK_SFC_SEL_75M:
1527 		return 75 * MHz;
1528 	case SCLK_SFC_SEL_100M:
1529 		return 100 * MHz;
1530 	case SCLK_SFC_SEL_125M:
1531 		return 125 * MHz;
1532 	case SCLK_SFC_SEL_150M:
1533 		return 150 * MHz;
1534 	default:
1535 		return -ENOENT;
1536 	}
1537 }
1538 
1539 static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1540 {
1541 	struct rk3568_cru *cru = priv->cru;
1542 	int src_clk;
1543 
1544 	switch (rate) {
1545 	case OSC_HZ:
1546 		src_clk = SCLK_SFC_SEL_24M;
1547 		break;
1548 	case 50 * MHz:
1549 		src_clk = SCLK_SFC_SEL_50M;
1550 		break;
1551 	case 75 * MHz:
1552 		src_clk = SCLK_SFC_SEL_75M;
1553 		break;
1554 	case 100 * MHz:
1555 		src_clk = SCLK_SFC_SEL_100M;
1556 		break;
1557 	case 125 * MHz:
1558 		src_clk = SCLK_SFC_SEL_125M;
1559 		break;
1560 	case 150 * MHz:
1561 		src_clk = SCLK_SFC_SEL_150M;
1562 		break;
1563 	default:
1564 		return -ENOENT;
1565 	}
1566 
1567 	rk_clrsetreg(&cru->clksel_con[28],
1568 		     SCLK_SFC_SEL_MASK,
1569 		     src_clk << SCLK_SFC_SEL_SHIFT);
1570 
1571 	return rk3568_sfc_get_clk(priv);
1572 }
1573 
1574 static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1575 {
1576 	struct rk3568_cru *cru = priv->cru;
1577 	u32 sel, con;
1578 
1579 	con = readl(&cru->clksel_con[28]);
1580 	sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1581 	switch (sel) {
1582 	case NCLK_NANDC_SEL_200M:
1583 		return 200 * MHz;
1584 	case NCLK_NANDC_SEL_150M:
1585 		return 150 * MHz;
1586 	case NCLK_NANDC_SEL_100M:
1587 		return 100 * MHz;
1588 	case NCLK_NANDC_SEL_24M:
1589 		return OSC_HZ;
1590 	default:
1591 		return -ENOENT;
1592 	}
1593 }
1594 
1595 static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1596 {
1597 	struct rk3568_cru *cru = priv->cru;
1598 	int src_clk;
1599 
1600 	switch (rate) {
1601 	case OSC_HZ:
1602 		src_clk = NCLK_NANDC_SEL_24M;
1603 		break;
1604 	case 100 * MHz:
1605 		src_clk = NCLK_NANDC_SEL_100M;
1606 		break;
1607 	case 150 * MHz:
1608 		src_clk = NCLK_NANDC_SEL_150M;
1609 		break;
1610 	case 200 * MHz:
1611 		src_clk = NCLK_NANDC_SEL_200M;
1612 		break;
1613 	default:
1614 		return -ENOENT;
1615 	}
1616 
1617 	rk_clrsetreg(&cru->clksel_con[28],
1618 		     NCLK_NANDC_SEL_MASK,
1619 		     src_clk << NCLK_NANDC_SEL_SHIFT);
1620 
1621 	return rk3568_nand_get_clk(priv);
1622 }
1623 
1624 static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1625 {
1626 	struct rk3568_cru *cru = priv->cru;
1627 	u32 sel, con;
1628 
1629 	con = readl(&cru->clksel_con[28]);
1630 	sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1631 	switch (sel) {
1632 	case CCLK_EMMC_SEL_200M:
1633 		return 200 * MHz;
1634 	case CCLK_EMMC_SEL_150M:
1635 		return 150 * MHz;
1636 	case CCLK_EMMC_SEL_100M:
1637 		return 100 * MHz;
1638 	case CCLK_EMMC_SEL_50M:
1639 		return 50 * MHz;
1640 	case CCLK_EMMC_SEL_375K:
1641 		return 375 * KHz;
1642 	case CCLK_EMMC_SEL_24M:
1643 		return OSC_HZ;
1644 	default:
1645 		return -ENOENT;
1646 	}
1647 }
1648 
1649 static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1650 {
1651 	struct rk3568_cru *cru = priv->cru;
1652 	int src_clk;
1653 
1654 	switch (rate) {
1655 	case OSC_HZ:
1656 		src_clk = CCLK_EMMC_SEL_24M;
1657 		break;
1658 	case 52 * MHz:
1659 	case 50 * MHz:
1660 		src_clk = CCLK_EMMC_SEL_50M;
1661 		break;
1662 	case 100 * MHz:
1663 		src_clk = CCLK_EMMC_SEL_100M;
1664 		break;
1665 	case 150 * MHz:
1666 		src_clk = CCLK_EMMC_SEL_150M;
1667 		break;
1668 	case 200 * MHz:
1669 		src_clk = CCLK_EMMC_SEL_200M;
1670 		break;
1671 	case 400 * KHz:
1672 	case 375 * KHz:
1673 		src_clk = CCLK_EMMC_SEL_375K;
1674 		break;
1675 	default:
1676 		return -ENOENT;
1677 	}
1678 
1679 	rk_clrsetreg(&cru->clksel_con[28],
1680 		     CCLK_EMMC_SEL_MASK,
1681 		     src_clk << CCLK_EMMC_SEL_SHIFT);
1682 
1683 	return rk3568_emmc_get_clk(priv);
1684 }
1685 
1686 #ifndef CONFIG_SPL_BUILD
1687 static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1688 {
1689 	struct rk3568_cru *cru = priv->cru;
1690 	u32 div, sel, con, parent;
1691 
1692 	con = readl(&cru->clksel_con[38]);
1693 	div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1694 	sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1695 	if (sel == ACLK_VOP_PRE_SEL_GPLL)
1696 		parent = priv->gpll_hz;
1697 	else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1698 		parent = priv->cpll_hz;
1699 	else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1700 		parent = priv->vpll_hz;
1701 	else
1702 		parent = priv->hpll_hz;
1703 
1704 	return DIV_TO_RATE(parent, div);
1705 }
1706 
1707 static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1708 {
1709 	struct rk3568_cru *cru = priv->cru;
1710 	int src_clk_div, src_clk_mux;
1711 
1712 	if ((priv->cpll_hz % rate) == 0) {
1713 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1714 		src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1715 	} else {
1716 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1717 		src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1718 	}
1719 	assert(src_clk_div - 1 <= 31);
1720 	rk_clrsetreg(&cru->clksel_con[38],
1721 		     ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1722 		     src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1723 		     (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1724 
1725 	return rk3568_aclk_vop_get_clk(priv);
1726 }
1727 
1728 static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1729 {
1730 	struct rk3568_cru *cru = priv->cru;
1731 	u32 conid, div, sel, con, parent;
1732 
1733 	switch (clk_id) {
1734 	case DCLK_VOP0:
1735 		conid = 39;
1736 		break;
1737 	case DCLK_VOP1:
1738 		conid = 40;
1739 		break;
1740 	case DCLK_VOP2:
1741 		conid = 41;
1742 		break;
1743 	default:
1744 		return -ENOENT;
1745 	}
1746 
1747 	con = readl(&cru->clksel_con[conid]);
1748 	div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1749 	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1750 	if (sel == DCLK_VOP_SEL_HPLL)
1751 		parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1752 	else if (sel == DCLK_VOP_SEL_VPLL)
1753 		parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1754 					       priv->cru, VPLL);
1755 	else if (sel == DCLK_VOP_SEL_GPLL)
1756 		parent = priv->gpll_hz;
1757 	else if (sel == DCLK_VOP_SEL_CPLL)
1758 		parent = priv->cpll_hz;
1759 	else
1760 		return -ENOENT;
1761 
1762 	return DIV_TO_RATE(parent, div);
1763 }
1764 
1765 #define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1766 
1767 static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1768 				     ulong clk_id, ulong rate)
1769 {
1770 	struct rk3568_cru *cru = priv->cru;
1771 	ulong pll_rate, now, best_rate = 0;
1772 	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1773 
1774 	switch (clk_id) {
1775 	case DCLK_VOP0:
1776 		conid = 39;
1777 		break;
1778 	case DCLK_VOP1:
1779 		conid = 40;
1780 		break;
1781 	case DCLK_VOP2:
1782 		conid = 41;
1783 		break;
1784 	default:
1785 		return -ENOENT;
1786 	}
1787 
1788 	con = readl(&cru->clksel_con[conid]);
1789 	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1790 
1791 	if (sel == DCLK_VOP_SEL_HPLL) {
1792 		div = 1;
1793 		rk_clrsetreg(&cru->clksel_con[conid],
1794 			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1795 			     (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1796 			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1797 		rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1798 	} else if (sel == DCLK_VOP_SEL_VPLL) {
1799 		div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1800 		rk_clrsetreg(&cru->clksel_con[conid],
1801 			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1802 			     (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1803 			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1804 		rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1805 				      priv->cru, VPLL, div * rate);
1806 	} else {
1807 		for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1808 			switch (i) {
1809 			case DCLK_VOP_SEL_GPLL:
1810 				pll_rate = priv->gpll_hz;
1811 				break;
1812 			case DCLK_VOP_SEL_CPLL:
1813 				pll_rate = priv->cpll_hz;
1814 				break;
1815 			default:
1816 				printf("do not support this vop pll sel\n");
1817 				return -EINVAL;
1818 			}
1819 
1820 			div = DIV_ROUND_UP(pll_rate, rate);
1821 			if (div > 255)
1822 				continue;
1823 			now = pll_rate / div;
1824 			if (abs(rate - now) < abs(rate - best_rate)) {
1825 				best_rate = now;
1826 				best_div = div;
1827 				best_sel = i;
1828 			}
1829 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1830 			      pll_rate, best_rate, best_div, best_sel);
1831 		}
1832 
1833 		if (best_rate) {
1834 			rk_clrsetreg(&cru->clksel_con[conid],
1835 				     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1836 				     best_sel << DCLK0_VOP_SEL_SHIFT |
1837 				     (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1838 		} else {
1839 			printf("do not support this vop freq %lu\n", rate);
1840 			return -EINVAL;
1841 		}
1842 	}
1843 	return rk3568_dclk_vop_get_clk(priv, clk_id);
1844 }
1845 
1846 static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1847 				     ulong mac_id)
1848 {
1849 	struct rk3568_cru *cru = priv->cru;
1850 	u32 sel, con;
1851 
1852 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1853 	sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1854 
1855 	switch (sel) {
1856 	case CLK_MAC0_2TOP_SEL_125M:
1857 		return 125 * MHz;
1858 	case CLK_MAC0_2TOP_SEL_50M:
1859 		return 50 * MHz;
1860 	case CLK_MAC0_2TOP_SEL_25M:
1861 		return 25 * MHz;
1862 	case CLK_MAC0_2TOP_SEL_PPLL:
1863 		return rk3568_pmu_pll_get_rate(priv, HPLL);
1864 	default:
1865 		return -ENOENT;
1866 	}
1867 }
1868 
1869 static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1870 				     ulong mac_id, ulong rate)
1871 {
1872 	struct rk3568_cru *cru = priv->cru;
1873 	int src_clk;
1874 
1875 	switch (rate) {
1876 	case 125 * MHz:
1877 		src_clk = CLK_MAC0_2TOP_SEL_125M;
1878 		break;
1879 	case 50 * MHz:
1880 		src_clk = CLK_MAC0_2TOP_SEL_50M;
1881 		break;
1882 	case 25 * MHz:
1883 		src_clk = CLK_MAC0_2TOP_SEL_25M;
1884 		break;
1885 	default:
1886 		return -ENOENT;
1887 	}
1888 
1889 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1890 		     CLK_MAC0_2TOP_SEL_MASK,
1891 		     src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1892 
1893 	return rk3568_gmac_src_get_clk(priv, mac_id);
1894 }
1895 
1896 static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1897 				     ulong mac_id)
1898 {
1899 	struct rk3568_cru *cru = priv->cru;
1900 	u32 sel, con;
1901 
1902 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1903 	sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1904 
1905 	switch (sel) {
1906 	case CLK_MAC0_OUT_SEL_125M:
1907 		return 125 * MHz;
1908 	case CLK_MAC0_OUT_SEL_50M:
1909 		return 50 * MHz;
1910 	case CLK_MAC0_OUT_SEL_25M:
1911 		return 25 * MHz;
1912 	case CLK_MAC0_OUT_SEL_24M:
1913 		return OSC_HZ;
1914 	default:
1915 		return -ENOENT;
1916 	}
1917 }
1918 
1919 static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1920 				     ulong mac_id, ulong rate)
1921 {
1922 	struct rk3568_cru *cru = priv->cru;
1923 	int src_clk;
1924 
1925 	switch (rate) {
1926 	case 125 * MHz:
1927 		src_clk = CLK_MAC0_OUT_SEL_125M;
1928 		break;
1929 	case 50 * MHz:
1930 		src_clk = CLK_MAC0_OUT_SEL_50M;
1931 		break;
1932 	case 25 * MHz:
1933 		src_clk = CLK_MAC0_OUT_SEL_25M;
1934 		break;
1935 	case 24 * MHz:
1936 		src_clk = CLK_MAC0_OUT_SEL_24M;
1937 		break;
1938 	default:
1939 		return -ENOENT;
1940 	}
1941 
1942 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1943 		     CLK_MAC0_OUT_SEL_MASK,
1944 		     src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1945 
1946 	return rk3568_gmac_out_get_clk(priv, mac_id);
1947 }
1948 
1949 static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1950 					 ulong mac_id)
1951 {
1952 	struct rk3568_cru *cru = priv->cru;
1953 	u32 sel, con;
1954 
1955 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1956 	sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1957 
1958 	switch (sel) {
1959 	case CLK_GMAC0_PTP_REF_SEL_62_5M:
1960 		return 62500 * KHz;
1961 	case CLK_GMAC0_PTP_REF_SEL_100M:
1962 		return 100 * MHz;
1963 	case CLK_GMAC0_PTP_REF_SEL_50M:
1964 		return 50 * MHz;
1965 	case CLK_GMAC0_PTP_REF_SEL_24M:
1966 		return OSC_HZ;
1967 	default:
1968 		return -ENOENT;
1969 	}
1970 }
1971 
1972 static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1973 					 ulong mac_id, ulong rate)
1974 {
1975 	struct rk3568_cru *cru = priv->cru;
1976 	int src_clk;
1977 
1978 	switch (rate) {
1979 	case 62500 * KHz:
1980 		src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
1981 		break;
1982 	case 100 * MHz:
1983 		src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
1984 		break;
1985 	case 50 * MHz:
1986 		src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
1987 		break;
1988 	case 24 * MHz:
1989 		src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
1990 		break;
1991 	default:
1992 		return -ENOENT;
1993 	}
1994 
1995 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1996 		     CLK_GMAC0_PTP_REF_SEL_MASK,
1997 		     src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
1998 
1999 	return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2000 }
2001 
2002 static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2003 				       ulong mac_id, ulong rate)
2004 {
2005 	struct rk3568_cru *cru = priv->cru;
2006 	u32 con, sel, div_sel;
2007 
2008 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
2009 	sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2010 
2011 	if (sel == RMII0_MODE_SEL_RGMII) {
2012 		if (rate == 2500000)
2013 			div_sel = RGMII0_CLK_SEL_2_5M;
2014 		else if (rate == 25000000)
2015 			div_sel = RGMII0_CLK_SEL_25M;
2016 		else
2017 			div_sel = RGMII0_CLK_SEL_125M;
2018 		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2019 			     RGMII0_CLK_SEL_MASK,
2020 			     div_sel << RGMII0_CLK_SEL_SHIFT);
2021 	} else if (sel == RMII0_MODE_SEL_RMII) {
2022 		if (rate == 2500000)
2023 			div_sel = RMII0_CLK_SEL_2_5M;
2024 		else
2025 			div_sel = RMII0_CLK_SEL_25M;
2026 		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2027 			     RMII0_CLK_SEL_MASK,
2028 			     div_sel << RMII0_CLK_SEL_SHIFT);
2029 	}
2030 
2031 	return 0;
2032 }
2033 
2034 static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2035 {
2036 	struct rk3568_cru *cru = priv->cru;
2037 	u32 con, div, p_rate;
2038 
2039 	con = readl(&cru->clksel_con[79]);
2040 	div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2041 	p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2042 
2043 	con = readl(&cru->clksel_con[43]);
2044 	div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2045 	switch (div) {
2046 	case DCLK_EBC_SEL_GPLL_400M:
2047 		return 400 * MHz;
2048 	case DCLK_EBC_SEL_CPLL_333M:
2049 		return p_rate;
2050 	case DCLK_EBC_SEL_GPLL_200M:
2051 		return 200 * MHz;
2052 	default:
2053 		return -ENOENT;
2054 	}
2055 }
2056 
2057 static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2058 {
2059 	struct rk3568_cru *cru = priv->cru;
2060 	int src_clk_div;
2061 
2062 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2063 	assert(src_clk_div - 1 <= 31);
2064 	rk_clrsetreg(&cru->clksel_con[79],
2065 		     CPLL_333M_DIV_MASK,
2066 		     (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2067 	rk_clrsetreg(&cru->clksel_con[43],
2068 		     DCLK_EBC_SEL_MASK,
2069 		     DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2070 
2071 	return rk3568_ebc_get_clk(priv);
2072 }
2073 
2074 static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2075 {
2076 	struct rk3568_cru *cru = priv->cru;
2077 	u32 con, div, src, p_rate;
2078 
2079 	switch (clk_id) {
2080 	case ACLK_RKVDEC_PRE:
2081 	case ACLK_RKVDEC:
2082 		con = readl(&cru->clksel_con[47]);
2083 		src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2084 		div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2085 		if (src == ACLK_RKVDEC_SEL_CPLL)
2086 			p_rate = priv->cpll_hz;
2087 		else
2088 			p_rate = priv->gpll_hz;
2089 		return DIV_TO_RATE(p_rate, div);
2090 	case CLK_RKVDEC_CORE:
2091 		con = readl(&cru->clksel_con[49]);
2092 		src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2093 		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2094 		div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2095 		      >> CLK_RKVDEC_CORE_DIV_SHIFT;
2096 		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2097 			p_rate = priv->cpll_hz;
2098 		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2099 			p_rate = priv->npll_hz;
2100 		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2101 			p_rate = priv->vpll_hz;
2102 		else
2103 			p_rate = priv->gpll_hz;
2104 		return DIV_TO_RATE(p_rate, div);
2105 	default:
2106 		return -ENOENT;
2107 	}
2108 }
2109 
2110 static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2111 				   ulong clk_id, ulong rate)
2112 {
2113 	struct rk3568_cru *cru = priv->cru;
2114 	int src_clk_div, src, p_rate;
2115 
2116 	switch (clk_id) {
2117 	case ACLK_RKVDEC_PRE:
2118 	case ACLK_RKVDEC:
2119 		src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2120 		      >> ACLK_RKVDEC_SEL_SHIFT;
2121 		if (src == ACLK_RKVDEC_SEL_CPLL)
2122 			p_rate = priv->cpll_hz;
2123 		else
2124 			p_rate = priv->gpll_hz;
2125 		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2126 		assert(src_clk_div - 1 <= 31);
2127 		rk_clrsetreg(&cru->clksel_con[47],
2128 			     ACLK_RKVDEC_SEL_MASK |
2129 			     ACLK_RKVDEC_DIV_MASK,
2130 			     (src << ACLK_RKVDEC_SEL_SHIFT) |
2131 			     (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2132 		break;
2133 	case CLK_RKVDEC_CORE:
2134 		src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2135 		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2136 		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2137 			p_rate = priv->cpll_hz;
2138 		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2139 			p_rate = priv->npll_hz;
2140 		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2141 			p_rate = priv->vpll_hz;
2142 		else
2143 			p_rate = priv->gpll_hz;
2144 		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2145 		assert(src_clk_div - 1 <= 31);
2146 		rk_clrsetreg(&cru->clksel_con[49],
2147 			     CLK_RKVDEC_CORE_SEL_MASK |
2148 			     CLK_RKVDEC_CORE_DIV_MASK,
2149 			     (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2150 			     (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2151 		break;
2152 	default:
2153 		return -ENOENT;
2154 	}
2155 
2156 	return rk3568_rkvdec_get_clk(priv, clk_id);
2157 }
2158 
2159 static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2160 {
2161 	struct rk3568_cru *cru = priv->cru;
2162 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
2163 	unsigned long m, n;
2164 
2165 	switch (clk_id) {
2166 	case SCLK_UART1:
2167 		reg = 52;
2168 		break;
2169 	case SCLK_UART2:
2170 		reg = 54;
2171 		break;
2172 	case SCLK_UART3:
2173 		reg = 56;
2174 		break;
2175 	case SCLK_UART4:
2176 		reg = 58;
2177 		break;
2178 	case SCLK_UART5:
2179 		reg = 60;
2180 		break;
2181 	case SCLK_UART6:
2182 		reg = 62;
2183 		break;
2184 	case SCLK_UART7:
2185 		reg = 64;
2186 		break;
2187 	case SCLK_UART8:
2188 		reg = 66;
2189 		break;
2190 	case SCLK_UART9:
2191 		reg = 68;
2192 		break;
2193 	default:
2194 		return -ENOENT;
2195 	}
2196 	con = readl(&cru->clksel_con[reg]);
2197 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2198 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2199 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2200 	if (p_src == CLK_UART_SRC_SEL_GPLL)
2201 		p_rate = priv->gpll_hz;
2202 	else if (p_src == CLK_UART_SRC_SEL_CPLL)
2203 		p_rate = priv->cpll_hz;
2204 	else
2205 		p_rate = 480000000;
2206 	if (src == CLK_UART_SEL_SRC) {
2207 		return DIV_TO_RATE(p_rate, div);
2208 	} else if (src == CLK_UART_SEL_FRAC) {
2209 		fracdiv = readl(&cru->clksel_con[reg + 1]);
2210 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2211 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2212 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2213 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2214 		return DIV_TO_RATE(p_rate, div) * n / m;
2215 	} else {
2216 		return OSC_HZ;
2217 	}
2218 }
2219 
2220 static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2221 				  ulong clk_id, ulong rate)
2222 {
2223 	struct rk3568_cru *cru = priv->cru;
2224 	u32 reg, clk_src, uart_src, div;
2225 	unsigned long m = 0, n = 0, val;
2226 
2227 	if (priv->gpll_hz % rate == 0) {
2228 		clk_src = CLK_UART_SRC_SEL_GPLL;
2229 		uart_src = CLK_UART_SEL_SRC;
2230 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2231 	} else if (priv->cpll_hz % rate == 0) {
2232 		clk_src = CLK_UART_SRC_SEL_CPLL;
2233 		uart_src = CLK_UART_SEL_SRC;
2234 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2235 	} else if (rate == OSC_HZ) {
2236 		clk_src = CLK_UART_SRC_SEL_GPLL;
2237 		uart_src = CLK_UART_SEL_XIN24M;
2238 		div = 2;
2239 	} else {
2240 		clk_src = CLK_UART_SRC_SEL_GPLL;
2241 		uart_src = CLK_UART_SEL_FRAC;
2242 		div = 2;
2243 		rational_best_approximation(rate, priv->gpll_hz / div,
2244 					    GENMASK(16 - 1, 0),
2245 					    GENMASK(16 - 1, 0),
2246 					    &m, &n);
2247 	}
2248 
2249 	switch (clk_id) {
2250 	case SCLK_UART1:
2251 		reg = 52;
2252 		break;
2253 	case SCLK_UART2:
2254 		reg = 54;
2255 		break;
2256 	case SCLK_UART3:
2257 		reg = 56;
2258 		break;
2259 	case SCLK_UART4:
2260 		reg = 58;
2261 		break;
2262 	case SCLK_UART5:
2263 		reg = 60;
2264 		break;
2265 	case SCLK_UART6:
2266 		reg = 62;
2267 		break;
2268 	case SCLK_UART7:
2269 		reg = 64;
2270 		break;
2271 	case SCLK_UART8:
2272 		reg = 66;
2273 		break;
2274 	case SCLK_UART9:
2275 		reg = 68;
2276 		break;
2277 	default:
2278 		return -ENOENT;
2279 	}
2280 	rk_clrsetreg(&cru->clksel_con[reg],
2281 		     CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2282 		     CLK_UART_SRC_DIV_MASK,
2283 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2284 		     (uart_src << CLK_UART_SEL_SHIFT) |
2285 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2286 	if (m && n) {
2287 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2288 		writel(val, &cru->clksel_con[reg + 1]);
2289 	}
2290 
2291 	return rk3568_uart_get_rate(priv, clk_id);
2292 }
2293 
2294 static ulong rk3568_i2s3_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2295 {
2296 	struct rk3568_cru *cru = priv->cru;
2297 	struct rk3568_grf *grf = priv->grf;
2298 	u32 con, div, src, p_rate;
2299 	u32 reg, fracdiv, p_src;
2300 	unsigned long m, n;
2301 
2302 	switch (clk_id) {
2303 	case I2S3_MCLKOUT_TX:
2304 		con = readl(&cru->clksel_con[21]);
2305 		src = (con & I2S3_MCLKOUT_TX_SEL_MASK) >>
2306 		      I2S3_MCLKOUT_TX_SEL_SHIFT;
2307 		if (src == I2S3_MCLKOUT_TX_SEL_12M)
2308 			p_rate = 12000000;
2309 		else
2310 			p_rate = rk3568_i2s3_get_rate(priv, MCLK_I2S3_2CH_TX);
2311 		return p_rate;
2312 	case I2S3_MCLKOUT_RX:
2313 		con = readl(&cru->clksel_con[83]);
2314 		src = (con & I2S3_MCLKOUT_TX_SEL_MASK) >>
2315 		      I2S3_MCLKOUT_TX_SEL_SHIFT;
2316 		if (src == I2S3_MCLKOUT_TX_SEL_12M)
2317 			p_rate = 12000000;
2318 		else
2319 			p_rate = rk3568_i2s3_get_rate(priv, MCLK_I2S3_2CH_RX);
2320 		return p_rate;
2321 	case I2S3_MCLKOUT:
2322 		con = readl(&grf->soc_con2);
2323 		src = (con & I2S3_MCLKOUT_SEL_MASK)
2324 		      >> I2S3_MCLKOUT_SEL_SHIFT;
2325 		if (src == I2S3_MCLKOUT_SEL_RX)
2326 			p_rate = rk3568_i2s3_get_rate(priv, I2S3_MCLKOUT_RX);
2327 		else
2328 			p_rate = rk3568_i2s3_get_rate(priv, I2S3_MCLKOUT_TX);
2329 		return p_rate;
2330 	case MCLK_I2S3_2CH_RX:
2331 		reg = 83;
2332 		break;
2333 	case MCLK_I2S3_2CH_TX:
2334 		reg = 21;
2335 		break;
2336 	default:
2337 		return -ENOENT;
2338 	}
2339 
2340 	con = readl(&cru->clksel_con[reg]);
2341 	src = (con & CLK_I2S3_SEL_MASK) >> CLK_I2S3_SEL_SHIFT;
2342 	div = (con & CLK_I2S3_SRC_DIV_MASK) >> CLK_I2S3_SRC_DIV_SHIFT;
2343 	p_src = (con & CLK_I2S3_SRC_SEL_MASK) >> CLK_I2S3_SRC_SEL_SHIFT;
2344 	if (p_src == CLK_I2S3_SRC_SEL_GPLL)
2345 		p_rate = priv->gpll_hz;
2346 	else if (p_src == CLK_I2S3_SRC_SEL_CPLL)
2347 		p_rate = priv->cpll_hz;
2348 	else
2349 		p_rate = priv->npll_hz;
2350 	if (src == CLK_I2S3_SEL_SRC) {
2351 		return DIV_TO_RATE(p_rate, div);
2352 	} else if (src == CLK_I2S3_SEL_FRAC) {
2353 		fracdiv = readl(&cru->clksel_con[reg + 1]);
2354 		n = fracdiv & CLK_I2S3_FRAC_NUMERATOR_MASK;
2355 		n >>= CLK_I2S3_FRAC_NUMERATOR_SHIFT;
2356 		m = fracdiv & CLK_I2S3_FRAC_DENOMINATOR_MASK;
2357 		m >>= CLK_I2S3_FRAC_DENOMINATOR_SHIFT;
2358 		return DIV_TO_RATE(p_rate, div) * n / m;
2359 	} else {
2360 		return OSC_HZ / 2;
2361 	}
2362 }
2363 
2364 static ulong rk3568_i2s3_set_rate(struct rk3568_clk_priv *priv,
2365 				  ulong clk_id, ulong rate)
2366 {
2367 	struct rk3568_cru *cru = priv->cru;
2368 	struct rk3568_grf *grf = priv->grf;
2369 	u32 reg, con, clk_src, i2s_src, div;
2370 	unsigned long m = 0, n = 0, val;
2371 
2372 	if (priv->gpll_hz % rate == 0) {
2373 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2374 		i2s_src = CLK_I2S3_SEL_SRC;
2375 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2376 	} else if (priv->cpll_hz % rate == 0) {
2377 		clk_src = CLK_I2S3_SRC_SEL_CPLL;
2378 		i2s_src = CLK_I2S3_SEL_SRC;
2379 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2380 	} else if (rate == OSC_HZ / 2) {
2381 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2382 		i2s_src = CLK_I2S3_SEL_XIN12M;
2383 		div = 1;
2384 	} else {
2385 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2386 		i2s_src = CLK_I2S3_SEL_FRAC;
2387 		div = 1;
2388 		rational_best_approximation(rate, priv->gpll_hz / div,
2389 					    GENMASK(16 - 1, 0),
2390 					    GENMASK(16 - 1, 0),
2391 					    &m, &n);
2392 	}
2393 
2394 	switch (clk_id) {
2395 	case I2S3_MCLKOUT_TX:
2396 		if (rate == 12000000) {
2397 			rk_clrsetreg(&cru->clksel_con[21],
2398 				     I2S3_MCLKOUT_TX_SEL_MASK,
2399 				     I2S3_MCLKOUT_TX_SEL_12M <<
2400 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2401 		} else {
2402 			rk3568_i2s3_set_rate(priv, MCLK_I2S3_2CH_TX, rate),
2403 			rk_clrsetreg(&cru->clksel_con[21],
2404 				     I2S3_MCLKOUT_TX_SEL_MASK,
2405 				     I2S3_MCLKOUT_TX_SEL_MCLK <<
2406 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2407 		}
2408 		return rk3568_i2s3_get_rate(priv, clk_id);
2409 	case I2S3_MCLKOUT_RX:
2410 		if (rate == 12000000) {
2411 			rk_clrsetreg(&cru->clksel_con[83],
2412 				     I2S3_MCLKOUT_TX_SEL_MASK,
2413 				     I2S3_MCLKOUT_TX_SEL_12M <<
2414 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2415 		} else {
2416 			rk3568_i2s3_set_rate(priv, MCLK_I2S3_2CH_RX, rate),
2417 			rk_clrsetreg(&cru->clksel_con[21],
2418 				     I2S3_MCLKOUT_TX_SEL_MASK,
2419 				     I2S3_MCLKOUT_TX_SEL_MCLK <<
2420 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2421 		}
2422 		return rk3568_i2s3_get_rate(priv, clk_id);
2423 	case I2S3_MCLKOUT:
2424 		con = readl(&grf->soc_con2);
2425 		clk_src = (con & I2S3_MCLKOUT_SEL_MASK)
2426 		      >> I2S3_MCLKOUT_SEL_SHIFT;
2427 		if (clk_src == I2S3_MCLKOUT_SEL_RX)
2428 			rk3568_i2s3_set_rate(priv, I2S3_MCLKOUT_RX, rate);
2429 		else
2430 			rk3568_i2s3_set_rate(priv, I2S3_MCLKOUT_TX, rate);
2431 		return rk3568_i2s3_get_rate(priv, clk_id);
2432 	case MCLK_I2S3_2CH_RX:
2433 		reg = 83;
2434 		break;
2435 	case MCLK_I2S3_2CH_TX:
2436 		reg = 21;
2437 		break;
2438 	default:
2439 		return -ENOENT;
2440 	}
2441 
2442 	rk_clrsetreg(&cru->clksel_con[reg],
2443 		     CLK_I2S3_SEL_MASK | CLK_I2S3_SRC_SEL_MASK |
2444 		     CLK_I2S3_SRC_DIV_MASK,
2445 		     (clk_src << CLK_I2S3_SRC_SEL_SHIFT) |
2446 		     (i2s_src << CLK_I2S3_SEL_SHIFT) |
2447 		     ((div - 1) << CLK_I2S3_SRC_DIV_SHIFT));
2448 	if (m && n) {
2449 		val = m << CLK_I2S3_FRAC_NUMERATOR_SHIFT | n;
2450 		writel(val, &cru->clksel_con[reg + 1]);
2451 	}
2452 	return rk3568_i2s3_get_rate(priv, clk_id);
2453 }
2454 
2455 #endif
2456 
2457 static ulong rk3568_clk_get_rate(struct clk *clk)
2458 {
2459 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2460 	ulong rate = 0;
2461 
2462 	if (!priv->gpll_hz) {
2463 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2464 		return -ENOENT;
2465 	}
2466 
2467 	switch (clk->id) {
2468 	case PLL_APLL:
2469 	case ARMCLK:
2470 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2471 					     APLL);
2472 		break;
2473 	case PLL_CPLL:
2474 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2475 					     CPLL);
2476 		break;
2477 	case PLL_GPLL:
2478 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2479 					     GPLL);
2480 		break;
2481 	case PLL_NPLL:
2482 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2483 					     NPLL);
2484 		break;
2485 	case PLL_VPLL:
2486 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2487 					     VPLL);
2488 		break;
2489 	case PLL_DPLL:
2490 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2491 					     DPLL);
2492 		break;
2493 	case ACLK_BUS:
2494 	case PCLK_BUS:
2495 	case PCLK_WDT_NS:
2496 		rate = rk3568_bus_get_clk(priv, clk->id);
2497 		break;
2498 	case ACLK_PERIMID:
2499 	case HCLK_PERIMID:
2500 		rate = rk3568_perimid_get_clk(priv, clk->id);
2501 		break;
2502 	case ACLK_TOP_HIGH:
2503 	case ACLK_TOP_LOW:
2504 	case HCLK_TOP:
2505 	case PCLK_TOP:
2506 		rate = rk3568_top_get_clk(priv, clk->id);
2507 		break;
2508 	case CLK_I2C1:
2509 	case CLK_I2C2:
2510 	case CLK_I2C3:
2511 	case CLK_I2C4:
2512 	case CLK_I2C5:
2513 		rate = rk3568_i2c_get_clk(priv, clk->id);
2514 		break;
2515 	case CLK_SPI0:
2516 	case CLK_SPI1:
2517 	case CLK_SPI2:
2518 	case CLK_SPI3:
2519 		rate = rk3568_spi_get_clk(priv, clk->id);
2520 		break;
2521 	case CLK_PWM1:
2522 	case CLK_PWM2:
2523 	case CLK_PWM3:
2524 		rate = rk3568_pwm_get_clk(priv, clk->id);
2525 		break;
2526 	case CLK_SARADC:
2527 	case CLK_TSADC_TSEN:
2528 	case CLK_TSADC:
2529 		rate = rk3568_adc_get_clk(priv, clk->id);
2530 		break;
2531 	case HCLK_SDMMC0:
2532 	case CLK_SDMMC0:
2533 	case CLK_SDMMC1:
2534 	case CLK_SDMMC2:
2535 		rate = rk3568_sdmmc_get_clk(priv, clk->id);
2536 		break;
2537 	case SCLK_SFC:
2538 		rate = rk3568_sfc_get_clk(priv);
2539 		break;
2540 	case NCLK_NANDC:
2541 		rate = rk3568_nand_get_clk(priv);
2542 		break;
2543 	case CCLK_EMMC:
2544 		rate = rk3568_emmc_get_clk(priv);
2545 		break;
2546 #ifndef CONFIG_SPL_BUILD
2547 	case ACLK_VOP:
2548 		rate = rk3568_aclk_vop_get_clk(priv);
2549 		break;
2550 	case DCLK_VOP0:
2551 	case DCLK_VOP1:
2552 	case DCLK_VOP2:
2553 		rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2554 		break;
2555 	case SCLK_GMAC0:
2556 	case CLK_MAC0_2TOP:
2557 	case CLK_MAC0_REFOUT:
2558 		rate = rk3568_gmac_src_get_clk(priv, 0);
2559 		break;
2560 	case CLK_MAC0_OUT:
2561 		rate = rk3568_gmac_out_get_clk(priv, 0);
2562 		break;
2563 	case CLK_GMAC0_PTP_REF:
2564 		rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2565 		break;
2566 	case SCLK_GMAC1:
2567 	case CLK_MAC1_2TOP:
2568 	case CLK_MAC1_REFOUT:
2569 		rate = rk3568_gmac_src_get_clk(priv, 1);
2570 		break;
2571 	case CLK_MAC1_OUT:
2572 		rate = rk3568_gmac_out_get_clk(priv, 1);
2573 		break;
2574 	case CLK_GMAC1_PTP_REF:
2575 		rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2576 		break;
2577 	case DCLK_EBC:
2578 		rate = rk3568_ebc_get_clk(priv);
2579 		break;
2580 	case ACLK_RKVDEC_PRE:
2581 	case ACLK_RKVDEC:
2582 	case CLK_RKVDEC_CORE:
2583 		rate = rk3568_rkvdec_get_clk(priv, clk->id);
2584 		break;
2585 	case TCLK_WDT_NS:
2586 		rate = OSC_HZ;
2587 		break;
2588 	case SCLK_UART1:
2589 	case SCLK_UART2:
2590 	case SCLK_UART3:
2591 	case SCLK_UART4:
2592 	case SCLK_UART5:
2593 	case SCLK_UART6:
2594 	case SCLK_UART7:
2595 	case SCLK_UART8:
2596 	case SCLK_UART9:
2597 		rate = rk3568_uart_get_rate(priv, clk->id);
2598 		break;
2599 	case I2S3_MCLKOUT_RX:
2600 	case I2S3_MCLKOUT_TX:
2601 	case MCLK_I2S3_2CH_RX:
2602 	case MCLK_I2S3_2CH_TX:
2603 	case I2S3_MCLKOUT:
2604 		rate = rk3568_i2s3_get_rate(priv, clk->id);
2605 		break;
2606 #endif
2607 	case ACLK_SECURE_FLASH:
2608 	case ACLK_CRYPTO_NS:
2609 	case HCLK_SECURE_FLASH:
2610 	case HCLK_CRYPTO_NS:
2611 	case CLK_CRYPTO_NS_RNG:
2612 	case CLK_CRYPTO_NS_CORE:
2613 	case CLK_CRYPTO_NS_PKA:
2614 		rate = rk3568_crypto_get_rate(priv, clk->id);
2615 		break;
2616 	case CPLL_500M:
2617 	case CPLL_333M:
2618 	case CPLL_250M:
2619 	case CPLL_125M:
2620 	case CPLL_100M:
2621 	case CPLL_62P5M:
2622 	case CPLL_50M:
2623 	case CPLL_25M:
2624 		rate = rk3568_cpll_div_get_rate(priv, clk->id);
2625 		break;
2626 	default:
2627 		return -ENOENT;
2628 	}
2629 
2630 	return rate;
2631 };
2632 
2633 static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2634 {
2635 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2636 	ulong ret = 0;
2637 
2638 	if (!priv->gpll_hz) {
2639 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2640 		return -ENOENT;
2641 	}
2642 
2643 	switch (clk->id) {
2644 	case PLL_APLL:
2645 	case ARMCLK:
2646 		if (priv->armclk_hz)
2647 			rk3568_armclk_set_clk(priv, rate);
2648 		priv->armclk_hz = rate;
2649 		break;
2650 	case PLL_CPLL:
2651 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2652 					    CPLL, rate);
2653 		priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2654 						      priv->cru, CPLL);
2655 		break;
2656 	case PLL_GPLL:
2657 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2658 					    GPLL, rate);
2659 		priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2660 						      priv->cru, GPLL);
2661 		break;
2662 	case PLL_NPLL:
2663 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2664 					    NPLL, rate);
2665 		break;
2666 	case PLL_VPLL:
2667 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2668 					    VPLL, rate);
2669 		priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2670 						      priv->cru,
2671 						      VPLL);
2672 		break;
2673 	case ACLK_BUS:
2674 	case PCLK_BUS:
2675 	case PCLK_WDT_NS:
2676 		ret = rk3568_bus_set_clk(priv, clk->id, rate);
2677 		break;
2678 	case ACLK_PERIMID:
2679 	case HCLK_PERIMID:
2680 		ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2681 		break;
2682 	case ACLK_TOP_HIGH:
2683 	case ACLK_TOP_LOW:
2684 	case HCLK_TOP:
2685 	case PCLK_TOP:
2686 		ret = rk3568_top_set_clk(priv, clk->id, rate);
2687 		break;
2688 	case CLK_I2C1:
2689 	case CLK_I2C2:
2690 	case CLK_I2C3:
2691 	case CLK_I2C4:
2692 	case CLK_I2C5:
2693 		ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2694 		break;
2695 	case CLK_SPI0:
2696 	case CLK_SPI1:
2697 	case CLK_SPI2:
2698 	case CLK_SPI3:
2699 		ret = rk3568_spi_set_clk(priv, clk->id, rate);
2700 		break;
2701 	case CLK_PWM1:
2702 	case CLK_PWM2:
2703 	case CLK_PWM3:
2704 		ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2705 		break;
2706 	case CLK_SARADC:
2707 	case CLK_TSADC_TSEN:
2708 	case CLK_TSADC:
2709 		ret = rk3568_adc_set_clk(priv, clk->id, rate);
2710 		break;
2711 	case HCLK_SDMMC0:
2712 	case CLK_SDMMC0:
2713 	case CLK_SDMMC1:
2714 	case CLK_SDMMC2:
2715 		ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2716 		break;
2717 	case SCLK_SFC:
2718 		ret = rk3568_sfc_set_clk(priv, rate);
2719 		break;
2720 	case NCLK_NANDC:
2721 		ret = rk3568_nand_set_clk(priv, rate);
2722 		break;
2723 	case CCLK_EMMC:
2724 		ret = rk3568_emmc_set_clk(priv, rate);
2725 		break;
2726 #ifndef CONFIG_SPL_BUILD
2727 	case ACLK_VOP:
2728 		ret = rk3568_aclk_vop_set_clk(priv, rate);
2729 		break;
2730 	case DCLK_VOP0:
2731 	case DCLK_VOP1:
2732 	case DCLK_VOP2:
2733 		ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2734 		break;
2735 	case SCLK_GMAC0:
2736 	case CLK_MAC0_2TOP:
2737 	case CLK_MAC0_REFOUT:
2738 		ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2739 		break;
2740 	case CLK_MAC0_OUT:
2741 		ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2742 		break;
2743 	case SCLK_GMAC0_RX_TX:
2744 		ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2745 		break;
2746 	case CLK_GMAC0_PTP_REF:
2747 		ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2748 		break;
2749 	case SCLK_GMAC1:
2750 	case CLK_MAC1_2TOP:
2751 	case CLK_MAC1_REFOUT:
2752 		ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2753 		break;
2754 	case CLK_MAC1_OUT:
2755 		ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2756 		break;
2757 	case SCLK_GMAC1_RX_TX:
2758 		ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2759 		break;
2760 	case CLK_GMAC1_PTP_REF:
2761 		ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2762 		break;
2763 	case DCLK_EBC:
2764 		ret = rk3568_ebc_set_clk(priv, rate);
2765 		break;
2766 	case ACLK_RKVDEC_PRE:
2767 	case ACLK_RKVDEC:
2768 	case CLK_RKVDEC_CORE:
2769 		ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2770 		break;
2771 	case TCLK_WDT_NS:
2772 		ret = OSC_HZ;
2773 		break;
2774 	case SCLK_UART1:
2775 	case SCLK_UART2:
2776 	case SCLK_UART3:
2777 	case SCLK_UART4:
2778 	case SCLK_UART5:
2779 	case SCLK_UART6:
2780 	case SCLK_UART7:
2781 	case SCLK_UART8:
2782 	case SCLK_UART9:
2783 		ret = rk3568_uart_set_rate(priv, clk->id, rate);
2784 		break;
2785 	case I2S3_MCLKOUT_RX:
2786 	case I2S3_MCLKOUT_TX:
2787 	case MCLK_I2S3_2CH_RX:
2788 	case MCLK_I2S3_2CH_TX:
2789 	case I2S3_MCLKOUT:
2790 		ret = rk3568_i2s3_set_rate(priv, clk->id, rate);
2791 		break;
2792 #endif
2793 	case ACLK_SECURE_FLASH:
2794 	case ACLK_CRYPTO_NS:
2795 	case HCLK_SECURE_FLASH:
2796 	case HCLK_CRYPTO_NS:
2797 	case CLK_CRYPTO_NS_RNG:
2798 	case CLK_CRYPTO_NS_CORE:
2799 	case CLK_CRYPTO_NS_PKA:
2800 		ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2801 		break;
2802 	case CPLL_500M:
2803 	case CPLL_333M:
2804 	case CPLL_250M:
2805 	case CPLL_125M:
2806 	case CPLL_100M:
2807 	case CPLL_62P5M:
2808 	case CPLL_50M:
2809 	case CPLL_25M:
2810 		ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2811 		break;
2812 	default:
2813 		return -ENOENT;
2814 	}
2815 
2816 	return ret;
2817 };
2818 
2819 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
2820 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
2821 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
2822 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
2823 
2824 #define PSECS_PER_SEC 1000000000000LL
2825 /*
2826  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
2827  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
2828  */
2829 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
2830 
2831 int rk3568_mmc_get_phase(struct clk *clk)
2832 {
2833 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2834 	struct rk3568_cru *cru = priv->cru;
2835 	u32 raw_value, delay_num;
2836 	u16 degrees = 0;
2837 	ulong rate;
2838 
2839 	rate = rk3568_clk_get_rate(clk);
2840 	if (rate < 0)
2841 		return rate;
2842 
2843 	if (clk->id == SCLK_EMMC_SAMPLE)
2844 		raw_value = readl(&cru->emmc_con[1]);
2845 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
2846 		raw_value = readl(&cru->sdmmc0_con[1]);
2847 	else if (clk->id == SCLK_SDMMC1_SAMPLE)
2848 		raw_value = readl(&cru->sdmmc1_con[1]);
2849 	else
2850 		raw_value = readl(&cru->sdmmc2_con[1]);
2851 
2852 	raw_value >>= 1;
2853 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
2854 
2855 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
2856 		/* degrees/delaynum * 10000 */
2857 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
2858 					36 * (rate / 1000000);
2859 
2860 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
2861 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
2862 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
2863 	}
2864 
2865 	return degrees % 360;
2866 }
2867 
2868 int rk3568_mmc_set_phase(struct clk *clk, u32 degrees)
2869 {
2870 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2871 	struct rk3568_cru *cru = priv->cru;
2872 	u8 nineties, remainder, delay_num;
2873 	u32 raw_value, delay;
2874 	ulong rate;
2875 
2876 	rate = rk3568_clk_get_rate(clk);
2877 	if (rate < 0)
2878 		return rate;
2879 
2880 	nineties = degrees / 90;
2881 	remainder = (degrees % 90);
2882 
2883 	/*
2884 	 * Convert to delay; do a little extra work to make sure we
2885 	 * don't overflow 32-bit / 64-bit numbers.
2886 	 */
2887 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
2888 	delay *= remainder;
2889 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
2890 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
2891 
2892 	delay_num = (u8)min_t(u32, delay, 255);
2893 
2894 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
2895 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
2896 	raw_value |= nineties;
2897 
2898 	raw_value <<= 1;
2899 	if (clk->id == SCLK_EMMC_SAMPLE)
2900 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
2901 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
2902 		writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]);
2903 	else if (clk->id == SCLK_SDMMC1_SAMPLE)
2904 		writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]);
2905 	else
2906 		writel(raw_value | 0xffff0000, &cru->sdmmc2_con[1]);
2907 
2908 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
2909 	      degrees, delay_num, raw_value, rk3568_mmc_get_phase(clk));
2910 
2911 	return 0;
2912 }
2913 
2914 static int rk3568_clk_get_phase(struct clk *clk)
2915 {
2916 	int ret;
2917 
2918 	debug("%s %ld\n", __func__, clk->id);
2919 	switch (clk->id) {
2920 	case SCLK_EMMC_SAMPLE:
2921 	case SCLK_SDMMC0_SAMPLE:
2922 	case SCLK_SDMMC1_SAMPLE:
2923 	case SCLK_SDMMC2_SAMPLE:
2924 		ret = rk3568_mmc_get_phase(clk);
2925 		break;
2926 	default:
2927 		return -ENOENT;
2928 	}
2929 
2930 	return ret;
2931 }
2932 
2933 static int rk3568_clk_set_phase(struct clk *clk, int degrees)
2934 {
2935 	int ret;
2936 
2937 	debug("%s %ld\n", __func__, clk->id);
2938 	switch (clk->id) {
2939 	case SCLK_EMMC_SAMPLE:
2940 	case SCLK_SDMMC0_SAMPLE:
2941 	case SCLK_SDMMC1_SAMPLE:
2942 	case SCLK_SDMMC2_SAMPLE:
2943 		ret = rk3568_mmc_set_phase(clk, degrees);
2944 		break;
2945 	default:
2946 		return -ENOENT;
2947 	}
2948 
2949 	return ret;
2950 }
2951 
2952 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2953 static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2954 {
2955 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2956 	struct rk3568_cru *cru = priv->cru;
2957 
2958 	if (parent->id == CLK_MAC0_2TOP)
2959 		rk_clrsetreg(&cru->clksel_con[31],
2960 			     RMII0_EXTCLK_SEL_MASK,
2961 			     RMII0_EXTCLK_SEL_MAC0_TOP <<
2962 			     RMII0_EXTCLK_SEL_SHIFT);
2963 	else
2964 		rk_clrsetreg(&cru->clksel_con[31],
2965 			     RMII0_EXTCLK_SEL_MASK,
2966 			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2967 	return 0;
2968 }
2969 
2970 static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2971 {
2972 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2973 	struct rk3568_cru *cru = priv->cru;
2974 
2975 	if (parent->id == CLK_MAC1_2TOP)
2976 		rk_clrsetreg(&cru->clksel_con[33],
2977 			     RMII0_EXTCLK_SEL_MASK,
2978 			     RMII0_EXTCLK_SEL_MAC0_TOP <<
2979 			     RMII0_EXTCLK_SEL_SHIFT);
2980 	else
2981 		rk_clrsetreg(&cru->clksel_con[33],
2982 			     RMII0_EXTCLK_SEL_MASK,
2983 			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2984 	return 0;
2985 }
2986 
2987 static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2988 {
2989 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2990 	struct rk3568_cru *cru = priv->cru;
2991 
2992 	if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2993 		rk_clrsetreg(&cru->clksel_con[31],
2994 			     RMII0_MODE_MASK,
2995 			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2996 	else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2997 		rk_clrsetreg(&cru->clksel_con[31],
2998 			     RMII0_MODE_MASK,
2999 			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
3000 	else
3001 		rk_clrsetreg(&cru->clksel_con[31],
3002 			     RMII0_MODE_MASK,
3003 			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
3004 
3005 	return 0;
3006 }
3007 
3008 static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
3009 {
3010 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3011 	struct rk3568_cru *cru = priv->cru;
3012 
3013 	if (parent->id == SCLK_GMAC1_RGMII_SPEED)
3014 		rk_clrsetreg(&cru->clksel_con[33],
3015 			     RMII0_MODE_MASK,
3016 			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
3017 	else if (parent->id == SCLK_GMAC1_RMII_SPEED)
3018 		rk_clrsetreg(&cru->clksel_con[33],
3019 			     RMII0_MODE_MASK,
3020 			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
3021 	else
3022 		rk_clrsetreg(&cru->clksel_con[33],
3023 			     RMII0_MODE_MASK,
3024 			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
3025 
3026 	return 0;
3027 }
3028 
3029 static int __maybe_unused rk3568_dclk_vop_set_parent(struct clk *clk,
3030 						     struct clk *parent)
3031 {
3032 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3033 	struct rk3568_cru *cru = priv->cru;
3034 	u32 con_id;
3035 
3036 	switch (clk->id) {
3037 	case DCLK_VOP0:
3038 		con_id = 39;
3039 		break;
3040 	case DCLK_VOP1:
3041 		con_id = 40;
3042 		break;
3043 	case DCLK_VOP2:
3044 		con_id = 41;
3045 		break;
3046 	default:
3047 		return -EINVAL;
3048 	}
3049 	if (parent->id == PLL_VPLL) {
3050 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3051 			     DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
3052 	} else {
3053 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3054 			     DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
3055 	}
3056 
3057 	return 0;
3058 }
3059 
3060 static int __maybe_unused rk3568_rkvdec_set_parent(struct clk *clk,
3061 						   struct clk *parent)
3062 {
3063 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3064 	struct rk3568_cru *cru = priv->cru;
3065 	u32 con_id, mask, shift;
3066 
3067 	switch (clk->id) {
3068 	case ACLK_RKVDEC_PRE:
3069 		con_id = 47;
3070 		mask = ACLK_RKVDEC_SEL_MASK;
3071 		shift = ACLK_RKVDEC_SEL_SHIFT;
3072 		break;
3073 	case CLK_RKVDEC_CORE:
3074 		con_id = 49;
3075 		mask = CLK_RKVDEC_CORE_SEL_MASK;
3076 		shift = CLK_RKVDEC_CORE_SEL_SHIFT;
3077 		break;
3078 	default:
3079 		return -EINVAL;
3080 	}
3081 	if (parent->id == PLL_CPLL) {
3082 		rk_clrsetreg(&cru->clksel_con[con_id], mask,
3083 			     ACLK_RKVDEC_SEL_CPLL << shift);
3084 	} else {
3085 		rk_clrsetreg(&cru->clksel_con[con_id], mask,
3086 			     ACLK_RKVDEC_SEL_GPLL << shift);
3087 	}
3088 
3089 	return 0;
3090 }
3091 
3092 static int __maybe_unused rk3568_i2s3_set_parent(struct clk *clk,
3093 						 struct clk *parent)
3094 {
3095 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3096 	struct rk3568_grf *grf = priv->grf;
3097 
3098 	switch (clk->id) {
3099 	case I2S3_MCLK_IOE:
3100 		if (parent->id == I2S3_MCLKOUT) {
3101 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLK_IOE_SEL_MASK,
3102 				     I2S3_MCLK_IOE_SEL_CLKOUT <<
3103 				     I2S3_MCLK_IOE_SEL_SHIFT);
3104 		} else {
3105 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLK_IOE_SEL_MASK,
3106 				     I2S3_MCLK_IOE_SEL_CLKIN <<
3107 				     I2S3_MCLK_IOE_SEL_SHIFT);
3108 		}
3109 		break;
3110 	case I2S3_MCLKOUT:
3111 		if (parent->id == I2S3_MCLKOUT_RX) {
3112 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLKOUT_SEL_MASK,
3113 				     I2S3_MCLKOUT_SEL_RX <<
3114 				     I2S3_MCLKOUT_SEL_SHIFT);
3115 		} else {
3116 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLKOUT_SEL_MASK,
3117 				     I2S3_MCLKOUT_SEL_TX <<
3118 				     I2S3_MCLKOUT_SEL_SHIFT);
3119 		}
3120 		break;
3121 	default:
3122 		return -EINVAL;
3123 	}
3124 
3125 	return 0;
3126 }
3127 
3128 static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
3129 {
3130 	switch (clk->id) {
3131 	case SCLK_GMAC0:
3132 		return rk3568_gmac0_src_set_parent(clk, parent);
3133 	case SCLK_GMAC1:
3134 		return rk3568_gmac1_src_set_parent(clk, parent);
3135 	case SCLK_GMAC0_RX_TX:
3136 		return rk3568_gmac0_tx_rx_set_parent(clk, parent);
3137 	case SCLK_GMAC1_RX_TX:
3138 		return rk3568_gmac1_tx_rx_set_parent(clk, parent);
3139 	case DCLK_VOP0:
3140 	case DCLK_VOP1:
3141 	case DCLK_VOP2:
3142 		return rk3568_dclk_vop_set_parent(clk, parent);
3143 	case ACLK_RKVDEC_PRE:
3144 	case CLK_RKVDEC_CORE:
3145 		return rk3568_rkvdec_set_parent(clk, parent);
3146 	case I2S3_MCLK_IOE:
3147 	case I2S3_MCLKOUT:
3148 		return rk3568_i2s3_set_parent(clk, parent);
3149 	default:
3150 		return -ENOENT;
3151 	}
3152 
3153 	return 0;
3154 }
3155 #endif
3156 
3157 static struct clk_ops rk3568_clk_ops = {
3158 	.get_rate = rk3568_clk_get_rate,
3159 	.set_rate = rk3568_clk_set_rate,
3160 	.get_phase = rk3568_clk_get_phase,
3161 	.set_phase = rk3568_clk_set_phase,
3162 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
3163 	.set_parent = rk3568_clk_set_parent,
3164 #endif
3165 };
3166 
3167 static void rk3568_clk_init(struct rk3568_clk_priv *priv)
3168 {
3169 	int ret;
3170 
3171 	priv->sync_kernel = false;
3172 	if (!priv->armclk_enter_hz) {
3173 		priv->armclk_enter_hz =
3174 			rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
3175 					      priv->cru, APLL);
3176 		priv->armclk_init_hz = priv->armclk_enter_hz;
3177 	}
3178 
3179 	if (priv->armclk_init_hz != APLL_HZ) {
3180 		ret = rk3568_armclk_set_clk(priv, APLL_HZ);
3181 		if (!ret)
3182 			priv->armclk_init_hz = APLL_HZ;
3183 	}
3184 	if (priv->cpll_hz != CPLL_HZ) {
3185 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
3186 					    CPLL, CPLL_HZ);
3187 		if (!ret)
3188 			priv->cpll_hz = CPLL_HZ;
3189 	}
3190 	if (priv->gpll_hz != GPLL_HZ) {
3191 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
3192 					    GPLL, GPLL_HZ);
3193 		if (!ret)
3194 			priv->gpll_hz = GPLL_HZ;
3195 	}
3196 
3197 #ifdef CONFIG_SPL_BUILD
3198 	ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
3199 	if (ret < 0)
3200 		printf("Fail to set the ACLK_BUS clock.\n");
3201 #endif
3202 
3203 	priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
3204 	priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
3205 }
3206 
3207 static int rk3568_clk_probe(struct udevice *dev)
3208 {
3209 	struct rk3568_clk_priv *priv = dev_get_priv(dev);
3210 	int ret;
3211 
3212 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
3213 	if (IS_ERR(priv->grf))
3214 		return PTR_ERR(priv->grf);
3215 
3216 	rk3568_clk_init(priv);
3217 
3218 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
3219 	ret = clk_set_defaults(dev);
3220 	if (ret)
3221 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
3222 	else
3223 		priv->sync_kernel = true;
3224 
3225 	return 0;
3226 }
3227 
3228 static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
3229 {
3230 	struct rk3568_clk_priv *priv = dev_get_priv(dev);
3231 
3232 	priv->cru = dev_read_addr_ptr(dev);
3233 
3234 	return 0;
3235 }
3236 
3237 static int rk3568_clk_bind(struct udevice *dev)
3238 {
3239 	int ret;
3240 	struct udevice *sys_child, *sf_child;
3241 	struct sysreset_reg *priv;
3242 	struct softreset_reg *sf_priv;
3243 
3244 	/* The reset driver does not have a device node, so bind it here */
3245 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
3246 				 &sys_child);
3247 	if (ret) {
3248 		debug("Warning: No sysreset driver: ret=%d\n", ret);
3249 	} else {
3250 		priv = malloc(sizeof(struct sysreset_reg));
3251 		priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
3252 						    glb_srst_fst);
3253 		priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
3254 						    glb_srsr_snd);
3255 		sys_child->priv = priv;
3256 	}
3257 
3258 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
3259 					 dev_ofnode(dev), &sf_child);
3260 	if (ret) {
3261 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
3262 	} else {
3263 		sf_priv = malloc(sizeof(struct softreset_reg));
3264 		sf_priv->sf_reset_offset = offsetof(struct rk3568_cru,
3265 						    softrst_con[0]);
3266 		sf_priv->sf_reset_num = 30;
3267 		sf_child->priv = sf_priv;
3268 	}
3269 
3270 	return 0;
3271 }
3272 
3273 static const struct udevice_id rk3568_clk_ids[] = {
3274 	{ .compatible = "rockchip,rk3568-cru" },
3275 	{ }
3276 };
3277 
3278 U_BOOT_DRIVER(rockchip_rk3568_cru) = {
3279 	.name		= "rockchip_rk3568_cru",
3280 	.id		= UCLASS_CLK,
3281 	.of_match	= rk3568_clk_ids,
3282 	.priv_auto_alloc_size = sizeof(struct rk3568_clk_priv),
3283 	.ofdata_to_platdata = rk3568_clk_ofdata_to_platdata,
3284 	.ops		= &rk3568_clk_ops,
3285 	.bind		= rk3568_clk_bind,
3286 	.probe		= rk3568_clk_probe,
3287 };
3288 
3289 #ifndef CONFIG_SPL_BUILD
3290 /**
3291  * soc_clk_dump() - Print clock frequencies
3292  * Returns zero on success
3293  *
3294  * Implementation for the clk dump command.
3295  */
3296 int soc_clk_dump(void)
3297 {
3298 	struct udevice *cru_dev, *pmucru_dev;
3299 	struct rk3568_clk_priv *priv;
3300 	const struct rk3568_clk_info *clk_dump;
3301 	struct clk clk;
3302 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
3303 	unsigned long rate;
3304 	int i, ret;
3305 
3306 	ret = uclass_get_device_by_driver(UCLASS_CLK,
3307 					  DM_GET_DRIVER(rockchip_rk3568_cru),
3308 					  &cru_dev);
3309 	if (ret) {
3310 		printf("%s failed to get cru device\n", __func__);
3311 		return ret;
3312 	}
3313 
3314 	ret = uclass_get_device_by_driver(UCLASS_CLK,
3315 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
3316 					  &pmucru_dev);
3317 	if (ret) {
3318 		printf("%s failed to get pmucru device\n", __func__);
3319 		return ret;
3320 	}
3321 
3322 	priv = dev_get_priv(cru_dev);
3323 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
3324 	       priv->sync_kernel ? "sync kernel" : "uboot",
3325 	       priv->armclk_enter_hz / 1000,
3326 	       priv->armclk_init_hz / 1000,
3327 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
3328 	       priv->set_armclk_rate ? " KHz" : "N/A");
3329 	for (i = 0; i < clk_count; i++) {
3330 		clk_dump = &clks_dump[i];
3331 		if (clk_dump->name) {
3332 			clk.id = clk_dump->id;
3333 			if (clk_dump->is_cru)
3334 				ret = clk_request(cru_dev, &clk);
3335 			else
3336 				ret = clk_request(pmucru_dev, &clk);
3337 			if (ret < 0)
3338 				return ret;
3339 
3340 			rate = clk_get_rate(&clk);
3341 			clk_free(&clk);
3342 			if (i == 0) {
3343 				if (rate < 0)
3344 					printf("  %s %s\n", clk_dump->name,
3345 					       "unknown");
3346 				else
3347 					printf("  %s %lu KHz\n", clk_dump->name,
3348 					       rate / 1000);
3349 			} else {
3350 				if (rate < 0)
3351 					printf("  %s %s\n", clk_dump->name,
3352 					       "unknown");
3353 				else
3354 					printf("  %s %lu KHz\n", clk_dump->name,
3355 					       rate / 1000);
3356 			}
3357 		}
3358 	}
3359 
3360 	return 0;
3361 }
3362 #endif
3363