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