xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3576.c (revision cf0c75989defbf69fa2a81f1a3bb46fca54cb21e)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021 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_rk3576.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rockchip,rk3576-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
23 
24 #if 1
25 static struct rockchip_pll_rate_table rk3576_24m_pll_rates[] = {
26 	/* _mhz, _p, _m, _s, _k */
27 	RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
28 	RK3588_PLL_RATE(1200000000, 1, 100, 1, 0),
29 	RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
30 	RK3588_PLL_RATE(1150000000, 3, 575, 2, 0),
31 	RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
32 	RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
33 	RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
34 	RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
35 	RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
36 	RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
37 	RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
38 	RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
39 	RK3588_PLL_RATE(742500000, 4, 495, 2, 0),
40 	RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
41 	RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
42 	RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
43 	RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
44 	RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
45 	{ /* sentinel */ },
46 };
47 #else
48 static struct rockchip_pll_rate_table rk3576_26m_pll_rates[] = {
49 	/* _mhz, _p, _m, _s, _k */
50 	RK3588_PLL_RATE(1188000000, 2, 183, 1, 50412),
51 	RK3588_PLL_RATE(1100000000, 2, 338, 2, 30247),
52 	RK3588_PLL_RATE(1014000000, 1, 156, 2, 0),
53 	RK3588_PLL_RATE(1000000000, 2, 308, 2, 45371),
54 	RK3588_PLL_RATE(858000000, 1, 132, 2, 0),
55 	RK3588_PLL_RATE(806000000, 1, 124, 2, 0),
56 	RK3588_PLL_RATE(786432000, 2, 242, 2, 64165),
57 	RK3588_PLL_RATE(594000000, 2, 183, 2, 50412),
58 	RK3588_PLL_RATE(297000000, 2, 183, 3, 50412),
59 	RK3588_PLL_RATE(148500000, 2, 183, 4, 50412),
60 	{ /* sentinel */ },
61 };
62 #endif
63 
64 static struct rockchip_pll_clock rk3576_pll_clks[] = {
65 	[BPLL] = PLL(pll_rk3588, PLL_BPLL, RK3576_PLL_CON(0),
66 		      RK3576_BPLL_MODE_CON0, 0, 15, 0,
67 		      rk3576_24m_pll_rates),
68 	[LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3576_LPLL_CON(16),
69 		     RK3576_LPLL_MODE_CON0, 0, 15, 0, rk3576_24m_pll_rates),
70 	[VPLL] = PLL(pll_rk3588, PLL_VPLL, RK3576_PLL_CON(88),
71 		      RK3576_LPLL_MODE_CON0, 4, 15, 0, rk3576_24m_pll_rates),
72 	[AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3576_PLL_CON(96),
73 		      RK3576_MODE_CON0, 6, 15, 0, rk3576_24m_pll_rates),
74 	[CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3576_PLL_CON(104),
75 		     RK3576_MODE_CON0, 8, 15, 0, rk3576_24m_pll_rates),
76 	[GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3576_PLL_CON(112),
77 		     RK3576_MODE_CON0, 2, 15, 0, rk3576_24m_pll_rates),
78 	[PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3576_PMU_PLL_CON(128),
79 		     RK3576_MODE_CON0, 10, 15, 0, rk3576_24m_pll_rates),
80 };
81 
82 #ifndef CONFIG_SPL_BUILD
83 #define RK3576_CLK_DUMP(_id, _name, _iscru)	\
84 {						\
85 	.id = _id,				\
86 	.name = _name,				\
87 	.is_cru = _iscru,			\
88 }
89 
90 static const struct rk3576_clk_info clks_dump[] = {
91 	RK3576_CLK_DUMP(PLL_BPLL, "bpll", true),
92 	RK3576_CLK_DUMP(PLL_LPLL, "lpll", true),
93 	RK3576_CLK_DUMP(PLL_VPLL, "vpll", true),
94 	RK3576_CLK_DUMP(PLL_AUPLL, "aupll", true),
95 	RK3576_CLK_DUMP(PLL_CPLL, "cpll", true),
96 	RK3576_CLK_DUMP(PLL_GPLL, "gpll", true),
97 	RK3576_CLK_DUMP(PLL_PPLL, "ppll", true),
98 	RK3576_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
99 	RK3576_CLK_DUMP(PCLK_BUS_ROOT, "pclk_bus_root", true),
100 	RK3576_CLK_DUMP(HCLK_BUS_ROOT, "hclk_bus_root", true),
101 	RK3576_CLK_DUMP(ACLK_TOP, "aclk_top", true),
102 	RK3576_CLK_DUMP(ACLK_TOP_MID, "aclk_top_mid", true),
103 	RK3576_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top", true),
104 	RK3576_CLK_DUMP(HCLK_TOP, "hclk_top", true),
105 };
106 #endif
107 
108 #ifdef CONFIG_SPL_BUILD
109 #ifndef BITS_WITH_WMASK
110 #define BITS_WITH_WMASK(bits, msk, shift) \
111 	((bits) << (shift)) | ((msk) << ((shift) + 16))
112 #endif
113 #endif
114 
115 #ifndef CONFIG_SPL_BUILD
116 /*
117  *
118  * rational_best_approximation(31415, 10000,
119  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
120  *
121  * you may look at given_numerator as a fixed point number,
122  * with the fractional part size described in given_denominator.
123  *
124  * for theoretical background, see:
125  * http://en.wikipedia.org/wiki/Continued_fraction
126  */
127 static void rational_best_approximation(unsigned long given_numerator,
128 					unsigned long given_denominator,
129 					unsigned long max_numerator,
130 					unsigned long max_denominator,
131 					unsigned long *best_numerator,
132 					unsigned long *best_denominator)
133 {
134 	unsigned long n, d, n0, d0, n1, d1;
135 
136 	n = given_numerator;
137 	d = given_denominator;
138 	n0 = 0;
139 	d1 = 0;
140 	n1 = 1;
141 	d0 = 1;
142 	for (;;) {
143 		unsigned long t, a;
144 
145 		if (n1 > max_numerator || d1 > max_denominator) {
146 			n1 = n0;
147 			d1 = d0;
148 			break;
149 		}
150 		if (d == 0)
151 			break;
152 		t = d;
153 		a = n / d;
154 		d = n % d;
155 		n = t;
156 		t = n0 + a * n1;
157 		n0 = n1;
158 		n1 = t;
159 		t = d0 + a * d1;
160 		d0 = d1;
161 		d1 = t;
162 	}
163 	*best_numerator = n1;
164 	*best_denominator = d1;
165 }
166 #endif
167 
168 static ulong rk3576_bus_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
169 {
170 	struct rk3576_cru *cru = priv->cru;
171 	u32 con, sel, div, rate;
172 
173 	switch (clk_id) {
174 	case ACLK_BUS_ROOT:
175 		con = readl(&cru->clksel_con[55]);
176 		sel = (con & ACLK_BUS_ROOT_SEL_MASK) >>
177 		      ACLK_BUS_ROOT_SEL_SHIFT;
178 		div = (con & ACLK_BUS_ROOT_DIV_MASK) >>
179 		      ACLK_BUS_ROOT_DIV_SHIFT;
180 		if (sel == ACLK_BUS_ROOT_SEL_CPLL)
181 			rate = DIV_TO_RATE(priv->cpll_hz , div);
182 		else
183 			rate = DIV_TO_RATE(priv->gpll_hz, div);
184 		break;
185 	case HCLK_BUS_ROOT:
186 		con = readl(&cru->clksel_con[55]);
187 		sel = (con & HCLK_BUS_ROOT_SEL_MASK) >>
188 		      HCLK_BUS_ROOT_SEL_SHIFT;
189 		if (sel == HCLK_BUS_ROOT_SEL_200M)
190 			rate = 198 * MHz;
191 		else if (sel == HCLK_BUS_ROOT_SEL_100M)
192 			rate = 100 * MHz;
193 		else if (sel == HCLK_BUS_ROOT_SEL_50M)
194 			rate = 50 * MHz;
195 		else
196 			rate = OSC_HZ;
197 		break;
198 	case PCLK_BUS_ROOT:
199 		con = readl(&cru->clksel_con[55]);
200 		sel = (con & PCLK_BUS_ROOT_SEL_MASK) >>
201 		      PCLK_BUS_ROOT_SEL_SHIFT;
202 		if (sel == PCLK_BUS_ROOT_SEL_100M)
203 			rate = 100 * MHz;
204 		else if (sel == PCLK_BUS_ROOT_SEL_50M)
205 			rate = 50 * MHz;
206 		else
207 			rate = OSC_HZ;
208 		break;
209 	default:
210 		return -ENOENT;
211 	}
212 
213 	return rate;
214 }
215 
216 static ulong rk3576_bus_set_clk(struct rk3576_clk_priv *priv,
217 				   ulong clk_id, ulong rate)
218 {
219 	struct rk3576_cru *cru = priv->cru;
220 	int src_clk, src_clk_div;
221 
222 	switch (clk_id) {
223 	case ACLK_BUS_ROOT:
224 		if (!(priv->cpll_hz % rate)) {
225 			src_clk = ACLK_BUS_ROOT_SEL_CPLL;
226 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
227 		} else {
228 			src_clk = ACLK_BUS_ROOT_SEL_GPLL;
229 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
230 		}
231 		rk_clrsetreg(&cru->clksel_con[55],
232 			     ACLK_BUS_ROOT_SEL_MASK,
233 			     src_clk << ACLK_BUS_ROOT_SEL_SHIFT);
234 		assert(src_clk_div - 1 <= 31);
235 		rk_clrsetreg(&cru->clksel_con[55],
236 			     ACLK_BUS_ROOT_DIV_MASK |
237 			     ACLK_BUS_ROOT_SEL_MASK,
238 			     (src_clk <<
239 			      ACLK_BUS_ROOT_SEL_SHIFT) |
240 			     (src_clk_div - 1) << ACLK_BUS_ROOT_DIV_SHIFT);
241 		break;
242 	case HCLK_BUS_ROOT:
243 		if (rate >= 198 * MHz)
244 			src_clk = HCLK_BUS_ROOT_SEL_200M;
245 		else if (rate >= 99 * MHz)
246 			src_clk = HCLK_BUS_ROOT_SEL_100M;
247 		else if (rate >= 50 * MHz)
248 			src_clk = HCLK_BUS_ROOT_SEL_50M;
249 		else
250 			src_clk = HCLK_BUS_ROOT_SEL_OSC;
251 		rk_clrsetreg(&cru->clksel_con[55],
252 			     HCLK_BUS_ROOT_SEL_MASK,
253 			     src_clk << HCLK_BUS_ROOT_SEL_SHIFT);
254 		break;
255 	case PCLK_BUS_ROOT:
256 		if (rate >= 99 * MHz)
257 			src_clk = PCLK_BUS_ROOT_SEL_100M;
258 		else if (rate >= 50 * MHz)
259 			src_clk = PCLK_BUS_ROOT_SEL_50M;
260 		else
261 			src_clk = PCLK_BUS_ROOT_SEL_OSC;
262 		rk_clrsetreg(&cru->clksel_con[55],
263 			     PCLK_BUS_ROOT_SEL_MASK,
264 			     src_clk << PCLK_BUS_ROOT_SEL_SHIFT);
265 		break;
266 	default:
267 		printf("do not support this center freq\n");
268 		return -EINVAL;
269 	}
270 
271 	return rk3576_bus_get_clk(priv, clk_id);
272 }
273 
274 static ulong rk3576_top_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
275 {
276 	struct rk3576_cru *cru = priv->cru;
277 	u32 con, sel, div, rate, prate;
278 
279 	switch (clk_id) {
280 	case ACLK_TOP:
281 		con = readl(&cru->clksel_con[9]);
282 		div = (con & ACLK_TOP_DIV_MASK) >>
283 		      ACLK_TOP_DIV_SHIFT;
284 		sel = (con & ACLK_TOP_SEL_MASK) >>
285 		      ACLK_TOP_SEL_SHIFT;
286 		if (sel == ACLK_TOP_SEL_CPLL)
287 			prate = priv->cpll_hz;
288 		else if (sel == ACLK_TOP_SEL_AUPLL)
289 			prate = priv->aupll_hz;
290 		else
291 			prate = priv->gpll_hz;
292 		return DIV_TO_RATE(prate, div);
293 	case ACLK_TOP_MID:
294 		con = readl(&cru->clksel_con[10]);
295 		div = (con & ACLK_TOP_MID_DIV_MASK) >>
296 		      ACLK_TOP_MID_DIV_SHIFT;
297 		sel = (con & ACLK_TOP_MID_SEL_MASK) >>
298 		      ACLK_TOP_MID_SEL_SHIFT;
299 		if (sel == ACLK_TOP_MID_SEL_CPLL)
300 			prate = priv->cpll_hz;
301 		else
302 			prate = priv->gpll_hz;
303 		return DIV_TO_RATE(prate, div);
304 	case PCLK_TOP_ROOT:
305 		con = readl(&cru->clksel_con[8]);
306 		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
307 		if (sel == PCLK_TOP_SEL_100M)
308 			rate = 100 * MHz;
309 		else if (sel == PCLK_TOP_SEL_50M)
310 			rate = 50 * MHz;
311 		else
312 			rate = OSC_HZ;
313 		break;
314 	case HCLK_TOP:
315 		con = readl(&cru->clksel_con[19]);
316 		sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
317 		if (sel == HCLK_TOP_SEL_200M)
318 			rate = 200 * MHz;
319 		else if (sel == HCLK_TOP_SEL_100M)
320 			rate = 100 * MHz;
321 		else if (sel == HCLK_TOP_SEL_50M)
322 			rate = 50 * MHz;
323 		else
324 			rate = OSC_HZ;
325 		break;
326 	default:
327 		return -ENOENT;
328 	}
329 
330 	return rate;
331 }
332 
333 static ulong rk3576_top_set_clk(struct rk3576_clk_priv *priv,
334 				ulong clk_id, ulong rate)
335 {
336 	struct rk3576_cru *cru = priv->cru;
337 	int src_clk, src_clk_div;
338 
339 	switch (clk_id) {
340 	case ACLK_TOP:
341 		if (!(priv->cpll_hz % rate)) {
342 			src_clk = ACLK_TOP_SEL_CPLL;
343 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
344 		} else {
345 			src_clk = ACLK_TOP_SEL_GPLL;
346 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
347 		}
348 		assert(src_clk_div - 1 <= 31);
349 		rk_clrsetreg(&cru->clksel_con[9],
350 			     ACLK_TOP_DIV_MASK |
351 			     ACLK_TOP_SEL_MASK,
352 			     (src_clk <<
353 			      ACLK_TOP_SEL_SHIFT) |
354 			     (src_clk_div - 1) << ACLK_TOP_SEL_SHIFT);
355 		break;
356 	case ACLK_TOP_MID:
357 		if (!(priv->cpll_hz % rate)) {
358 			src_clk = ACLK_TOP_MID_SEL_CPLL;
359 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
360 		} else {
361 			src_clk = ACLK_TOP_MID_SEL_GPLL;
362 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
363 		}
364 		rk_clrsetreg(&cru->clksel_con[10],
365 			     ACLK_TOP_MID_DIV_MASK |
366 			     ACLK_TOP_MID_SEL_MASK,
367 			     (ACLK_TOP_MID_SEL_GPLL <<
368 			      ACLK_TOP_MID_SEL_SHIFT) |
369 			     (src_clk_div - 1) << ACLK_TOP_MID_DIV_SHIFT);
370 		break;
371 	case PCLK_TOP_ROOT:
372 		if (rate >= 99 * MHz)
373 			src_clk = PCLK_TOP_SEL_100M;
374 		else if (rate >= 50 * MHz)
375 			src_clk = PCLK_TOP_SEL_50M;
376 		else
377 			src_clk = PCLK_TOP_SEL_OSC;
378 		rk_clrsetreg(&cru->clksel_con[8],
379 			     PCLK_TOP_SEL_MASK,
380 			     src_clk << PCLK_TOP_SEL_SHIFT);
381 		break;
382 	case HCLK_TOP:
383 		if (rate >= 198 * MHz)
384 			src_clk = HCLK_TOP_SEL_200M;
385 		else if (rate >= 99 * MHz)
386 			src_clk = HCLK_TOP_SEL_100M;
387 		else if (rate >= 50 * MHz)
388 			src_clk = HCLK_TOP_SEL_50M;
389 		else
390 			src_clk = HCLK_TOP_SEL_OSC;
391 		rk_clrsetreg(&cru->clksel_con[19],
392 			     HCLK_TOP_SEL_MASK,
393 			     src_clk << HCLK_TOP_SEL_SHIFT);
394 		break;
395 	default:
396 		printf("do not support this top freq\n");
397 		return -EINVAL;
398 	}
399 
400 	return rk3576_top_get_clk(priv, clk_id);
401 }
402 
403 static ulong rk3576_i2c_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
404 {
405 	struct rk3576_cru *cru = priv->cru;
406 	u32 sel, con;
407 	ulong rate;
408 
409 	switch (clk_id) {
410 	case CLK_I2C0:
411 		con = readl(&cru->pmuclksel_con[6]);
412 		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
413 		break;
414 	case CLK_I2C1:
415 		con = readl(&cru->clksel_con[57]);
416 		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
417 		break;
418 	case CLK_I2C2:
419 		con = readl(&cru->clksel_con[57]);
420 		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
421 		break;
422 	case CLK_I2C3:
423 		con = readl(&cru->clksel_con[57]);
424 		sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
425 		break;
426 	case CLK_I2C4:
427 		con = readl(&cru->clksel_con[57]);
428 		sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
429 		break;
430 	case CLK_I2C5:
431 		con = readl(&cru->clksel_con[57]);
432 		sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
433 		break;
434 	case CLK_I2C6:
435 		con = readl(&cru->clksel_con[57]);
436 		sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
437 		break;
438 	case CLK_I2C7:
439 		con = readl(&cru->clksel_con[57]);
440 		sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
441 		break;
442 	case CLK_I2C8:
443 		con = readl(&cru->clksel_con[57]);
444 		sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
445 		break;
446 	case CLK_I2C9:
447 		con = readl(&cru->clksel_con[58]);
448 		sel = (con & CLK_I2C9_SEL_MASK) >> CLK_I2C9_SEL_SHIFT;
449 		break;
450 
451 	default:
452 		return -ENOENT;
453 	}
454 	if (sel == CLK_I2C_SEL_200M)
455 		rate = 200 * MHz;
456 	else if (sel == CLK_I2C_SEL_100M)
457 		rate = 100 * MHz;
458 	else if (sel == CLK_I2C_SEL_50M)
459 		rate = 50 * MHz;
460 	else
461 		rate = OSC_HZ;
462 
463 	return rate;
464 }
465 
466 static ulong rk3576_i2c_set_clk(struct rk3576_clk_priv *priv, ulong clk_id,
467 				ulong rate)
468 {
469 	struct rk3576_cru *cru = priv->cru;
470 	int src_clk;
471 
472 	if (rate >= 198 * MHz)
473 		src_clk = CLK_I2C_SEL_200M;
474 	else if (rate >= 99 * MHz)
475 		src_clk = CLK_I2C_SEL_100M;
476 	if (rate >= 50 * MHz)
477 		src_clk = CLK_I2C_SEL_50M;
478 	else
479 		src_clk = CLK_I2C_SEL_OSC;
480 
481 	switch (clk_id) {
482 	case CLK_I2C0:
483 		rk_clrsetreg(&cru->pmuclksel_con[6], CLK_I2C0_SEL_MASK,
484 			     src_clk << CLK_I2C0_SEL_SHIFT);
485 		break;
486 	case CLK_I2C1:
487 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C1_SEL_MASK,
488 			     src_clk << CLK_I2C1_SEL_SHIFT);
489 		break;
490 	case CLK_I2C2:
491 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C2_SEL_MASK,
492 			     src_clk << CLK_I2C2_SEL_SHIFT);
493 		break;
494 	case CLK_I2C3:
495 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C3_SEL_MASK,
496 			     src_clk << CLK_I2C3_SEL_SHIFT);
497 		break;
498 	case CLK_I2C4:
499 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C4_SEL_MASK,
500 			     src_clk << CLK_I2C4_SEL_SHIFT);
501 		break;
502 	case CLK_I2C5:
503 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C5_SEL_MASK,
504 			     src_clk << CLK_I2C5_SEL_SHIFT);
505 		break;
506 	case CLK_I2C6:
507 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C6_SEL_MASK,
508 			     src_clk << CLK_I2C6_SEL_SHIFT);
509 		break;
510 	case CLK_I2C7:
511 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C7_SEL_MASK,
512 			     src_clk << CLK_I2C7_SEL_SHIFT);
513 		break;
514 	case CLK_I2C8:
515 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C8_SEL_MASK,
516 			     src_clk << CLK_I2C8_SEL_SHIFT);
517 	case CLK_I2C9:
518 		rk_clrsetreg(&cru->clksel_con[58], CLK_I2C9_SEL_MASK,
519 			     src_clk << CLK_I2C9_SEL_SHIFT);
520 		break;
521 	default:
522 		return -ENOENT;
523 	}
524 
525 	return rk3576_i2c_get_clk(priv, clk_id);
526 }
527 
528 static ulong rk3576_spi_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
529 {
530 	struct rk3576_cru *cru = priv->cru;
531 	u32 sel, con;
532 
533 	switch (clk_id) {
534 	case CLK_SPI0:
535 		con = readl(&cru->clksel_con[70]);
536 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
537 		break;
538 	case CLK_SPI1:
539 		con = readl(&cru->clksel_con[71]);
540 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
541 		break;
542 	case CLK_SPI2:
543 		con = readl(&cru->clksel_con[71]);
544 		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
545 		break;
546 	case CLK_SPI3:
547 		con = readl(&cru->clksel_con[71]);
548 		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
549 		break;
550 	case CLK_SPI4:
551 		con = readl(&cru->clksel_con[71]);
552 		sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
553 		break;
554 	default:
555 		return -ENOENT;
556 	}
557 
558 	switch (sel) {
559 	case CLK_SPI_SEL_200M:
560 		return 200 * MHz;
561 	case CLK_SPI_SEL_100M:
562 		return 100 * MHz;
563 	case CLK_SPI_SEL_50M:
564 		return 50 * MHz;
565 	case CLK_SPI_SEL_OSC:
566 		return OSC_HZ;
567 	default:
568 		return -ENOENT;
569 	}
570 }
571 
572 static ulong rk3576_spi_set_clk(struct rk3576_clk_priv *priv,
573 				ulong clk_id, ulong rate)
574 {
575 	struct rk3576_cru *cru = priv->cru;
576 	int src_clk;
577 
578 	if (rate >= 198 * MHz)
579 		src_clk = CLK_SPI_SEL_200M;
580 	else if (rate >= 99 * MHz)
581 		src_clk = CLK_SPI_SEL_100M;
582 	else if (rate >= 50 * MHz)
583 		src_clk = CLK_SPI_SEL_50M;
584 	else
585 		src_clk = CLK_SPI_SEL_OSC;
586 
587 	switch (clk_id) {
588 	case CLK_SPI0:
589 		rk_clrsetreg(&cru->clksel_con[70],
590 			     CLK_SPI0_SEL_MASK,
591 			     src_clk << CLK_SPI0_SEL_SHIFT);
592 		break;
593 	case CLK_SPI1:
594 		rk_clrsetreg(&cru->clksel_con[71],
595 			     CLK_SPI1_SEL_MASK,
596 			     src_clk << CLK_SPI1_SEL_SHIFT);
597 		break;
598 	case CLK_SPI2:
599 		rk_clrsetreg(&cru->clksel_con[71],
600 			     CLK_SPI2_SEL_MASK,
601 			     src_clk << CLK_SPI2_SEL_SHIFT);
602 		break;
603 	case CLK_SPI3:
604 		rk_clrsetreg(&cru->clksel_con[71],
605 			     CLK_SPI3_SEL_MASK,
606 			     src_clk << CLK_SPI3_SEL_SHIFT);
607 		break;
608 	case CLK_SPI4:
609 		rk_clrsetreg(&cru->clksel_con[71],
610 			     CLK_SPI4_SEL_MASK,
611 			     src_clk << CLK_SPI4_SEL_SHIFT);
612 		break;
613 	default:
614 		return -ENOENT;
615 	}
616 
617 	return rk3576_spi_get_clk(priv, clk_id);
618 }
619 
620 static ulong rk3576_pwm_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
621 {
622 	struct rk3576_cru *cru = priv->cru;
623 	u32 sel, con;
624 
625 	switch (clk_id) {
626 	case CLK_PWM1:
627 		con = readl(&cru->clksel_con[71]);
628 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
629 		break;
630 	case CLK_PWM2:
631 		con = readl(&cru->clksel_con[74]);
632 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
633 		break;
634 	case CLK_PMU1PWM:
635 		con = readl(&cru->pmuclksel_con[5]);
636 		sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
637 		break;
638 	default:
639 		return -ENOENT;
640 	}
641 
642 	switch (sel) {
643 	case CLK_PWM_SEL_100M:
644 		return 100 * MHz;
645 	case CLK_PWM_SEL_50M:
646 		return 50 * MHz;
647 	case CLK_PWM_SEL_OSC:
648 		return OSC_HZ;
649 	default:
650 		return -ENOENT;
651 	}
652 }
653 
654 static ulong rk3576_pwm_set_clk(struct rk3576_clk_priv *priv,
655 				ulong clk_id, ulong rate)
656 {
657 	struct rk3576_cru *cru = priv->cru;
658 	int src_clk;
659 
660 	if (rate >= 99 * MHz)
661 		src_clk = CLK_PWM_SEL_100M;
662 	else if (rate >= 50 * MHz)
663 		src_clk = CLK_PWM_SEL_50M;
664 	else
665 		src_clk = CLK_PWM_SEL_OSC;
666 
667 	switch (clk_id) {
668 	case CLK_PWM1:
669 		rk_clrsetreg(&cru->clksel_con[71],
670 			     CLK_PWM1_SEL_MASK,
671 			     src_clk << CLK_PWM1_SEL_SHIFT);
672 		break;
673 	case CLK_PWM2:
674 		rk_clrsetreg(&cru->clksel_con[74],
675 			     CLK_PWM2_SEL_MASK,
676 			     src_clk << CLK_PWM2_SEL_SHIFT);
677 		break;
678 	case CLK_PMU1PWM:
679 		rk_clrsetreg(&cru->pmuclksel_con[5],
680 			     CLK_PMU1PWM_SEL_MASK,
681 			     src_clk << CLK_PMU1PWM_SEL_SHIFT);
682 		break;
683 	default:
684 		return -ENOENT;
685 	}
686 
687 	return rk3576_pwm_get_clk(priv, clk_id);
688 }
689 
690 static ulong rk3576_adc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
691 {
692 	struct rk3576_cru *cru = priv->cru;
693 	u32 div, sel, con, prate;
694 
695 	switch (clk_id) {
696 	case CLK_SARADC:
697 		con = readl(&cru->clksel_con[58]);
698 		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
699 		sel = (con & CLK_SARADC_SEL_MASK) >>
700 		      CLK_SARADC_SEL_SHIFT;
701 		if (sel == CLK_SARADC_SEL_OSC)
702 			prate = OSC_HZ;
703 		else
704 			prate = priv->gpll_hz;
705 		return DIV_TO_RATE(prate, div);
706 	case CLK_TSADC:
707 		con = readl(&cru->clksel_con[59]);
708 		div = (con & CLK_TSADC_DIV_MASK) >>
709 		      CLK_TSADC_DIV_SHIFT;
710 		prate = OSC_HZ;
711 		return DIV_TO_RATE(prate, div);
712 	default:
713 		return -ENOENT;
714 	}
715 }
716 
717 static ulong rk3576_adc_set_clk(struct rk3576_clk_priv *priv,
718 				ulong clk_id, ulong rate)
719 {
720 	struct rk3576_cru *cru = priv->cru;
721 	int src_clk_div;
722 
723 	switch (clk_id) {
724 	case CLK_SARADC:
725 		if (!(OSC_HZ % rate)) {
726 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
727 			assert(src_clk_div - 1 <= 255);
728 			rk_clrsetreg(&cru->clksel_con[58],
729 				     CLK_SARADC_SEL_MASK |
730 				     CLK_SARADC_DIV_MASK,
731 				     (CLK_SARADC_SEL_OSC <<
732 				      CLK_SARADC_SEL_SHIFT) |
733 				     (src_clk_div - 1) <<
734 				     CLK_SARADC_DIV_SHIFT);
735 		} else {
736 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
737 			assert(src_clk_div - 1 <= 255);
738 			rk_clrsetreg(&cru->clksel_con[59],
739 				     CLK_SARADC_SEL_MASK |
740 				     CLK_SARADC_DIV_MASK,
741 				     (CLK_SARADC_SEL_GPLL <<
742 				      CLK_SARADC_SEL_SHIFT) |
743 				     (src_clk_div - 1) <<
744 				     CLK_SARADC_DIV_SHIFT);
745 		}
746 		break;
747 	case CLK_TSADC:
748 		src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
749 		assert(src_clk_div - 1 <= 255);
750 		rk_clrsetreg(&cru->clksel_con[58],
751 			     CLK_TSADC_DIV_MASK,
752 			     (src_clk_div - 1) <<
753 			     CLK_TSADC_DIV_SHIFT);
754 		break;
755 	default:
756 		return -ENOENT;
757 	}
758 	return rk3576_adc_get_clk(priv, clk_id);
759 }
760 
761 static ulong rk3576_mmc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
762 {
763 	struct rk3576_cru *cru = priv->cru;
764 	u32 sel, con, prate, div = 0;
765 
766 	switch (clk_id) {
767 	case CCLK_SRC_SDIO:
768 		con = readl(&cru->clksel_con[104]);
769 		div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
770 		sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
771 		      CCLK_SDIO_SRC_SEL_SHIFT;
772 		if (sel == CCLK_SDIO_SRC_SEL_GPLL)
773 			prate = priv->gpll_hz;
774 		else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
775 			prate = priv->cpll_hz;
776 		else
777 			prate = OSC_HZ;
778 		return DIV_TO_RATE(prate, div);
779 	case CCLK_SRC_SDMMC0:
780 		con = readl(&cru->clksel_con[105]);
781 		div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT;
782 		sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >>
783 		      CCLK_SDMMC0_SRC_SEL_SHIFT;
784 		if (sel == CCLK_SDMMC0_SRC_SEL_GPLL)
785 			prate = priv->gpll_hz;
786 		else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL)
787 			prate = priv->cpll_hz;
788 		else
789 			prate = OSC_HZ;
790 		return DIV_TO_RATE(prate, div);
791 	case CCLK_SRC_EMMC:
792 		con = readl(&cru->clksel_con[89]);
793 		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
794 		sel = (con & CCLK_EMMC_SEL_MASK) >>
795 		      CCLK_EMMC_SEL_SHIFT;
796 		if (sel == CCLK_EMMC_SEL_GPLL)
797 			prate = priv->gpll_hz;
798 		else if (sel == CCLK_EMMC_SEL_CPLL)
799 			prate = priv->cpll_hz;
800 		else
801 			prate = OSC_HZ;
802 		return DIV_TO_RATE(prate, div);
803 	case BCLK_EMMC:
804 		con = readl(&cru->clksel_con[90]);
805 		sel = (con & BCLK_EMMC_SEL_MASK) >>
806 		      BCLK_EMMC_SEL_SHIFT;
807 		if (sel == BCLK_EMMC_SEL_200M)
808 			prate = 200 * MHz;
809 		else if (sel == BCLK_EMMC_SEL_100M)
810 			prate = 100 * MHz;
811 		else if (sel == BCLK_EMMC_SEL_50M)
812 			prate = 50 * MHz;
813 		else
814 			prate = OSC_HZ;
815 		return DIV_TO_RATE(prate, div);
816 	case SCLK_FSPI_X2:
817 		con = readl(&cru->clksel_con[89]);
818 		div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
819 		sel = (con & SCLK_FSPI_SEL_MASK) >>
820 		      SCLK_FSPI_SEL_SHIFT;
821 		if (sel == SCLK_FSPI_SEL_GPLL)
822 			prate = priv->gpll_hz;
823 		else if (sel == SCLK_FSPI_SEL_CPLL)
824 			prate = priv->cpll_hz;
825 		else
826 			prate = OSC_HZ;
827 		return DIV_TO_RATE(prate, div);
828 	case SCLK_FSPI1_X2:
829 		con = readl(&cru->clksel_con[106]);
830 		div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
831 		sel = (con & SCLK_FSPI_SEL_MASK) >>
832 		      SCLK_FSPI_SEL_SHIFT;
833 		if (sel == SCLK_FSPI_SEL_GPLL)
834 			prate = priv->gpll_hz;
835 		else if (sel == SCLK_FSPI_SEL_CPLL)
836 			prate = priv->cpll_hz;
837 		else
838 			prate = OSC_HZ;
839 		return DIV_TO_RATE(prate, div);
840 	default:
841 		return -ENOENT;
842 	}
843 }
844 
845 static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv,
846 				ulong clk_id, ulong rate)
847 {
848 	struct rk3576_cru *cru = priv->cru;
849 	int src_clk, div = 0;
850 
851 	switch (clk_id) {
852 	case CCLK_SRC_SDIO:
853 	case CCLK_SRC_SDMMC0:
854 	case CCLK_SRC_EMMC:
855 	case SCLK_FSPI_X2:
856 	case SCLK_FSPI1_X2:
857 		if (!(OSC_HZ % rate)) {
858 			src_clk = SCLK_FSPI_SEL_OSC;
859 			div = DIV_ROUND_UP(OSC_HZ, rate);
860 		} else if (!(priv->cpll_hz % rate)) {
861 			src_clk = SCLK_FSPI_SEL_CPLL;
862 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
863 		} else {
864 			src_clk = SCLK_FSPI_SEL_GPLL;
865 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
866 		}
867 		break;
868 	case BCLK_EMMC:
869 		if (rate >= 198 * MHz)
870 			src_clk = BCLK_EMMC_SEL_200M;
871 		else if (rate >= 99 * MHz)
872 			src_clk = BCLK_EMMC_SEL_100M;
873 		else if (rate >= 50 * MHz)
874 			src_clk = BCLK_EMMC_SEL_50M;
875 		else
876 			src_clk = BCLK_EMMC_SEL_OSC;
877 		break;
878 	default:
879 		return -ENOENT;
880 	}
881 
882 	switch (clk_id) {
883 	case CCLK_SRC_SDIO:
884 		rk_clrsetreg(&cru->clksel_con[104],
885 			     CCLK_SDIO_SRC_SEL_MASK |
886 			     CCLK_SDIO_SRC_DIV_MASK,
887 			     (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
888 			     (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
889 		break;
890 	case CCLK_SRC_SDMMC0:
891 		rk_clrsetreg(&cru->clksel_con[105],
892 			     CCLK_EMMC_SEL_MASK |
893 			     CCLK_EMMC_DIV_MASK,
894 			     (src_clk << CCLK_EMMC_SEL_SHIFT) |
895 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
896 		break;
897 	case CCLK_SRC_EMMC:
898 		rk_clrsetreg(&cru->clksel_con[89],
899 			     CCLK_EMMC_DIV_MASK |
900 			     CCLK_EMMC_SEL_MASK,
901 			     (src_clk << CCLK_EMMC_SEL_SHIFT) |
902 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
903 		break;
904 	case SCLK_FSPI_X2:
905 		rk_clrsetreg(&cru->clksel_con[89],
906 			     SCLK_FSPI_DIV_MASK |
907 			     SCLK_FSPI_SEL_MASK,
908 			     (src_clk << SCLK_FSPI_SEL_SHIFT) |
909 			     (div - 1) << SCLK_FSPI_DIV_SHIFT);
910 		break;
911 	case SCLK_FSPI1_X2:
912 		rk_clrsetreg(&cru->clksel_con[106],
913 			     SCLK_FSPI_DIV_MASK |
914 			     SCLK_FSPI_SEL_MASK,
915 			     (src_clk << SCLK_FSPI_SEL_SHIFT) |
916 			     (div - 1) << SCLK_FSPI_DIV_SHIFT);
917 		break;
918 	case BCLK_EMMC:
919 		rk_clrsetreg(&cru->clksel_con[90],
920 			     BCLK_EMMC_SEL_MASK,
921 			     src_clk << BCLK_EMMC_SEL_SHIFT);
922 		break;
923 	default:
924 		return -ENOENT;
925 	}
926 
927 	return rk3576_mmc_get_clk(priv, clk_id);
928 }
929 
930 #ifndef CONFIG_SPL_BUILD
931 
932 static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
933 {
934 	struct rk3576_cru *cru = priv->cru;
935 	u32 div, sel, con, parent = 0;
936 
937 	switch (clk_id) {
938 	case ACLK_VOP_ROOT:
939 	case ACLK_VOP:
940 		con = readl(&cru->clksel_con[144]);
941 		div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
942 		sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
943 		if (sel == ACLK_VOP_ROOT_SEL_GPLL)
944 			parent = priv->gpll_hz;
945 		else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
946 			parent = priv->cpll_hz;
947 		else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
948 			parent = priv->aupll_hz;
949 		else if (sel == ACLK_VOP_ROOT_SEL_SPLL)
950 			parent = priv->spll_hz;
951 		else if (sel == ACLK_VOP_ROOT_SEL_LPLL)
952 			parent = priv->lpll_hz / 2;
953 		return DIV_TO_RATE(parent, div);
954 	case ACLK_VO0_ROOT:
955 		con = readl(&cru->clksel_con[149]);
956 		div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
957 		sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
958 		if (sel == ACLK_VO0_ROOT_SEL_GPLL)
959 			parent = priv->gpll_hz;
960 		else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
961 			parent = priv->cpll_hz;
962 		else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
963 			parent = priv->lpll_hz / 2;
964 		else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
965 			parent = priv->bpll_hz / 4;
966 		return DIV_TO_RATE(parent, div);
967 	case ACLK_VO1_ROOT:
968 		con = readl(&cru->clksel_con[158]);
969 		div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
970 		sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
971 		if (sel == ACLK_VO0_ROOT_SEL_GPLL)
972 			parent = priv->gpll_hz;
973 		else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
974 			parent = priv->cpll_hz;
975 		else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
976 			parent = priv->lpll_hz / 2;
977 		else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
978 			parent = priv->bpll_hz / 4;
979 		return DIV_TO_RATE(parent, div);
980 	case HCLK_VOP_ROOT:
981 		con = readl(&cru->clksel_con[144]);
982 		sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
983 		if (sel == HCLK_VOP_ROOT_SEL_200M)
984 			return 200 * MHz;
985 		else if (sel == HCLK_VOP_ROOT_SEL_100M)
986 			return 100 * MHz;
987 		else if (sel == HCLK_VOP_ROOT_SEL_50M)
988 			return 50 * MHz;
989 		else
990 			return OSC_HZ;
991 	case PCLK_VOP_ROOT:
992 		con = readl(&cru->clksel_con[144]);
993 		sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT;
994 		if (sel == PCLK_VOP_ROOT_SEL_100M)
995 			return 100 * MHz;
996 		else if (sel == PCLK_VOP_ROOT_SEL_50M)
997 			return 50 * MHz;
998 		else
999 			return OSC_HZ;
1000 
1001 	default:
1002 		return -ENOENT;
1003 	}
1004 }
1005 
1006 static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv,
1007 				     ulong clk_id, ulong rate)
1008 {
1009 	struct rk3576_cru *cru = priv->cru;
1010 	int src_clk, div;
1011 
1012 	switch (clk_id) {
1013 	case ACLK_VOP_ROOT:
1014 	case ACLK_VOP:
1015 		if (rate == 700 * MHz) {
1016 			src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1017 			div = 1;
1018 		} else if (!(priv->cpll_hz % rate)) {
1019 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1020 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1021 		} else {
1022 			src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1023 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1024 		}
1025 		rk_clrsetreg(&cru->clksel_con[144],
1026 			     ACLK_VOP_ROOT_DIV_MASK |
1027 			     ACLK_VOP_ROOT_SEL_MASK,
1028 			     (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1029 			     (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1030 		break;
1031 	case ACLK_VO0_ROOT:
1032 		if (!(priv->cpll_hz % rate)) {
1033 			src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1034 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1035 		} else {
1036 			src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1037 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1038 		}
1039 		rk_clrsetreg(&cru->clksel_con[149],
1040 			     ACLK_VO0_ROOT_DIV_MASK |
1041 			     ACLK_VO0_ROOT_SEL_MASK,
1042 			     (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1043 			     (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1044 		break;
1045 	case ACLK_VO1_ROOT:
1046 		if (!(priv->cpll_hz % rate)) {
1047 			src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1048 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1049 		} else {
1050 			src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1051 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1052 		}
1053 		rk_clrsetreg(&cru->clksel_con[158],
1054 			     ACLK_VO0_ROOT_DIV_MASK |
1055 			     ACLK_VO0_ROOT_SEL_MASK,
1056 			     (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1057 			     (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1058 		break;
1059 	case HCLK_VOP_ROOT:
1060 		if (rate == 200 * MHz)
1061 			src_clk = HCLK_VOP_ROOT_SEL_200M;
1062 		else if (rate == 100 * MHz)
1063 			src_clk = HCLK_VOP_ROOT_SEL_100M;
1064 		else if (rate == 50 * MHz)
1065 			src_clk = HCLK_VOP_ROOT_SEL_50M;
1066 		else
1067 			src_clk = HCLK_VOP_ROOT_SEL_OSC;
1068 		rk_clrsetreg(&cru->clksel_con[144],
1069 			     HCLK_VOP_ROOT_SEL_MASK,
1070 			     src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1071 		break;
1072 	case PCLK_VOP_ROOT:
1073 		if (rate == 100 * MHz)
1074 			src_clk = PCLK_VOP_ROOT_SEL_100M;
1075 		else if (rate == 50 * MHz)
1076 			src_clk = PCLK_VOP_ROOT_SEL_50M;
1077 		else
1078 			src_clk = PCLK_VOP_ROOT_SEL_OSC;
1079 		rk_clrsetreg(&cru->clksel_con[144],
1080 			     PCLK_VOP_ROOT_SEL_MASK,
1081 			     src_clk << PCLK_VOP_ROOT_SEL_SHIFT);
1082 		break;
1083 
1084 	default:
1085 		return -ENOENT;
1086 	}
1087 
1088 	return rk3576_aclk_vop_get_clk(priv, clk_id);
1089 }
1090 
1091 static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1092 {
1093 	struct rk3576_cru *cru = priv->cru;
1094 	u32 div, sel, con, parent;
1095 
1096 	switch (clk_id) {
1097 	case DCLK_VP0:
1098 	case DCLK_VP0_SRC:
1099 		con = readl(&cru->clksel_con[145]);
1100 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1101 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1102 		break;
1103 	case DCLK_VP1:
1104 	case DCLK_VP1_SRC:
1105 		con = readl(&cru->clksel_con[146]);
1106 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1107 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1108 		break;
1109 	case DCLK_VP2:
1110 	case DCLK_VP2_SRC:
1111 		con = readl(&cru->clksel_con[147]);
1112 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1113 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1114 		break;
1115 	default:
1116 		return -ENOENT;
1117 	}
1118 
1119 	if (sel == DCLK_VOP_SRC_SEL_VPLL)
1120 		parent = priv->vpll_hz;
1121 	else if (sel == DCLK_VOP_SRC_SEL_BPLL)
1122 		parent = priv->bpll_hz / 4;
1123 	else if (sel == DCLK_VOP_SRC_SEL_LPLL)
1124 		parent = priv->lpll_hz / 2;
1125 	else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1126 		parent = priv->gpll_hz;
1127 	else
1128 		parent = priv->cpll_hz;
1129 
1130 	return DIV_TO_RATE(parent, div);
1131 }
1132 
1133 #define RK3576_VOP_PLL_LIMIT_FREQ 600000000
1134 
1135 static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv,
1136 				     ulong clk_id, ulong rate)
1137 {
1138 	struct rk3576_cru *cru = priv->cru;
1139 	ulong pll_rate, now, best_rate = 0;
1140 	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1141 	u32 mask, div_shift, sel_shift;
1142 
1143 	switch (clk_id) {
1144 	case DCLK_VP0:
1145 	case DCLK_VP0_SRC:
1146 		conid = 145;
1147 		con = readl(&cru->clksel_con[conid]);
1148 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1149 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1150 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1151 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1152 		break;
1153 	case DCLK_VP1:
1154 	case DCLK_VP1_SRC:
1155 		conid = 146;
1156 		con = readl(&cru->clksel_con[conid]);
1157 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1158 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1159 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1160 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1161 		break;
1162 	case DCLK_VP2:
1163 	case DCLK_VP2_SRC:
1164 		conid = 147;
1165 		con = readl(&cru->clksel_con[conid]);
1166 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1167 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1168 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1169 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1170 		break;
1171 	default:
1172 		return -ENOENT;
1173 	}
1174 
1175 	if (sel == DCLK_VOP_SRC_SEL_VPLL) {
1176 		pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1177 						 priv->cru, VPLL);
1178 		if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
1179 			div = DIV_ROUND_UP(pll_rate, rate);
1180 			rk_clrsetreg(&cru->clksel_con[conid],
1181 				     mask,
1182 				     DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1183 				     ((div - 1) << div_shift));
1184 		} else {
1185 			div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate);
1186 			if (div % 2)
1187 				div = div + 1;
1188 			rk_clrsetreg(&cru->clksel_con[conid],
1189 				     mask,
1190 				     DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1191 				     ((div - 1) << div_shift));
1192 			rockchip_pll_set_rate(&rk3576_pll_clks[VPLL],
1193 					      priv->cru, VPLL, div * rate);
1194 			priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1195 							      priv->cru, VPLL);
1196 		}
1197 	} else {
1198 		for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) {
1199 			switch (i) {
1200 			case DCLK_VOP_SRC_SEL_GPLL:
1201 				pll_rate = priv->gpll_hz;
1202 				break;
1203 			case DCLK_VOP_SRC_SEL_CPLL:
1204 				pll_rate = priv->cpll_hz;
1205 				break;
1206 			case DCLK_VOP_SRC_SEL_BPLL:
1207 				pll_rate = 0;
1208 				break;
1209 			case DCLK_VOP_SRC_SEL_LPLL:
1210 				pll_rate = 0;
1211 				break;
1212 			case DCLK_VOP_SRC_SEL_VPLL:
1213 				pll_rate = 0;
1214 				break;
1215 			default:
1216 				printf("do not support this vop pll sel\n");
1217 				return -EINVAL;
1218 			}
1219 
1220 			div = DIV_ROUND_UP(pll_rate, rate);
1221 			if (div > 255)
1222 				continue;
1223 			now = pll_rate / div;
1224 			if (abs(rate - now) < abs(rate - best_rate)) {
1225 				best_rate = now;
1226 				best_div = div;
1227 				best_sel = i;
1228 			}
1229 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1230 			      pll_rate, best_rate, best_div, best_sel);
1231 		}
1232 
1233 		if (best_rate) {
1234 			rk_clrsetreg(&cru->clksel_con[conid],
1235 				     mask,
1236 				     best_sel << sel_shift |
1237 				     (best_div - 1) << div_shift);
1238 		} else {
1239 			printf("do not support this vop freq %lu\n", rate);
1240 			return -EINVAL;
1241 		}
1242 	}
1243 	return rk3576_dclk_vop_get_clk(priv, clk_id);
1244 }
1245 
1246 static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1247 {
1248 	struct rk3576_cru *cru = priv->cru;
1249 	u32 div, sel, con, parent;
1250 
1251 	switch (clk_id) {
1252 		case CLK_DSIHOST0:
1253 		con = readl(&cru->clksel_con[151]);
1254 		div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT;
1255 		sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT;
1256 		break;
1257 	default:
1258 		return -ENOENT;
1259 	}
1260 
1261 	if (sel == CLK_DSIHOST0_SEL_VPLL)
1262 		parent = priv->vpll_hz;
1263 	else if (sel == CLK_DSIHOST0_SEL_BPLL)
1264 		parent = priv->bpll_hz / 4;
1265 	else if (sel == CLK_DSIHOST0_SEL_LPLL)
1266 		parent = priv->lpll_hz / 2;
1267 	else if (sel == CLK_DSIHOST0_SEL_GPLL)
1268 		parent = priv->gpll_hz;
1269 	else if (sel == CLK_DSIHOST0_SEL_SPLL)
1270 		parent = priv->spll_hz;
1271 	else
1272 		parent = priv->cpll_hz;
1273 
1274 	return DIV_TO_RATE(parent, div);
1275 }
1276 
1277 static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv,
1278 				     ulong clk_id, ulong rate)
1279 {
1280 	struct rk3576_cru *cru = priv->cru;
1281 	ulong pll_rate, now, best_rate = 0;
1282 	u32 i, con, div, best_div = 0, best_sel = 0;
1283 	u32 mask, div_shift, sel_shift;
1284 
1285 	switch (clk_id) {
1286 	case CLK_DSIHOST0:
1287 		con = 151;
1288 		mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK;
1289 		div_shift = CLK_DSIHOST0_DIV_SHIFT;
1290 		sel_shift = CLK_DSIHOST0_SEL_SHIFT;
1291 		break;
1292 	default:
1293 		return -ENOENT;
1294 	}
1295 	for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) {
1296 		switch (i) {
1297 		case CLK_DSIHOST0_SEL_GPLL:
1298 			pll_rate = priv->gpll_hz;
1299 			break;
1300 		case CLK_DSIHOST0_SEL_CPLL:
1301 			pll_rate = priv->cpll_hz;
1302 			break;
1303 		case CLK_DSIHOST0_SEL_BPLL:
1304 			pll_rate = 0;
1305 			break;
1306 		case CLK_DSIHOST0_SEL_LPLL:
1307 			pll_rate = 0;
1308 			break;
1309 		case CLK_DSIHOST0_SEL_VPLL:
1310 			pll_rate = 0;
1311 			break;
1312 		case CLK_DSIHOST0_SEL_SPLL:
1313 			pll_rate = priv->spll_hz;
1314 			break;
1315 		default:
1316 			printf("do not support this vop pll sel\n");
1317 			return -EINVAL;
1318 		}
1319 
1320 		div = DIV_ROUND_UP(pll_rate, rate);
1321 		if (div > 255)
1322 			continue;
1323 		now = pll_rate / div;
1324 		if (abs(rate - now) < abs(rate - best_rate)) {
1325 			best_rate = now;
1326 			best_div = div;
1327 			best_sel = i;
1328 		}
1329 		debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1330 		      pll_rate, best_rate, best_div, best_sel);
1331 	}
1332 	if (best_rate) {
1333 		rk_clrsetreg(&cru->clksel_con[con],
1334 			     mask,
1335 			     best_sel << sel_shift |
1336 			     (best_div - 1) << div_shift);
1337 	} else {
1338 		printf("do not support this vop freq %lu\n", rate);
1339 		return -EINVAL;
1340 	}
1341 	return rk3576_clk_csihost_get_clk(priv, clk_id);
1342 }
1343 
1344 static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1345 {
1346 	struct rk3576_cru *cru = priv->cru;
1347 	u32 div, sel, con, parent;
1348 	unsigned long m = 0, n = 0;
1349 
1350 	switch (clk_id) {
1351 	case DCLK_EBC:
1352 		con = readl(&cru->clksel_con[123]);
1353 		div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT;
1354 		sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
1355 		if (sel == DCLK_EBC_SEL_CPLL)
1356 			parent = priv->cpll_hz;
1357 		else if (sel == DCLK_EBC_SEL_VPLL)
1358 			parent = priv->vpll_hz;
1359 		else if (sel == DCLK_EBC_SEL_AUPLL)
1360 			parent = priv->aupll_hz;
1361 		else if (sel == DCLK_EBC_SEL_LPLL)
1362 			parent = priv->lpll_hz / 2;
1363 		else if (sel == DCLK_EBC_SEL_GPLL)
1364 			parent = priv->gpll_hz;
1365 		else if (sel == DCLK_EBC_SEL_FRAC_SRC)
1366 			parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC);
1367 		else
1368 			parent = OSC_HZ;
1369 		return DIV_TO_RATE(parent, div);
1370 	case DCLK_EBC_FRAC_SRC:
1371 		con = readl(&cru->clksel_con[123]);
1372 		div = readl(&cru->clksel_con[122]);
1373 		sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT;
1374 		if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL)
1375 			parent = priv->gpll_hz;
1376 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL)
1377 			parent = priv->cpll_hz;
1378 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL)
1379 			parent = priv->vpll_hz;
1380 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL)
1381 			parent = priv->aupll_hz;
1382 		else
1383 			parent = OSC_HZ;
1384 
1385 		n = div & CLK_UART_FRAC_NUMERATOR_MASK;
1386 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1387 		m = div & CLK_UART_FRAC_DENOMINATOR_MASK;
1388 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1389 		return parent * n / m;
1390 	default:
1391 		return -ENOENT;
1392 	}
1393 }
1394 
1395 static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv,
1396 				     ulong clk_id, ulong rate)
1397 {
1398 	struct rk3576_cru *cru = priv->cru;
1399 	u32 div, sel;
1400 	unsigned long m = 0, n = 0, val;
1401 
1402 	switch (clk_id) {
1403 	case DCLK_EBC:
1404 		if (!(priv->gpll_hz % rate)) {
1405 			sel = DCLK_EBC_SEL_GPLL;
1406 			div = priv->gpll_hz / rate;
1407 		} else if (!(priv->cpll_hz % rate)) {
1408 			sel = DCLK_EBC_SEL_CPLL;
1409 			div = priv->cpll_hz / rate;
1410 		} else if (!(priv->aupll_hz % rate)) {
1411 			sel = DCLK_EBC_SEL_AUPLL;
1412 			div = priv->aupll_hz / rate;
1413 		} else if (!(priv->vpll_hz % rate)) {
1414 			sel = DCLK_EBC_SEL_VPLL;
1415 			div = priv->vpll_hz / rate;
1416 		} else if (!(OSC_HZ % rate)) {
1417 			sel = DCLK_EBC_SEL_OSC;
1418 			div = OSC_HZ / rate;
1419 		} else {
1420 			sel = DCLK_EBC_SEL_FRAC_SRC;
1421 			rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate);
1422 			div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate;
1423 		}
1424 		rk_clrsetreg(&cru->clksel_con[123],
1425 			     DCLK_EBC_SEL_MASK | DCLK_EBC_DIV_MASK,
1426 			     (sel << DCLK_EBC_SEL_SHIFT) |
1427 			     (div - 1) << DCLK_EBC_DIV_SHIFT);
1428 		break;
1429 	case DCLK_EBC_FRAC_SRC:
1430 		sel = DCLK_EBC_FRAC_SRC_SEL_GPLL;
1431 		div = 1;
1432 		rational_best_approximation(rate, priv->gpll_hz,
1433 					    GENMASK(16 - 1, 0),
1434 					    GENMASK(16 - 1, 0),
1435 					    &m, &n);
1436 
1437 		if (m < 4 && m != 0) {
1438 			if (n % 2 == 0)
1439 				val = 1;
1440 			else
1441 				val = DIV_ROUND_UP(4, m);
1442 
1443 			n *= val;
1444 			m *= val;
1445 			if (n > 0xffff) {
1446 				n = 0xffff;
1447 			}
1448 		}
1449 
1450 		rk_clrsetreg(&cru->clksel_con[123],
1451 		     DCLK_EBC_FRAC_SRC_SEL_MASK,
1452 		     (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT));
1453 		if (m && n) {
1454 			val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1455 			writel(val, &cru->clksel_con[122]);
1456 		}
1457 		break;
1458 	default:
1459 		return -ENOENT;
1460 	}
1461 	return rk3576_dclk_ebc_get_clk(priv, clk_id);
1462 }
1463 
1464 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1465 {
1466 	struct rk3576_cru *cru = priv->cru;
1467 	u32 con, div, src, p_rate;
1468 
1469 	switch (clk_id) {
1470 	case CLK_GMAC0_PTP_REF_SRC:
1471 	case CLK_GMAC0_PTP_REF:
1472 		con = readl(&cru->clksel_con[105]);
1473 		div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1474 		src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT;
1475 		if (src == CLK_GMAC0_PTP_SEL_GPLL)
1476 			p_rate = priv->gpll_hz;
1477 		else if (src == CLK_GMAC0_PTP_SEL_CPLL)
1478 			p_rate = priv->cpll_hz;
1479 		else
1480 			p_rate = GMAC0_PTP_REFCLK_IN;
1481 		return DIV_TO_RATE(p_rate, div);
1482 	case CLK_GMAC1_PTP_REF_SRC:
1483 	case CLK_GMAC1_PTP_REF:
1484 		con = readl(&cru->clksel_con[104]);
1485 		div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1486 		src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT;
1487 		if (src == CLK_GMAC1_PTP_SEL_GPLL)
1488 			p_rate = priv->gpll_hz;
1489 		else if (src == CLK_GMAC1_PTP_SEL_CPLL)
1490 			p_rate = priv->cpll_hz;
1491 		else
1492 			p_rate = GMAC1_PTP_REFCLK_IN;
1493 		return DIV_TO_RATE(p_rate, div);
1494 	case CLK_GMAC0_125M_SRC:
1495 		con = readl(&cru->clksel_con[30]);
1496 		div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT;
1497 		return DIV_TO_RATE(priv->cpll_hz, div);
1498 	case CLK_GMAC1_125M_SRC:
1499 		con = readl(&cru->clksel_con[31]);
1500 		div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT;
1501 		return DIV_TO_RATE(priv->cpll_hz, div);
1502 	default:
1503 		return -ENOENT;
1504 	}
1505 }
1506 
1507 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv,
1508 				 ulong clk_id, ulong rate)
1509 {
1510 	struct rk3576_cru *cru = priv->cru;
1511 	int div, src;
1512 
1513 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
1514 
1515 	switch (clk_id) {
1516 	case CLK_GMAC0_PTP_REF_SRC:
1517 	case CLK_GMAC0_PTP_REF:
1518 		if (rate == GMAC0_PTP_REFCLK_IN) {
1519 			src = CLK_GMAC0_PTP_SEL_REFIN;
1520 			div = 1;
1521 		} else if (!(priv->gpll_hz % rate)) {
1522 			src = CLK_GMAC0_PTP_SEL_GPLL;
1523 			div = priv->gpll_hz / rate;
1524 		} else {
1525 			src = CLK_GMAC0_PTP_SEL_CPLL;
1526 			div = priv->cpll_hz / rate;
1527 		}
1528 		rk_clrsetreg(&cru->clksel_con[105],
1529 			     CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1530 			     src << CLK_GMAC0_PTP_SEL_SHIFT |
1531 			     (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1532 		break;
1533 	case CLK_GMAC1_PTP_REF_SRC:
1534 	case CLK_GMAC1_PTP_REF:
1535 		if (rate == GMAC1_PTP_REFCLK_IN) {
1536 			src = CLK_GMAC1_PTP_SEL_REFIN;
1537 			div = 1;
1538 		} else if (!(priv->gpll_hz % rate)) {
1539 			src = CLK_GMAC1_PTP_SEL_GPLL;
1540 			div = priv->gpll_hz / rate;
1541 		} else {
1542 			src = CLK_GMAC1_PTP_SEL_CPLL;
1543 			div = priv->cpll_hz / rate;
1544 		}
1545 		rk_clrsetreg(&cru->clksel_con[104],
1546 			     CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1547 			     src << CLK_GMAC1_PTP_SEL_SHIFT |
1548 			     (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1549 		break;
1550 
1551 	case CLK_GMAC0_125M_SRC:
1552 		rk_clrsetreg(&cru->clksel_con[30],
1553 			     CLK_GMAC0_125M_DIV_MASK,
1554 			     (div - 1) << CLK_GMAC0_125M_DIV_SHIFT);
1555 		break;
1556 	case CLK_GMAC1_125M_SRC:
1557 		rk_clrsetreg(&cru->clksel_con[31],
1558 			     CLK_GMAC1_125M_DIV_MASK,
1559 			     (div - 1) << CLK_GMAC1_125M_DIV_SHIFT);
1560 		break;
1561 	default:
1562 		return -ENOENT;
1563 	}
1564 
1565 	return rk3576_gmac_get_clk(priv, clk_id);
1566 }
1567 
1568 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1569 {
1570 	struct rk3576_cru *cru = priv->cru;
1571 	u32 reg, con, fracdiv, p_src, p_rate;
1572 	unsigned long m, n;
1573 
1574 	switch (clk_id) {
1575 	case CLK_UART_FRAC_0:
1576 		reg = 21;
1577 		break;
1578 	case CLK_UART_FRAC_1:
1579 		reg = 23;
1580 		break;
1581 	case CLK_UART_FRAC_2:
1582 		reg = 25;
1583 		break;
1584 	default:
1585 		return -ENOENT;
1586 	}
1587 	con = readl(&cru->clksel_con[reg + 1]);
1588 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1589 	if (p_src == CLK_UART_SRC_SEL_GPLL)
1590 		p_rate = priv->gpll_hz;
1591 	else if (p_src == CLK_UART_SRC_SEL_CPLL)
1592 		p_rate = priv->cpll_hz;
1593 	else if (p_src == CLK_UART_SRC_SEL_AUPLL)
1594 		p_rate = priv->aupll_hz;
1595 	else
1596 		p_rate = OSC_HZ;
1597 
1598 	fracdiv = readl(&cru->clksel_con[reg]);
1599 	n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1600 	n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1601 	m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1602 	m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1603 	return p_rate * n / m;
1604 }
1605 
1606 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv,
1607 				  ulong clk_id, ulong rate)
1608 {
1609 	struct rk3576_cru *cru = priv->cru;
1610 	u32 reg, clk_src, p_rate;
1611 	unsigned long m = 0, n = 0, val;
1612 
1613 	if (priv->cpll_hz % rate == 0) {
1614 		clk_src = CLK_UART_SRC_SEL_CPLL;
1615 		p_rate = priv->cpll_hz;
1616 	} else if (rate == OSC_HZ) {
1617 		clk_src = CLK_UART_SRC_SEL_OSC;
1618 		p_rate = OSC_HZ;
1619 	} else {
1620 		clk_src = CLK_UART_SRC_SEL_GPLL;
1621 		p_rate = priv->cpll_hz;
1622 	}
1623 	rational_best_approximation(rate, p_rate,
1624 					    GENMASK(16 - 1, 0),
1625 					    GENMASK(16 - 1, 0),
1626 					    &m, &n);
1627 
1628 	if (m < 4 && m != 0) {
1629 		if (n % 2 == 0)
1630 			val = 1;
1631 		else
1632 			val = DIV_ROUND_UP(4, m);
1633 
1634 		n *= val;
1635 		m *= val;
1636 		if (n > 0xffff) {
1637 			n = 0xffff;
1638 		}
1639 	}
1640 
1641 
1642 	switch (clk_id) {
1643 	case CLK_UART_FRAC_0:
1644 		reg = 21;
1645 		break;
1646 	case CLK_UART_FRAC_1:
1647 		reg = 23;
1648 		break;
1649 	case CLK_UART_FRAC_2:
1650 		reg = 25;
1651 		break;
1652 	default:
1653 		return -ENOENT;
1654 	}
1655 	rk_clrsetreg(&cru->clksel_con[reg +1],
1656 		     CLK_UART_SRC_SEL_MASK,
1657 		     (clk_src << CLK_UART_SRC_SEL_SHIFT));
1658 	if (m && n) {
1659 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1660 		writel(val, &cru->clksel_con[reg]);
1661 	}
1662 
1663 	return rk3576_uart_frac_get_rate(priv, clk_id);
1664 }
1665 
1666 
1667 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1668 {
1669 	struct rk3576_cru *cru = priv->cru;
1670 	u32 con, div, src, p_rate;
1671 
1672 	switch (clk_id) {
1673 	case SCLK_UART0:
1674 		con = readl(&cru->clksel_con[60]);
1675 		break;
1676 	case SCLK_UART1:
1677 		con = readl(&cru->pmuclksel_con[8]);
1678 		src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
1679 		if (src == CLK_UART1_SEL_OSC)
1680 			return OSC_HZ;
1681 		con = readl(&cru->clksel_con[27]);
1682 		break;
1683 	case SCLK_UART2:
1684 		con = readl(&cru->clksel_con[61]);
1685 		break;
1686 	case SCLK_UART3:
1687 		con = readl(&cru->clksel_con[62]);
1688 		break;
1689 	case SCLK_UART4:
1690 		con = readl(&cru->clksel_con[63]);
1691 		break;
1692 	case SCLK_UART5:
1693 		con = readl(&cru->clksel_con[64]);
1694 		break;
1695 	case SCLK_UART6:
1696 		con = readl(&cru->clksel_con[65]);
1697 		break;
1698 	case SCLK_UART7:
1699 		con = readl(&cru->clksel_con[66]);
1700 		break;
1701 	case SCLK_UART8:
1702 		con = readl(&cru->clksel_con[67]);
1703 		break;
1704 	case SCLK_UART9:
1705 		con = readl(&cru->clksel_con[68]);
1706 		break;
1707 	case SCLK_UART10:
1708 		con = readl(&cru->clksel_con[69]);
1709 		break;
1710 	case SCLK_UART11:
1711 		con = readl(&cru->clksel_con[70]);
1712 		break;
1713 	default:
1714 		return -ENOENT;
1715 	}
1716 	if (clk_id == SCLK_UART1) {
1717 		src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT;
1718 		div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
1719 	} else {
1720 		src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1721 		div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT;
1722 	}
1723 	if (src == CLK_UART_SEL_GPLL)
1724 		p_rate = priv->gpll_hz;
1725 	else  if (src == CLK_UART_SEL_CPLL)
1726 		p_rate = priv->cpll_hz;
1727 	else  if (src == CLK_UART_SEL_AUPLL)
1728 		p_rate = priv->aupll_hz;
1729 	else  if (src == CLK_UART_SEL_FRAC0)
1730 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0);
1731 	else  if (src == CLK_UART_SEL_FRAC1)
1732 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1);
1733 	else  if (src == CLK_UART_SEL_FRAC2)
1734 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2);
1735 	else
1736 		p_rate = OSC_HZ;
1737 
1738 	return DIV_TO_RATE(p_rate, div);
1739 }
1740 
1741 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv,
1742 				  ulong clk_id, ulong rate)
1743 {
1744 	struct rk3576_cru *cru = priv->cru;
1745 	u32 reg, clk_src = 0, div = 0;
1746 
1747 	if (!(priv->gpll_hz % rate)) {
1748 		clk_src = CLK_UART_SEL_GPLL;
1749 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1750 	} else if (!(priv->cpll_hz % rate)) {
1751 		clk_src = CLK_UART_SEL_CPLL;
1752 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1753 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) {
1754 		clk_src = CLK_UART_SEL_FRAC0;
1755 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate);
1756 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) {
1757 		clk_src = CLK_UART_SEL_FRAC1;
1758 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate);
1759 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) {
1760 		clk_src = CLK_UART_SEL_FRAC2;
1761 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate);
1762 	} else if (!(OSC_HZ % rate)) {
1763 		clk_src = CLK_UART_SEL_OSC;
1764 		div = DIV_ROUND_UP(OSC_HZ, rate);
1765 	}
1766 
1767 	switch (clk_id) {
1768 	case SCLK_UART0:
1769 		reg = 60;
1770 		break;
1771 	case SCLK_UART1:
1772 		if (rate == OSC_HZ) {
1773 			rk_clrsetreg(&cru->pmuclksel_con[8],
1774 		     CLK_UART1_SEL_MASK,
1775 		     (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT));
1776 			return 0;
1777 		} else {
1778 		rk_clrsetreg(&cru->clksel_con[27],
1779 		     CLK_UART1_SRC_SEL_MASK |
1780 		     CLK_UART1_SRC_DIV_MASK,
1781 		     (clk_src << CLK_UART1_SRC_SEL_SHIFT) |
1782 		     ((div - 1) << CLK_UART1_SRC_DIV_SHIFT));
1783 		rk_clrsetreg(&cru->pmuclksel_con[8],
1784 		     CLK_UART1_SEL_MASK,
1785 		     (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT));
1786 		return 0;
1787 		}
1788 		break;
1789 	case SCLK_UART2:
1790 		reg = 61;
1791 		break;
1792 	case SCLK_UART3:
1793 		reg = 62;
1794 		break;
1795 	case SCLK_UART4:
1796 		reg = 63;
1797 		break;
1798 	case SCLK_UART5:
1799 		reg = 64;
1800 		break;
1801 	case SCLK_UART6:
1802 		reg = 65;
1803 		break;
1804 	case SCLK_UART7:
1805 		reg = 66;
1806 		break;
1807 	case SCLK_UART8:
1808 		reg = 67;
1809 		break;
1810 	case SCLK_UART9:
1811 		reg = 68;
1812 		break;
1813 	case SCLK_UART10:
1814 		reg = 69;
1815 		break;
1816 	case SCLK_UART11:
1817 		reg = 70;
1818 		break;
1819 	default:
1820 		return -ENOENT;
1821 	}
1822 	rk_clrsetreg(&cru->clksel_con[reg],
1823 		     CLK_UART_SEL_MASK |
1824 		     CLK_UART_DIV_MASK,
1825 		     (clk_src << CLK_UART_SEL_SHIFT) |
1826 		     ((div - 1) << CLK_UART_DIV_SHIFT));
1827 
1828 	return rk3576_uart_get_rate(priv, clk_id);
1829 }
1830 #endif
1831 
1832 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1833 {
1834 	struct rk3576_cru *cru = priv->cru;
1835 	u32 src, div;
1836 
1837 	src = readl(&cru->pmuclksel_con[3]) & 0x3;
1838 	div= readl(&cru->pmuclksel_con[1]) & 0xff;
1839 	if (src == 0)
1840 		return OSC_HZ;
1841 	else if (src == 2)
1842 		return priv->ppll_hz / (div + 1);
1843 	else
1844 		return 26000000;
1845 
1846 }
1847 
1848 static ulong rk3576_clk_get_rate(struct clk *clk)
1849 {
1850 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
1851 	ulong rate = 0;
1852 
1853 	if (!priv->gpll_hz) {
1854 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1855 		return -ENOENT;
1856 	}
1857 
1858 	if (!priv->ppll_hz) {
1859 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
1860 						      priv->cru, PPLL);
1861 	}
1862 
1863 	switch (clk->id) {
1864 	case PLL_LPLL:
1865 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru,
1866 					     LPLL);
1867 		priv->lpll_hz = rate;
1868 		break;
1869 	case PLL_BPLL:
1870 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru,
1871 					     BPLL);
1872 		priv->bpll_hz = rate;
1873 		break;
1874 	case PLL_GPLL:
1875 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru,
1876 					     GPLL);
1877 		break;
1878 	case PLL_CPLL:
1879 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru,
1880 					     CPLL);
1881 		break;
1882 	case PLL_VPLL:
1883 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru,
1884 					     VPLL);
1885 		break;
1886 	case PLL_AUPLL:
1887 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru,
1888 					     AUPLL);
1889 		break;
1890 	case PLL_PPLL:
1891 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru,
1892 					     PPLL) * 2;
1893 		break;
1894 	case ACLK_BUS_ROOT:
1895 	case HCLK_BUS_ROOT:
1896 	case PCLK_BUS_ROOT:
1897 		rate = rk3576_bus_get_clk(priv, clk->id);
1898 		break;
1899 	case ACLK_TOP:
1900 	case HCLK_TOP:
1901 	case PCLK_TOP_ROOT:
1902 	case ACLK_TOP_MID:
1903 		rate = rk3576_top_get_clk(priv, clk->id);
1904 		break;
1905 	case CLK_I2C0:
1906 	case CLK_I2C1:
1907 	case CLK_I2C2:
1908 	case CLK_I2C3:
1909 	case CLK_I2C4:
1910 	case CLK_I2C5:
1911 	case CLK_I2C6:
1912 	case CLK_I2C7:
1913 	case CLK_I2C8:
1914 	case CLK_I2C9:
1915 		rate = rk3576_i2c_get_clk(priv, clk->id);
1916 		break;
1917 	case CLK_SPI0:
1918 	case CLK_SPI1:
1919 	case CLK_SPI2:
1920 	case CLK_SPI3:
1921 	case CLK_SPI4:
1922 		rate = rk3576_spi_get_clk(priv, clk->id);
1923 		break;
1924 	case CLK_PWM1:
1925 	case CLK_PWM2:
1926 	case CLK_PMU1PWM:
1927 		rate = rk3576_pwm_get_clk(priv, clk->id);
1928 		break;
1929 	case CLK_SARADC:
1930 	case CLK_TSADC:
1931 		rate = rk3576_adc_get_clk(priv, clk->id);
1932 		break;
1933 	case CCLK_SRC_SDIO:
1934 	case CCLK_SRC_SDMMC0:
1935 	case CCLK_SRC_EMMC:
1936 	case BCLK_EMMC:
1937 	case SCLK_FSPI_X2:
1938 	case SCLK_FSPI1_X2:
1939 		rate = rk3576_mmc_get_clk(priv, clk->id);
1940 		break;
1941 	case TCLK_WDT0:
1942 		rate = OSC_HZ;
1943 		break;
1944 #ifndef CONFIG_SPL_BUILD
1945 	case ACLK_VOP_ROOT:
1946 	case ACLK_VOP:
1947 	case ACLK_VO0_ROOT:
1948 	case ACLK_VO1_ROOT:
1949 	case HCLK_VOP_ROOT:
1950 	case PCLK_VOP_ROOT:
1951 		rate = rk3576_aclk_vop_get_clk(priv, clk->id);
1952 		break;
1953 	case DCLK_VP0:
1954 	case DCLK_VP0_SRC:
1955 	case DCLK_VP1:
1956 	case DCLK_VP1_SRC:
1957 	case DCLK_VP2:
1958 	case DCLK_VP2_SRC:
1959 		rate = rk3576_dclk_vop_get_clk(priv, clk->id);
1960 		break;
1961 	case CLK_GMAC0_PTP_REF_SRC:
1962 	case CLK_GMAC1_PTP_REF_SRC:
1963 	case CLK_GMAC0_PTP_REF:
1964 	case CLK_GMAC1_PTP_REF:
1965 	case CLK_GMAC0_125M_SRC:
1966 	case CLK_GMAC1_125M_SRC:
1967 		rate = rk3576_gmac_get_clk(priv, clk->id);
1968 		break;
1969 	case CLK_UART_FRAC_0:
1970 	case CLK_UART_FRAC_1:
1971 	case CLK_UART_FRAC_2:
1972 		rate = rk3576_uart_frac_get_rate(priv, clk->id);
1973 		break;
1974 	case SCLK_UART0:
1975 	case SCLK_UART1:
1976 	case SCLK_UART2:
1977 	case SCLK_UART3:
1978 	case SCLK_UART4:
1979 	case SCLK_UART5:
1980 	case SCLK_UART6:
1981 	case SCLK_UART7:
1982 	case SCLK_UART8:
1983 	case SCLK_UART9:
1984 	case SCLK_UART10:
1985 	case SCLK_UART11:
1986 		rate = rk3576_uart_get_rate(priv, clk->id);
1987 		break;
1988 	case CLK_DSIHOST0:
1989 		rate = rk3576_clk_csihost_get_clk(priv, clk->id);
1990 		break;
1991 	case DCLK_EBC:
1992 	case DCLK_EBC_FRAC_SRC:
1993 		rate = rk3576_dclk_ebc_get_clk(priv, clk->id);
1994 		break;
1995 #endif
1996 	case CLK_REF_UFS_CLKOUT:
1997 	case CLK_REF_OSC_MPHY:
1998 		rate = rk3576_ufs_ref_get_rate(priv, clk->id);
1999 		break;
2000 
2001 	default:
2002 		return -ENOENT;
2003 	}
2004 
2005 	return rate;
2006 };
2007 
2008 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
2009 {
2010 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2011 	ulong ret = 0;
2012 
2013 	if (!priv->ppll_hz) {
2014 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2015 						      priv->cru, PPLL);
2016 	}
2017 	if (!priv->aupll_hz) {
2018 		priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2019 						      priv->cru, AUPLL);
2020 	}
2021 
2022 	switch (clk->id) {
2023 	case PLL_CPLL:
2024 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2025 					    CPLL, rate);
2026 		priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL],
2027 						      priv->cru, CPLL);
2028 		break;
2029 	case PLL_GPLL:
2030 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2031 					    GPLL, rate);
2032 		priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL],
2033 						      priv->cru, GPLL);
2034 		break;
2035 	case PLL_VPLL:
2036 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru,
2037 					    VPLL, rate);
2038 		priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
2039 						       priv->cru, VPLL);
2040 		break;
2041 	case PLL_AUPLL:
2042 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru,
2043 					    AUPLL, rate);
2044 		priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2045 						       priv->cru, AUPLL);
2046 		break;
2047 	case PLL_PPLL:
2048 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru,
2049 					    PPLL, rate);
2050 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2051 						      priv->cru, PPLL) * 2;
2052 		break;
2053 	case ACLK_BUS_ROOT:
2054 	case HCLK_BUS_ROOT:
2055 	case PCLK_BUS_ROOT:
2056 		ret = rk3576_bus_set_clk(priv, clk->id, rate);
2057 		break;
2058 	case ACLK_TOP:
2059 	case HCLK_TOP:
2060 	case PCLK_TOP_ROOT:
2061 	case ACLK_TOP_MID:
2062 		ret = rk3576_top_set_clk(priv, clk->id, rate);
2063 		break;
2064 	case CLK_I2C0:
2065 	case CLK_I2C1:
2066 	case CLK_I2C2:
2067 	case CLK_I2C3:
2068 	case CLK_I2C4:
2069 	case CLK_I2C5:
2070 	case CLK_I2C6:
2071 	case CLK_I2C7:
2072 	case CLK_I2C8:
2073 	case CLK_I2C9:
2074 		ret = rk3576_i2c_set_clk(priv, clk->id, rate);
2075 		break;
2076 	case CLK_SPI0:
2077 	case CLK_SPI1:
2078 	case CLK_SPI2:
2079 	case CLK_SPI3:
2080 	case CLK_SPI4:
2081 		ret = rk3576_spi_set_clk(priv, clk->id, rate);
2082 		break;
2083 	case CLK_PWM1:
2084 	case CLK_PWM2:
2085 	case CLK_PMU1PWM:
2086 		ret = rk3576_pwm_set_clk(priv, clk->id, rate);
2087 		break;
2088 	case CLK_SARADC:
2089 	case CLK_TSADC:
2090 		ret = rk3576_adc_set_clk(priv, clk->id, rate);
2091 		break;
2092 	case CCLK_SRC_SDIO:
2093 	case CCLK_SRC_SDMMC0:
2094 	case CCLK_SRC_EMMC:
2095 	case BCLK_EMMC:
2096 	case SCLK_FSPI_X2:
2097 	case SCLK_FSPI1_X2:
2098 		ret = rk3576_mmc_set_clk(priv, clk->id, rate);
2099 		break;
2100 	case TCLK_WDT0:
2101 		ret = OSC_HZ;
2102 		break;
2103 #ifndef CONFIG_SPL_BUILD
2104 	case ACLK_VOP_ROOT:
2105 	case ACLK_VOP:
2106 	case ACLK_VO0_ROOT:
2107 	case ACLK_VO1_ROOT:
2108 	case HCLK_VOP_ROOT:
2109 	case PCLK_VOP_ROOT:
2110 		ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate);
2111 		break;
2112 	case DCLK_VP0:
2113 	case DCLK_VP0_SRC:
2114 	case DCLK_VP1:
2115 	case DCLK_VP1_SRC:
2116 	case DCLK_VP2:
2117 	case DCLK_VP2_SRC:
2118 		ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate);
2119 		break;
2120 	case CLK_GMAC0_PTP_REF_SRC:
2121 	case CLK_GMAC1_PTP_REF_SRC:
2122 	case CLK_GMAC0_PTP_REF:
2123 	case CLK_GMAC1_PTP_REF:
2124 	case CLK_GMAC0_125M_SRC:
2125 	case CLK_GMAC1_125M_SRC:
2126 		ret = rk3576_gmac_set_clk(priv, clk->id, rate);
2127 		break;
2128 	case CLK_UART_FRAC_0:
2129 	case CLK_UART_FRAC_1:
2130 	case CLK_UART_FRAC_2:
2131 		ret = rk3576_uart_frac_set_rate(priv, clk->id, rate);
2132 		break;
2133 	case SCLK_UART0:
2134 	case SCLK_UART1:
2135 	case SCLK_UART2:
2136 	case SCLK_UART3:
2137 	case SCLK_UART4:
2138 	case SCLK_UART5:
2139 	case SCLK_UART6:
2140 	case SCLK_UART7:
2141 	case SCLK_UART8:
2142 	case SCLK_UART9:
2143 	case SCLK_UART10:
2144 	case SCLK_UART11:
2145 		ret = rk3576_uart_set_rate(priv, clk->id, rate);
2146 		break;
2147 	case CLK_DSIHOST0:
2148 		ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate);
2149 		break;
2150 	case DCLK_EBC:
2151 	case DCLK_EBC_FRAC_SRC:
2152 		ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate);
2153 		break;
2154 #endif
2155 	default:
2156 		return -ENOENT;
2157 	}
2158 
2159 	return ret;
2160 };
2161 
2162 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2163 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk,
2164 						     struct clk *parent)
2165 {
2166 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2167 	struct rk3576_cru *cru = priv->cru;
2168 	u32 sel;
2169 	const char *clock_dev_name = parent->dev->name;
2170 
2171 	if (parent->id == PLL_VPLL)
2172 		sel = 2;
2173 	else if (parent->id == PLL_GPLL)
2174 		sel = 0;
2175 	else if (parent->id == PLL_CPLL)
2176 		sel = 1;
2177 	else if (parent->id == PLL_BPLL)
2178 		sel = 3;
2179 	else
2180 		sel = 4;
2181 
2182 	switch (clk->id) {
2183 	case DCLK_VP0_SRC:
2184 		rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK,
2185 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2186 		break;
2187 	case DCLK_VP1_SRC:
2188 		rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK,
2189 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2190 		break;
2191 	case DCLK_VP2_SRC:
2192 		rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK,
2193 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2194 		break;
2195 	case DCLK_VP0:
2196 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2197 			sel = 1;
2198 		else
2199 			sel = 0;
2200 		rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK,
2201 			     sel << DCLK0_VOP_SEL_SHIFT);
2202 		break;
2203 	case DCLK_VP1:
2204 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2205 			sel = 1;
2206 		else
2207 			sel = 0;
2208 		rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK,
2209 			     sel << DCLK1_VOP_SEL_SHIFT);
2210 		break;
2211 	case DCLK_VP2:
2212 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2213 			sel = 1;
2214 		else
2215 			sel = 0;
2216 		rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK,
2217 			     sel << DCLK2_VOP_SEL_SHIFT);
2218 		break;
2219 	default:
2220 		return -EINVAL;
2221 	}
2222 	return 0;
2223 }
2224 
2225 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk,
2226 						     struct clk *parent)
2227 {
2228 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2229 	struct rk3576_cru *cru = priv->cru;
2230 	u32 sel;
2231 	const char *clock_dev_name = parent->dev->name;
2232 
2233 	if (parent->id == CLK_REF_MPHY_26M)
2234 		sel = 2;
2235 	else if (!strcmp(clock_dev_name, "xin24m"))
2236 		sel = 0;
2237 	else
2238 		sel = 1;
2239 
2240 	rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0);
2241 	return 0;
2242 }
2243 
2244 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent)
2245 {
2246 	switch (clk->id) {
2247 	case DCLK_VP0_SRC:
2248 	case DCLK_VP1_SRC:
2249 	case DCLK_VP2_SRC:
2250 	case DCLK_VP0:
2251 	case DCLK_VP1:
2252 	case DCLK_VP2:
2253 		return rk3576_dclk_vop_set_parent(clk, parent);
2254 	case CLK_REF_OSC_MPHY:
2255 		return rk3576_ufs_ref_set_parent(clk, parent);
2256 
2257 	default:
2258 		return -ENOENT;
2259 	}
2260 
2261 	return 0;
2262 }
2263 #endif
2264 
2265 static struct clk_ops rk3576_clk_ops = {
2266 	.get_rate = rk3576_clk_get_rate,
2267 	.set_rate = rk3576_clk_set_rate,
2268 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2269 	.set_parent = rk3576_clk_set_parent,
2270 #endif
2271 };
2272 
2273 static void rk3576_clk_init(struct rk3576_clk_priv *priv)
2274 {
2275 	int ret;
2276 
2277 	priv->spll_hz = 702000000;
2278 
2279 	if (priv->cpll_hz != CPLL_HZ) {
2280 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2281 					    CPLL, CPLL_HZ);
2282 		if (!ret)
2283 			priv->cpll_hz = CPLL_HZ;
2284 	}
2285 	if (priv->gpll_hz != GPLL_HZ) {
2286 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2287 					    GPLL, GPLL_HZ);
2288 		if (!ret)
2289 			priv->gpll_hz = GPLL_HZ;
2290 	}
2291 }
2292 
2293 static int rk3576_clk_probe(struct udevice *dev)
2294 {
2295 	struct rk3576_clk_priv *priv = dev_get_priv(dev);
2296 	int ret;
2297 #if CONFIG_IS_ENABLED(CLK_SCMI)
2298 	struct clk clk;
2299 #endif
2300 
2301 	priv->sync_kernel = false;
2302 
2303 #ifdef CONFIG_SPL_BUILD
2304 	/* relase presetn_bigcore_biu/cru/grf */
2305 	writel(0x1c001c00, 0x26010010);
2306 	/* set spll to normal mode */
2307 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2308 	       RK3576_SCRU_BASE + RK3576_PLL_CON(137));
2309 	writel(BITS_WITH_WMASK(1, 0x3U, 0),
2310 	       RK3576_SCRU_BASE + RK3576_MODE_CON0);
2311 	/* fix ppll\aupll\cpll */
2312 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2313 	       RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129));
2314 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2315 	       RK3576_CRU_BASE + RK3576_PLL_CON(97));
2316 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2317 	       RK3576_CRU_BASE + RK3576_PLL_CON(105));
2318 	writel(BITS_WITH_WMASK(1, 0x3U, 6),
2319 	       RK3576_CRU_BASE + RK3576_MODE_CON0);
2320 	writel(BITS_WITH_WMASK(1, 0x3U, 8),
2321 	       RK3576_CRU_BASE + RK3576_MODE_CON0);
2322 	/* init cci */
2323 	writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2324 	rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru,
2325 			      BPLL, LPLL_HZ);
2326 	if (!priv->armclk_enter_hz) {
2327 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru,
2328 					    LPLL, LPLL_HZ);
2329 		priv->armclk_enter_hz =
2330 			rockchip_pll_get_rate(&rk3576_pll_clks[LPLL],
2331 					      priv->cru, LPLL);
2332 		priv->armclk_init_hz = priv->armclk_enter_hz;
2333 		rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK,
2334 			     0 << CLK_LITCORE_DIV_SHIFT);
2335 	}
2336 	/* init cci */
2337 	writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2338 
2339 	/* Change bigcore rm from 4 to 3 */
2340 	writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c);
2341 	writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44);
2342 	writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38);
2343 	udelay(1);
2344 	writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38);
2345 	/* Change litcore rm from 4 to 3 */
2346 	writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x3c);
2347 	writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x44);
2348 	writel(0x00020002, RK3576_LITCORE_GRF_BASE + 0x38);
2349 	udelay(1);
2350 	writel(0x00020000, RK3576_LITCORE_GRF_BASE + 0x38);
2351 	/* Change cci rm form 4 to 3 */
2352 	writel(0x001c000c, RK3576_CCI_GRF_BASE + 0x54);
2353 #endif
2354 
2355 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2356 	if (IS_ERR(priv->grf))
2357 		return PTR_ERR(priv->grf);
2358 
2359 	rk3576_clk_init(priv);
2360 
2361 #if CONFIG_IS_ENABLED(CLK_SCMI)
2362 #ifndef CONFIG_SPL_BUILD
2363 	ret = rockchip_get_scmi_clk(&clk.dev);
2364 	if (ret) {
2365 		printf("Failed to get scmi clk dev, ret=%d\n", ret);
2366 		return ret;
2367 	}
2368 	if (!priv->armclk_enter_hz) {
2369 		clk.id = ARMCLK_L;
2370 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2371 		if (ret < 0) {
2372 			printf("Failed to set cpubl, ret=%d\n", ret);
2373 		} else {
2374 			priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2375 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
2376 		}
2377 	}
2378 	clk.id = ARMCLK_B;
2379 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2380 	if (ret < 0)
2381 		printf("Failed to set cpub, ret=%d\n", ret);
2382 #endif
2383 #endif
2384 
2385 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2386 	ret = clk_set_defaults(dev);
2387 	if (ret)
2388 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2389 	else
2390 		priv->sync_kernel = true;
2391 
2392 	return 0;
2393 }
2394 
2395 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev)
2396 {
2397 	struct rk3576_clk_priv *priv = dev_get_priv(dev);
2398 
2399 	priv->cru = dev_read_addr_ptr(dev);
2400 
2401 	return 0;
2402 }
2403 
2404 static int rk3576_clk_bind(struct udevice *dev)
2405 {
2406 	int ret;
2407 	struct udevice *sys_child, *sf_child;
2408 	struct sysreset_reg *priv;
2409 	struct softreset_reg *sf_priv;
2410 
2411 	/* The reset driver does not have a device node, so bind it here */
2412 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2413 				 &sys_child);
2414 	if (ret) {
2415 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2416 	} else {
2417 		priv = malloc(sizeof(struct sysreset_reg));
2418 		priv->glb_srst_fst_value = offsetof(struct rk3576_cru,
2419 						    glb_srst_fst);
2420 		priv->glb_srst_snd_value = offsetof(struct rk3576_cru,
2421 						    glb_srsr_snd);
2422 		sys_child->priv = priv;
2423 	}
2424 
2425 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2426 					 dev_ofnode(dev), &sf_child);
2427 	if (ret) {
2428 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2429 	} else {
2430 		sf_priv = malloc(sizeof(struct softreset_reg));
2431 		sf_priv->sf_reset_offset = offsetof(struct rk3576_cru,
2432 						    softrst_con[0]);
2433 		sf_priv->sf_reset_num = 524454;
2434 		sf_child->priv = sf_priv;
2435 	}
2436 
2437 	return 0;
2438 }
2439 
2440 static const struct udevice_id rk3576_clk_ids[] = {
2441 	{ .compatible = "rockchip,rk3576-cru" },
2442 	{ }
2443 };
2444 
2445 U_BOOT_DRIVER(rockchip_rk3576_cru) = {
2446 	.name		= "rockchip_rk3576_cru",
2447 	.id		= UCLASS_CLK,
2448 	.of_match	= rk3576_clk_ids,
2449 	.priv_auto_alloc_size = sizeof(struct rk3576_clk_priv),
2450 	.ofdata_to_platdata = rk3576_clk_ofdata_to_platdata,
2451 	.ops		= &rk3576_clk_ops,
2452 	.bind		= rk3576_clk_bind,
2453 	.probe		= rk3576_clk_probe,
2454 };
2455 
2456 #ifndef CONFIG_SPL_BUILD
2457 /**
2458  * soc_clk_dump() - Print clock frequencies
2459  * Returns zero on success
2460  *
2461  * Implementation for the clk dump command.
2462  */
2463 int soc_clk_dump(void)
2464 {
2465 	struct udevice *cru_dev;
2466 	struct rk3576_clk_priv *priv;
2467 	const struct rk3576_clk_info *clk_dump;
2468 	struct clk clk;
2469 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2470 	unsigned long rate;
2471 	int i, ret;
2472 
2473 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2474 					  DM_GET_DRIVER(rockchip_rk3576_cru),
2475 					  &cru_dev);
2476 	if (ret) {
2477 		printf("%s failed to get cru device\n", __func__);
2478 		return ret;
2479 	}
2480 
2481 	priv = dev_get_priv(cru_dev);
2482 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2483 	       priv->sync_kernel ? "sync kernel" : "uboot",
2484 	       priv->armclk_enter_hz / 1000,
2485 	       priv->armclk_init_hz / 1000,
2486 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2487 	       priv->set_armclk_rate ? " KHz" : "N/A");
2488 	for (i = 0; i < clk_count; i++) {
2489 		clk_dump = &clks_dump[i];
2490 		if (clk_dump->name) {
2491 			memset(&clk, 0, sizeof(struct clk));
2492 			clk.id = clk_dump->id;
2493 			if (clk_dump->is_cru)
2494 				ret = clk_request(cru_dev, &clk);
2495 			if (ret < 0)
2496 				return ret;
2497 
2498 			rate = clk_get_rate(&clk);
2499 			clk_free(&clk);
2500 			if (rate < 0)
2501 				printf("  %s %s\n", clk_dump->name,
2502 				       "unknown");
2503 			else
2504 				printf("  %s %lu KHz\n", clk_dump->name,
2505 				       rate / 1000);
2506 		}
2507 	}
2508 
2509 	return 0;
2510 }
2511 #endif
2512