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