xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3562.c (revision bcf6e1a4748ac5be0a5dc950ec047eb4e01fbeef)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022 Rockchip Electronics Co., Ltd
4  * Author: Finley Xiao <finley.xiao@rock-chips.com>
5  */
6 
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <syscon.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/cru_rk3562.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/io.h>
15 #include <dm/lists.h>
16 #include <dt-bindings/clock/rk3562-cru.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
21 
22 static struct rockchip_pll_rate_table rk3562_pll_rates[] = {
23 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
24 	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
25 	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
26 	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
27 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
28 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
29 	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
30 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
31 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
32 	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
33 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
34 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
35 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
36 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
37 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
38 	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
39 	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
40 	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
41 	{ /* sentinel */ },
42 };
43 
44 static struct rockchip_pll_clock rk3562_pll_clks[] = {
45 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3562_PLL_CON(0),
46 		     RK3562_MODE_CON, 0, 10, 0, rk3562_pll_rates),
47 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3562_PLL_CON(24),
48 		     RK3562_MODE_CON, 2, 10, 0, rk3562_pll_rates),
49 	[VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3562_PLL_CON(32),
50 		     RK3562_MODE_CON, 6, 10, 0, rk3562_pll_rates),
51 	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3562_PLL_CON(40),
52 		     RK3562_MODE_CON, 8, 10, 0, rk3562_pll_rates),
53 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3562_PMU1_PLL_CON(0),
54 		     RK3562_PMU1_MODE_CON, 0, 10, 0, rk3562_pll_rates),
55 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3562_SUBDDR_PLL_CON(0),
56 		     RK3562_SUBDDR_MODE_CON, 0, 10, 0, NULL),
57 };
58 
59 #define RK3562_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg)	\
60 {								\
61 	.rate = _rate##U,					\
62 	.aclk_div = (_aclk_m_core) - 1,				\
63 	.pclk_div = (_pclk_dbg) - 1,				\
64 }
65 
66 static struct rockchip_cpu_rate_table rk3562_cpu_rates[] = {
67 	RK3562_CPUCLK_RATE(1416000000, 1, 8),
68 	RK3562_CPUCLK_RATE(1296000000, 1, 8),
69 	RK3562_CPUCLK_RATE(1200000000, 1, 8),
70 	RK3562_CPUCLK_RATE(1104000000, 1, 8),
71 	RK3562_CPUCLK_RATE(1008000000, 1, 8),
72 	RK3562_CPUCLK_RATE(912000000, 1, 6),
73 	RK3562_CPUCLK_RATE(816000000, 1, 6),
74 	RK3562_CPUCLK_RATE(600000000, 1, 6),
75 	RK3562_CPUCLK_RATE(408000000, 1, 4),
76 	{ /* sentinel */ },
77 };
78 
79 #ifndef CONFIG_SPL_BUILD
80 #define RK3562_CLK_DUMP(_id, _name)		\
81 {						\
82 	.id = _id,				\
83 	.name = _name,				\
84 }
85 
86 static const struct rk3562_clk_info clks_dump[] = {
87 	RK3562_CLK_DUMP(PLL_APLL, "apll"),
88 	RK3562_CLK_DUMP(PLL_GPLL, "gpll"),
89 	RK3562_CLK_DUMP(PLL_VPLL, "vpll"),
90 	RK3562_CLK_DUMP(PLL_HPLL, "hpll"),
91 	RK3562_CLK_DUMP(PLL_CPLL, "cpll"),
92 	RK3562_CLK_DUMP(PLL_DPLL, "dpll"),
93 	RK3562_CLK_DUMP(ACLK_BUS, "aclk_bus"),
94 	RK3562_CLK_DUMP(HCLK_BUS, "hclk_bus"),
95 	RK3562_CLK_DUMP(PCLK_BUS, "pclk_bus"),
96 	RK3562_CLK_DUMP(ACLK_PERI, "aclk_peri"),
97 	RK3562_CLK_DUMP(HCLK_PERI, "hclk_peri"),
98 	RK3562_CLK_DUMP(PCLK_PERI, "pclk_peri"),
99 };
100 #endif
101 
102 /*
103  *
104  * rational_best_approximation(31415, 10000,
105  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
106  *
107  * you may look at given_numerator as a fixed point number,
108  * with the fractional part size described in given_denominator.
109  *
110  * for theoretical background, see:
111  * http://en.wikipedia.org/wiki/Continued_fraction
112  */
113 static void rational_best_approximation(unsigned long given_numerator,
114 					unsigned long given_denominator,
115 					unsigned long max_numerator,
116 					unsigned long max_denominator,
117 					unsigned long *best_numerator,
118 					unsigned long *best_denominator)
119 {
120 	unsigned long n, d, n0, d0, n1, d1;
121 
122 	n = given_numerator;
123 	d = given_denominator;
124 	n0 = 0;
125 	d1 = 0;
126 	n1 = 1;
127 	d0 = 1;
128 	for (;;) {
129 		unsigned long t, a;
130 
131 		if (n1 > max_numerator || d1 > max_denominator) {
132 			n1 = n0;
133 			d1 = d0;
134 			break;
135 		}
136 		if (d == 0)
137 			break;
138 		t = d;
139 		a = n / d;
140 		d = n % d;
141 		n = t;
142 		t = n0 + a * n1;
143 		n0 = n1;
144 		n1 = t;
145 		t = d0 + a * d1;
146 		d0 = d1;
147 		d1 = t;
148 	}
149 	*best_numerator = n1;
150 	*best_denominator = d1;
151 }
152 
153 static int rk3562_armclk_set_rate(struct rk3562_clk_priv *priv, ulong new_rate)
154 {
155 	const struct rockchip_cpu_rate_table *rate;
156 	struct rk3562_cru *cru = priv->cru;
157 	ulong old_rate;
158 
159 	rate = rockchip_get_cpu_settings(rk3562_cpu_rates, new_rate);
160 	if (!rate) {
161 		printf("%s unsupported rate\n", __func__);
162 		return -EINVAL;
163 	}
164 
165 	/*
166 	 * set up dependent divisors for DBG and ACLK clocks.
167 	 */
168 	old_rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru,
169 					 APLL);
170 	if (old_rate == new_rate) {
171 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
172 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
173 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
174 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
175 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
176 	} else if (old_rate > new_rate) {
177 		if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL],
178 					  priv->cru, APLL, new_rate))
179 			return -EINVAL;
180 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
181 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
182 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
183 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
184 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
185 	} else if (old_rate < new_rate) {
186 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
187 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
188 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
189 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
190 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
191 
192 		if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL],
193 					  priv->cru, APLL, new_rate))
194 			return -EINVAL;
195 	}
196 
197 	return 0;
198 }
199 
200 static ulong rk3562_bus_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
201 {
202 	struct rk3562_cru *cru = priv->cru;
203 	u32 sel, con, div;
204 	ulong rate;
205 
206 	switch (clk_id) {
207 	case ACLK_BUS:
208 		con = readl(&cru->clksel_con[40]);
209 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
210 		div = (con & ACLK_BUS_DIV_MASK) >> ACLK_BUS_DIV_SHIFT;
211 		break;
212 	case HCLK_BUS:
213 		con = readl(&cru->clksel_con[40]);
214 		sel = (con & HCLK_BUS_SEL_MASK) >> HCLK_BUS_SEL_SHIFT;
215 		div = (con & HCLK_BUS_DIV_MASK) >> HCLK_BUS_DIV_SHIFT;
216 		break;
217 	case PCLK_BUS:
218 		con = readl(&cru->clksel_con[41]);
219 		sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
220 		div = (con & PCLK_BUS_DIV_MASK) >> PCLK_BUS_DIV_SHIFT;
221 		break;
222 	default:
223 		return -ENOENT;
224 	}
225 
226 	if (sel == ACLK_BUS_SEL_CPLL)
227 		rate = priv->cpll_hz;
228 	else
229 		rate = priv->gpll_hz;
230 
231 	return DIV_TO_RATE(rate, div);
232 }
233 
234 static ulong rk3562_bus_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
235 				 ulong rate)
236 {
237 	struct rk3562_cru *cru = priv->cru;
238 	u32 sel, div;
239 
240 	if (priv->cpll_hz % rate == 0) {
241 		sel = ACLK_BUS_SEL_CPLL;
242 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
243 	} else {
244 		sel= ACLK_BUS_SEL_GPLL;
245 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
246 	}
247 
248 	switch (clk_id) {
249 	case ACLK_BUS:
250 		rk_clrsetreg(&cru->clksel_con[40],
251 			     ACLK_BUS_SEL_MASK | ACLK_BUS_DIV_MASK,
252 			     (sel << ACLK_BUS_SEL_SHIFT) |
253 			     ((div - 1) << ACLK_BUS_DIV_SHIFT));
254 		break;
255 	case HCLK_BUS:
256 		rk_clrsetreg(&cru->clksel_con[40],
257 			     HCLK_BUS_SEL_MASK | HCLK_BUS_DIV_MASK,
258 			     (sel << HCLK_BUS_SEL_SHIFT) |
259 			     ((div - 1) << HCLK_BUS_DIV_SHIFT));
260 		break;
261 	case PCLK_BUS:
262 		rk_clrsetreg(&cru->clksel_con[41],
263 			     PCLK_BUS_SEL_MASK | PCLK_BUS_DIV_MASK,
264 			     (sel << PCLK_BUS_SEL_SHIFT) |
265 			     ((div - 1) << PCLK_BUS_DIV_SHIFT));
266 		break;
267 	default:
268 		return -ENOENT;
269 	}
270 
271 	return rk3562_bus_get_rate(priv, clk_id);
272 }
273 
274 static ulong rk3562_peri_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
275 {
276 	struct rk3562_cru *cru = priv->cru;
277 	u32 sel, con, div;
278 	ulong rate;
279 
280 	switch (clk_id) {
281 	case ACLK_PERI:
282 		con = readl(&cru->periclksel_con[0]);
283 		sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
284 		div = (con & ACLK_PERI_DIV_MASK) >> ACLK_PERI_DIV_SHIFT;
285 		break;
286 	case HCLK_PERI:
287 		con = readl(&cru->periclksel_con[0]);
288 		sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT;
289 		div = (con & HCLK_PERI_DIV_MASK) >> HCLK_PERI_DIV_SHIFT;
290 		break;
291 	case PCLK_PERI:
292 		con = readl(&cru->periclksel_con[1]);
293 		sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
294 		div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
295 		break;
296 	default:
297 		return -ENOENT;
298 	}
299 
300 	if (sel == ACLK_PERI_SEL_CPLL)
301 		rate = priv->cpll_hz;
302 	else
303 		rate = priv->gpll_hz;
304 
305 	return DIV_TO_RATE(rate, div);
306 }
307 
308 static ulong rk3562_peri_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
309 				  ulong rate)
310 {
311 	struct rk3562_cru *cru = priv->cru;
312 	u32 sel, div;
313 
314 	if (priv->cpll_hz % rate == 0) {
315 		sel = ACLK_PERI_SEL_CPLL;
316 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
317 	} else {
318 		sel= ACLK_PERI_SEL_GPLL;
319 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
320 	}
321 
322 	switch (clk_id) {
323 	case ACLK_PERI:
324 		rk_clrsetreg(&cru->periclksel_con[0],
325 			     ACLK_PERI_SEL_MASK | ACLK_PERI_DIV_MASK,
326 			     (sel << ACLK_PERI_SEL_SHIFT) |
327 			     ((div - 1) << ACLK_PERI_DIV_SHIFT));
328 		break;
329 	case HCLK_PERI:
330 		rk_clrsetreg(&cru->periclksel_con[0],
331 			     HCLK_PERI_SEL_MASK | HCLK_PERI_DIV_MASK,
332 			     (sel << HCLK_PERI_SEL_SHIFT) |
333 			     ((div - 1) << HCLK_PERI_DIV_SHIFT));
334 		break;
335 	case PCLK_PERI:
336 		rk_clrsetreg(&cru->periclksel_con[1],
337 			     PCLK_PERI_SEL_MASK | PCLK_PERI_DIV_MASK,
338 			     (sel << PCLK_PERI_SEL_SHIFT) |
339 			     ((div - 1) << PCLK_PERI_DIV_SHIFT));
340 		break;
341 	default:
342 		return -ENOENT;
343 	}
344 
345 	return rk3562_peri_get_rate(priv, clk_id);
346 }
347 
348 static ulong rk3562_i2c_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
349 {
350 	struct rk3562_cru *cru = priv->cru;
351 	u32 sel, con, div;
352 	ulong rate;
353 
354 	switch (clk_id) {
355 	case CLK_PMU0_I2C0:
356 		con = readl(&cru->pmu0clksel_con[3]);
357 		sel = (con & CLK_PMU0_I2C0_SEL_MASK) >> CLK_PMU0_I2C0_SEL_SHIFT;
358 		if (sel == CLK_PMU0_I2C0_SEL_200M)
359 			rate = 200 * MHz;
360 		else if (sel == CLK_PMU0_I2C0_SEL_24M)
361 			rate = OSC_HZ;
362 		else
363 			rate = 32768;
364 		div = (con & CLK_PMU0_I2C0_DIV_MASK) >> CLK_PMU0_I2C0_DIV_SHIFT;
365 
366 		return DIV_TO_RATE(rate, div);
367 	case CLK_I2C:
368 	case CLK_I2C1:
369 	case CLK_I2C2:
370 	case CLK_I2C3:
371 	case CLK_I2C4:
372 	case CLK_I2C5:
373 		con = readl(&cru->clksel_con[41]);
374 		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
375 		if (sel == CLK_I2C_SEL_200M)
376 			rate = 200 * MHz;
377 		else if (sel == CLK_I2C_SEL_100M)
378 			rate = 100 * MHz;
379 		else if (sel == CLK_I2C_SEL_50M)
380 			rate = 50 * MHz;
381 		else
382 			rate = OSC_HZ;
383 		break;
384 	default:
385 		return -ENOENT;
386 	}
387 
388 	return rate;
389 }
390 
391 static ulong rk3562_i2c_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
392 				 ulong rate)
393 {
394 	struct rk3562_cru *cru = priv->cru;
395 	u32 sel, div;
396 
397 	switch (clk_id) {
398 	case CLK_PMU0_I2C0:
399 		if (rate == 200 * MHz) {
400 			sel = CLK_PMU0_I2C0_SEL_200M;
401 			div = 1;
402 		} else if (rate == OSC_HZ) {
403 			sel = CLK_PMU0_I2C0_SEL_24M;
404 			div = 1;
405 		} else if (rate == 32768) {
406 			sel = CLK_PMU0_I2C0_SEL_32K;
407 			div = 1;
408 		} else {
409 			sel = CLK_PMU0_I2C0_SEL_200M;
410 			div = DIV_ROUND_UP(200 * MHz, rate);
411 			assert(div - 1 <= 31);
412 		}
413 		rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_DIV_MASK,
414 			     (div - 1) << CLK_PMU0_I2C0_DIV_SHIFT);
415 		rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_SEL_MASK,
416 			     sel << CLK_PMU0_I2C0_SEL_SHIFT);
417 		break;
418 	case CLK_I2C:
419 	case CLK_I2C2:
420 	case CLK_I2C3:
421 	case CLK_I2C4:
422 	case CLK_I2C5:
423 		if (rate == 200 * MHz)
424 			sel = CLK_I2C_SEL_200M;
425 		else if (rate == 100 * MHz)
426 			sel = CLK_I2C_SEL_100M;
427 		else if (rate == 50 * MHz)
428 			sel = CLK_I2C_SEL_50M;
429 		else
430 			sel = CLK_I2C_SEL_24M;
431 		rk_clrsetreg(&cru->clksel_con[41], CLK_I2C_SEL_MASK,
432 			     sel << CLK_I2C_SEL_SHIFT);
433 		break;
434 	default:
435 		return -ENOENT;
436 	}
437 
438 
439 	return rk3562_i2c_get_rate(priv, clk_id);
440 }
441 
442 static ulong rk3562_uart_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
443 {
444 	struct rk3562_cru *cru = priv->cru;
445 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
446 	unsigned long m, n;
447 
448 	switch (clk_id) {
449 	case SCLK_PMU1_UART0:
450 		con = readl(&cru->pmu1clksel_con[2]);
451 		src = (con & CLK_PMU1_UART0_SEL_MASK) >>
452 		       CLK_PMU1_UART0_SEL_SHIFT;
453 		div = (con & CLK_PMU1_UART0_SRC_DIV_MASK) >>
454 		       CLK_PMU1_UART0_SRC_DIV_SHIFT;
455 		if (src == CLK_UART_SEL_SRC) {
456 			return DIV_TO_RATE(priv->cpll_hz, div);
457 		} else if (src == CLK_UART_SEL_FRAC) {
458 			fracdiv = readl(&cru->pmu1clksel_con[3]);
459 			n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
460 			n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
461 			m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
462 			m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
463 			return DIV_TO_RATE(priv->cpll_hz, div) * n / m;
464 		} else {
465 			return OSC_HZ;
466 		}
467 	case SCLK_UART1:
468 		reg = 21;
469 		break;
470 	case SCLK_UART2:
471 		reg = 23;
472 		break;
473 	case SCLK_UART3:
474 		reg = 25;
475 		break;
476 	case SCLK_UART4:
477 		reg = 27;
478 		break;
479 	case SCLK_UART5:
480 		reg = 29;
481 		break;
482 	case SCLK_UART6:
483 		reg = 31;
484 		break;
485 	case SCLK_UART7:
486 		reg = 33;
487 		break;
488 	case SCLK_UART8:
489 		reg = 35;
490 		break;
491 	case SCLK_UART9:
492 		reg = 37;
493 		break;
494 	default:
495 		return -ENOENT;
496 	}
497 	con = readl(&cru->periclksel_con[reg]);
498 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
499 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
500 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
501 	if (p_src == CLK_UART_SRC_SEL_GPLL)
502 		p_rate = priv->gpll_hz;
503 	else
504 		p_rate = priv->cpll_hz;
505 	if (src == CLK_UART_SEL_SRC) {
506 		return DIV_TO_RATE(p_rate, div);
507 	} else if (src == CLK_UART_SEL_FRAC) {
508 		fracdiv = readl(&cru->periclksel_con[reg + 1]);
509 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
510 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
511 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
512 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
513 		return DIV_TO_RATE(p_rate, div) * n / m;
514 	} else {
515 		return OSC_HZ;
516 	}
517 }
518 
519 static ulong rk3562_uart_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
520 				  ulong rate)
521 {
522 	struct rk3562_cru *cru = priv->cru;
523 	u32 reg, clk_src, uart_src, div;
524 	unsigned long m = 0, n = 0, val;
525 
526 	switch (clk_id) {
527 	case SCLK_PMU1_UART0:
528 		if (priv->cpll_hz % rate == 0) {
529 			uart_src = CLK_UART_SEL_SRC;
530 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
531 		} else if (rate == OSC_HZ) {
532 			uart_src = CLK_UART_SEL_XIN24M;
533 			div = 2;
534 		} else {
535 			uart_src = CLK_UART_SEL_FRAC;
536 			div = 2;
537 			rational_best_approximation(rate, priv->cpll_hz / div,
538 						    GENMASK(16 - 1, 0),
539 						    GENMASK(16 - 1, 0),
540 						    &n, &m);
541 		}
542 
543 		rk_clrsetreg(&cru->pmu1clksel_con[2],
544 			     CLK_PMU1_UART0_SEL_MASK |
545 			     CLK_PMU1_UART0_SRC_DIV_MASK,
546 			     (uart_src << CLK_PMU1_UART0_SEL_SHIFT) |
547 			     ((div - 1) << CLK_PMU1_UART0_SRC_DIV_SHIFT));
548 		if (m && n) {
549 			val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m;
550 			writel(val, &cru->pmu1clksel_con[3]);
551 		}
552 
553 		return rk3562_uart_get_rate(priv, clk_id);
554 	case SCLK_UART1:
555 		reg = 21;
556 		break;
557 	case SCLK_UART2:
558 		reg = 23;
559 		break;
560 	case SCLK_UART3:
561 		reg = 25;
562 		break;
563 	case SCLK_UART4:
564 		reg = 27;
565 		break;
566 	case SCLK_UART5:
567 		reg = 29;
568 		break;
569 	case SCLK_UART6:
570 		reg = 31;
571 		break;
572 	case SCLK_UART7:
573 		reg = 33;
574 		break;
575 	case SCLK_UART8:
576 		reg = 35;
577 		break;
578 	case SCLK_UART9:
579 		reg = 37;
580 		break;
581 	default:
582 		return -ENOENT;
583 	}
584 
585 	if (priv->gpll_hz % rate == 0) {
586 		clk_src = CLK_UART_SRC_SEL_GPLL;
587 		uart_src = CLK_UART_SEL_SRC;
588 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
589 	} else if (priv->cpll_hz % rate == 0) {
590 		clk_src = CLK_UART_SRC_SEL_CPLL;
591 		uart_src = CLK_UART_SEL_SRC;
592 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
593 	} else if (rate == OSC_HZ) {
594 		clk_src = CLK_UART_SRC_SEL_GPLL;
595 		uart_src = CLK_UART_SEL_XIN24M;
596 		div = 2;
597 	} else {
598 		clk_src = CLK_UART_SRC_SEL_GPLL;
599 		uart_src = CLK_UART_SEL_FRAC;
600 		div = 2;
601 		rational_best_approximation(rate, priv->gpll_hz / div,
602 					    GENMASK(16 - 1, 0),
603 					    GENMASK(16 - 1, 0),
604 					    &n, &m);
605 	}
606 
607 	rk_clrsetreg(&cru->periclksel_con[reg],
608 		     CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
609 		     CLK_UART_SRC_DIV_MASK,
610 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
611 		     (uart_src << CLK_UART_SEL_SHIFT) |
612 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
613 	if (m && n) {
614 		val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m;
615 		writel(val, &cru->periclksel_con[reg + 1]);
616 	}
617 
618 	return rk3562_uart_get_rate(priv, clk_id);
619 }
620 
621 static ulong rk3562_pwm_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
622 {
623 	struct rk3562_cru *cru = priv->cru;
624 	u32 sel, con, div, mask, shift;
625 	ulong rate;
626 
627 	switch (clk_id) {
628 	case CLK_PMU1_PWM0:
629 		con = readl(&cru->pmu1clksel_con[4]);
630 		sel = (con & CLK_PMU1_PWM0_SEL_MASK) >> CLK_PMU1_PWM0_SEL_SHIFT;
631 		if (sel == CLK_PMU1_PWM0_SEL_200M)
632 			rate = 200 * MHz;
633 		else if (sel == CLK_PMU1_PWM0_SEL_24M)
634 			rate = OSC_HZ;
635 		else
636 			rate = 32768;
637 		div = (con & CLK_PMU1_PWM0_DIV_MASK) >> CLK_PMU1_PWM0_DIV_SHIFT;
638 
639 		return DIV_TO_RATE(rate, div);
640 	case CLK_PWM1_PERI:
641 		mask = CLK_PWM1_PERI_SEL_MASK;
642 		shift = CLK_PWM1_PERI_SEL_SHIFT;
643 		break;
644 	case CLK_PWM2_PERI:
645 		mask = CLK_PWM2_PERI_SEL_MASK;
646 		shift = CLK_PWM2_PERI_SEL_SHIFT;
647 		break;
648 	case CLK_PWM3_PERI:
649 		mask = CLK_PWM3_PERI_SEL_MASK;
650 		shift = CLK_PWM3_PERI_SEL_SHIFT;
651 		break;
652 	default:
653 		return -ENOENT;
654 	}
655 
656 	con = readl(&cru->periclksel_con[40]);
657 	sel = (con & mask) >> shift;
658 	if (sel == CLK_PWM_SEL_100M)
659 		rate = 100 * MHz;
660 	else if (sel == CLK_PWM_SEL_50M)
661 		rate = 50 * MHz;
662 	else
663 		rate = OSC_HZ;
664 
665 	return rate;
666 }
667 
668 static ulong rk3562_pwm_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
669 				 ulong rate)
670 {
671 	struct rk3562_cru *cru = priv->cru;
672 	u32 sel, div, mask, shift;
673 
674 	switch (clk_id) {
675 	case CLK_PMU1_PWM0:
676 		if (rate == 200 * MHz) {
677 			sel = CLK_PMU1_PWM0_SEL_200M;
678 			div = 1;
679 		} else if (rate == OSC_HZ) {
680 			sel = CLK_PMU1_PWM0_SEL_24M;
681 			div = 1;
682 		} else if (rate == 32768) {
683 			sel = CLK_PMU1_PWM0_SEL_32K;
684 			div = 1;
685 		} else {
686 			sel = CLK_PMU1_PWM0_SEL_200M;
687 			div = DIV_ROUND_UP(200 * MHz, rate);
688 			assert(div - 1 <= 3);
689 		}
690 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_DIV_MASK,
691 			     (div - 1) << CLK_PMU1_PWM0_DIV_SHIFT);
692 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_SEL_MASK,
693 			     sel << CLK_PMU1_PWM0_SEL_SHIFT);
694 
695 		return rk3562_pwm_get_rate(priv, clk_id);
696 	case CLK_PWM1_PERI:
697 		mask = CLK_PWM1_PERI_SEL_MASK;
698 		shift = CLK_PWM1_PERI_SEL_SHIFT;
699 		break;
700 	case CLK_PWM2_PERI:
701 		mask = CLK_PWM2_PERI_SEL_MASK;
702 		shift = CLK_PWM2_PERI_SEL_SHIFT;
703 		break;
704 	case CLK_PWM3_PERI:
705 		mask = CLK_PWM3_PERI_SEL_MASK;
706 		shift = CLK_PWM3_PERI_SEL_SHIFT;
707 		break;
708 	default:
709 		return -ENOENT;
710 	}
711 
712 	if (rate == 100 * MHz)
713 		sel = CLK_PWM_SEL_100M;
714 	else if (rate == 50 * MHz)
715 		sel = CLK_PWM_SEL_50M;
716 	else
717 		sel = CLK_PWM_SEL_24M;
718 	rk_clrsetreg(&cru->periclksel_con[40], mask, sel << shift);
719 
720 	return rk3562_pwm_get_rate(priv, clk_id);
721 }
722 
723 static ulong rk3562_spi_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
724 {
725 	struct rk3562_cru *cru = priv->cru;
726 	u32 sel, con, div, mask, shift;
727 	ulong rate;
728 
729 	switch (clk_id) {
730 	case CLK_PMU1_SPI0:
731 		con = readl(&cru->pmu1clksel_con[4]);
732 		sel = (con & CLK_PMU1_SPI0_SEL_MASK) >> CLK_PMU1_SPI0_SEL_SHIFT;
733 		if (sel == CLK_PMU1_SPI0_SEL_200M)
734 			rate = 200 * MHz;
735 		else if (sel == CLK_PMU1_SPI0_SEL_24M)
736 			rate = OSC_HZ;
737 		else
738 			rate = 32768;
739 		div = (con & CLK_PMU1_SPI0_DIV_MASK) >> CLK_PMU1_SPI0_DIV_SHIFT;
740 
741 		return DIV_TO_RATE(rate, div);
742 	case CLK_SPI1:
743 		mask = CLK_SPI1_SEL_MASK;
744 		shift = CLK_SPI1_SEL_SHIFT;
745 		break;
746 	case CLK_SPI2:
747 		mask = CLK_SPI2_SEL_MASK;
748 		shift = CLK_SPI2_SEL_SHIFT;
749 		break;
750 	default:
751 		return -ENOENT;
752 	}
753 
754 	con = readl(&cru->periclksel_con[20]);
755 	sel = (con & mask) >> shift;
756 	if (sel == CLK_SPI_SEL_200M)
757 		rate = 200 * MHz;
758 	else if (sel == CLK_SPI_SEL_100M)
759 		rate = 100 * MHz;
760 	else if (sel == CLK_SPI_SEL_50M)
761 		rate = 50 * MHz;
762 	else
763 		rate = OSC_HZ;
764 
765 	return rate;
766 }
767 
768 static ulong rk3562_spi_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
769 				 ulong rate)
770 {
771 	struct rk3562_cru *cru = priv->cru;
772 	u32 sel, div, mask, shift;
773 
774 	switch (clk_id) {
775 	case CLK_PMU1_SPI0:
776 		if (rate == 200 * MHz) {
777 			sel = CLK_PMU1_SPI0_SEL_200M;
778 			div = 1;
779 		} else if (rate == OSC_HZ) {
780 			sel = CLK_PMU1_SPI0_SEL_24M;
781 			div = 1;
782 		} else if (rate == 32768) {
783 			sel = CLK_PMU1_SPI0_SEL_32K;
784 			div = 1;
785 		} else {
786 			sel = CLK_PMU1_SPI0_SEL_200M;
787 			div = DIV_ROUND_UP(200 * MHz, rate);
788 			assert(div - 1 <= 3);
789 		}
790 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_DIV_MASK,
791 			     (div - 1) << CLK_PMU1_SPI0_DIV_SHIFT);
792 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_SEL_MASK,
793 			     sel << CLK_PMU1_SPI0_SEL_SHIFT);
794 
795 		return rk3562_spi_get_rate(priv, clk_id);
796 	case CLK_SPI1:
797 		mask = CLK_SPI1_SEL_MASK;
798 		shift = CLK_SPI1_SEL_SHIFT;
799 		break;
800 	case CLK_SPI2:
801 		mask = CLK_SPI2_SEL_MASK;
802 		shift = CLK_SPI2_SEL_SHIFT;
803 		break;
804 	default:
805 		return -ENOENT;
806 	}
807 
808 	if (rate == 200 * MHz)
809 		sel = CLK_SPI_SEL_200M;
810 	else if (rate == 100 * MHz)
811 		sel = CLK_SPI_SEL_100M;
812 	else if (rate == 50 * MHz)
813 		sel = CLK_SPI_SEL_50M;
814 	else
815 		sel = CLK_SPI_SEL_24M;
816 	rk_clrsetreg(&cru->periclksel_con[20], mask, sel << shift);
817 
818 	return rk3562_spi_get_rate(priv, clk_id);
819 }
820 
821 static ulong rk3562_tsadc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
822 {
823 	struct rk3562_cru *cru = priv->cru;
824 	u32 div, con;
825 
826 	con = readl(&cru->clksel_con[43]);
827 	switch (clk_id) {
828 	case CLK_TSADC_TSEN:
829 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
830 		       CLK_TSADC_TSEN_DIV_SHIFT;
831 		break;
832 	case CLK_TSADC:
833 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
834 		break;
835 	default:
836 		return -ENOENT;
837 	}
838 
839 	return DIV_TO_RATE(OSC_HZ, div);
840 }
841 
842 static ulong rk3562_tsadc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
843 				   ulong rate)
844 {
845 	struct rk3562_cru *cru = priv->cru;
846 	u32 div, mask, shift;
847 
848 	switch (clk_id) {
849 	case CLK_TSADC_TSEN:
850 		mask = CLK_TSADC_TSEN_DIV_MASK;
851 		shift =	CLK_TSADC_TSEN_DIV_SHIFT;
852 		break;
853 	case CLK_TSADC:
854 		mask = CLK_TSADC_DIV_MASK;
855 		shift =	CLK_TSADC_DIV_SHIFT;
856 		break;
857 	default:
858 		return -ENOENT;
859 	}
860 
861 	div = DIV_ROUND_UP(OSC_HZ, rate);
862 	rk_clrsetreg(&cru->clksel_con[43], mask, (div - 1) << shift);
863 
864 	return rk3562_tsadc_get_rate(priv, clk_id);
865 }
866 
867 static ulong rk3562_saradc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
868 {
869 	struct rk3562_cru *cru = priv->cru;
870 	u32 div, con;
871 
872 	switch (clk_id) {
873 	case CLK_SARADC_VCCIO156:
874 		con = readl(&cru->clksel_con[44]);
875 		div = (con & CLK_SARADC_VCCIO156_DIV_MASK) >>
876 		       CLK_SARADC_VCCIO156_DIV_SHIFT;
877 		break;
878 	case CLK_SARADC:
879 		con = readl(&cru->periclksel_con[46]);
880 		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
881 		break;
882 	default:
883 		return -ENOENT;
884 	}
885 
886 	return DIV_TO_RATE(OSC_HZ, div);
887 }
888 
889 static ulong rk3562_saradc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
890 				    ulong rate)
891 {
892 	struct rk3562_cru *cru = priv->cru;
893 	u32 div;
894 
895 	switch (clk_id) {
896 	case CLK_SARADC_VCCIO156:
897 		div = DIV_ROUND_UP(OSC_HZ, rate);
898 		rk_clrsetreg(&cru->clksel_con[44], CLK_SARADC_VCCIO156_DIV_MASK,
899 			     (div - 1) << CLK_SARADC_VCCIO156_DIV_SHIFT);
900 		break;
901 	case CLK_SARADC:
902 		div = DIV_ROUND_UP(OSC_HZ, rate);
903 		rk_clrsetreg(&cru->periclksel_con[46], CLK_SARADC_DIV_MASK,
904 			     (div - 1) << CLK_SARADC_DIV_SHIFT);
905 		break;
906 	default:
907 		return -ENOENT;
908 	}
909 
910 	return rk3562_saradc_get_rate(priv, clk_id);
911 }
912 
913 static ulong rk3562_sfc_get_rate(struct rk3562_clk_priv *priv)
914 {
915 	struct rk3562_cru *cru = priv->cru;
916 	u32 div, sel, con, parent;
917 
918 	con = readl(&cru->periclksel_con[20]);
919 	div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
920 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
921 	if (sel == SCLK_SFC_SRC_SEL_GPLL)
922 		parent = priv->gpll_hz;
923 	else if (sel == SCLK_SFC_SRC_SEL_CPLL)
924 		parent = priv->cpll_hz;
925 	else
926 		parent = OSC_HZ;
927 
928 	return DIV_TO_RATE(parent, div);
929 }
930 
931 static ulong rk3562_sfc_set_rate(struct rk3562_clk_priv *priv, ulong rate)
932 {
933 	struct rk3562_cru *cru = priv->cru;
934 	int div, sel;
935 
936 	if (OSC_HZ % rate == 0) {
937 		div = DIV_ROUND_UP(OSC_HZ, rate);
938 		sel = SCLK_SFC_SRC_SEL_24M;
939 	} else if ((priv->cpll_hz % rate) == 0) {
940 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
941 		sel = SCLK_SFC_SRC_SEL_CPLL;
942 	} else {
943 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
944 		sel = SCLK_SFC_SRC_SEL_GPLL;
945 	}
946 
947 	assert(div - 1 <= 255);
948 	rk_clrsetreg(&cru->periclksel_con[20],
949 		     SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
950 		     sel << SCLK_SFC_SEL_SHIFT |
951 		     (div - 1) << SCLK_SFC_DIV_SHIFT);
952 
953 	return rk3562_sfc_get_rate(priv);
954 }
955 
956 static ulong rk3562_emmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
957 {
958 	struct rk3562_cru *cru = priv->cru;
959 	u32 div, sel, con, parent;
960 
961 	switch (clk_id) {
962 	case CCLK_EMMC:
963 		con = readl(&cru->periclksel_con[18]);
964 		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
965 		sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
966 		if (sel == CCLK_EMMC_SEL_GPLL)
967 			parent = priv->gpll_hz;
968 		else if (sel == CCLK_EMMC_SEL_CPLL)
969 			parent = priv->cpll_hz;
970 		else if (sel == CCLK_EMMC_SEL_HPLL)
971 			parent = priv->hpll_hz;
972 		else
973 			parent = OSC_HZ;
974 		break;
975 	case BCLK_EMMC:
976 		con = readl(&cru->periclksel_con[19]);
977 		div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
978 		sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
979 		if (sel == BCLK_EMMC_SEL_GPLL)
980 			parent = priv->gpll_hz;
981 		else
982 			parent = priv->cpll_hz;
983 		break;
984 	default:
985 		return -ENOENT;
986 	}
987 
988 	return DIV_TO_RATE(parent, div);
989 }
990 
991 static ulong rk3562_emmc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
992 				  ulong rate)
993 {
994 	struct rk3562_cru *cru = priv->cru;
995 	int div, sel;
996 
997 	switch (clk_id) {
998 	case CCLK_EMMC:
999 		if (OSC_HZ % rate == 0) {
1000 			div = DIV_ROUND_UP(OSC_HZ, rate);
1001 			sel = CCLK_EMMC_SEL_24M;
1002 		} else if ((priv->cpll_hz % rate) == 0) {
1003 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1004 			sel = CCLK_EMMC_SEL_CPLL;
1005 		} else if ((priv->hpll_hz % rate) == 0) {
1006 			div = DIV_ROUND_UP(priv->hpll_hz, rate);
1007 			sel = CCLK_EMMC_SEL_HPLL;
1008 		} else {
1009 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1010 			sel = CCLK_EMMC_SEL_GPLL;
1011 		}
1012 		rk_clrsetreg(&cru->periclksel_con[18],
1013 			     CCLK_EMMC_SEL_MASK | CCLK_EMMC_DIV_MASK,
1014 			     sel << CCLK_EMMC_SEL_SHIFT |
1015 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
1016 		break;
1017 	case BCLK_EMMC:
1018 		if ((priv->cpll_hz % rate) == 0) {
1019 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1020 			sel = BCLK_EMMC_SEL_CPLL;
1021 		} else {
1022 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1023 			sel = BCLK_EMMC_SEL_GPLL;
1024 		}
1025 		rk_clrsetreg(&cru->periclksel_con[19],
1026 			     BCLK_EMMC_SEL_MASK | BCLK_EMMC_DIV_MASK,
1027 			     sel << BCLK_EMMC_SEL_SHIFT |
1028 			     (div - 1) << BCLK_EMMC_DIV_SHIFT);
1029 		break;
1030 	default:
1031 		return -ENOENT;
1032 	}
1033 
1034 	return rk3562_emmc_get_rate(priv, clk_id);
1035 }
1036 
1037 static ulong rk3562_sdmmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1038 {
1039 	struct rk3562_cru *cru = priv->cru;
1040 	u32 div, sel, con;
1041 	ulong prate;
1042 
1043 	switch (clk_id) {
1044 	case HCLK_SDMMC0:
1045 	case CCLK_SDMMC0:
1046 	case SCLK_SDMMC0_SAMPLE:
1047 		con = readl(&cru->periclksel_con[16]);
1048 		div = (con & CCLK_SDMMC0_DIV_MASK) >> CCLK_SDMMC0_DIV_SHIFT;
1049 		sel = (con & CCLK_SDMMC0_SEL_MASK) >> CCLK_SDMMC0_SEL_SHIFT;
1050 		break;
1051 	case HCLK_SDMMC1:
1052 	case CCLK_SDMMC1:
1053 	case SCLK_SDMMC1_SAMPLE:
1054 		con = readl(&cru->periclksel_con[17]);
1055 		div = (con & CCLK_SDMMC1_DIV_MASK) >> CCLK_SDMMC1_DIV_SHIFT;
1056 		sel = (con & CCLK_SDMMC1_SEL_MASK) >> CCLK_SDMMC1_SEL_SHIFT;
1057 		break;
1058 	default:
1059 		return -ENOENT;
1060 	}
1061 
1062 	if (sel == CCLK_SDMMC_SEL_GPLL)
1063 		prate = priv->gpll_hz;
1064 	else if (sel == CCLK_SDMMC_SEL_CPLL)
1065 		prate = priv->cpll_hz;
1066 	else if (sel == CCLK_SDMMC_SEL_HPLL)
1067 		prate = priv->hpll_hz;
1068 	else
1069 		prate = OSC_HZ;
1070 
1071 	return DIV_TO_RATE(prate, div);
1072 }
1073 
1074 static ulong rk3562_sdmmc_set_rate(struct rk3562_clk_priv *priv,
1075 				   ulong clk_id, ulong rate)
1076 {
1077 	struct rk3562_cru *cru = priv->cru;
1078 	u32 div, sel;
1079 
1080 	if (OSC_HZ % rate == 0) {
1081 		div = DIV_ROUND_UP(OSC_HZ, rate);
1082 		sel = CCLK_SDMMC_SEL_24M;
1083 	} else if ((priv->cpll_hz % rate) == 0) {
1084 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
1085 		sel = CCLK_SDMMC_SEL_CPLL;
1086 	} else if ((priv->hpll_hz % rate) == 0) {
1087 		div = DIV_ROUND_UP(priv->hpll_hz, rate);
1088 		sel = CCLK_SDMMC_SEL_HPLL;
1089 	} else {
1090 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1091 		sel = CCLK_SDMMC_SEL_CPLL;
1092 	}
1093 
1094 	switch (clk_id) {
1095 	case HCLK_SDMMC0:
1096 	case CCLK_SDMMC0:
1097 		rk_clrsetreg(&cru->periclksel_con[16],
1098 			     CCLK_SDMMC0_SEL_MASK | CCLK_SDMMC0_DIV_MASK,
1099 			     sel << CCLK_SDMMC0_SEL_SHIFT |
1100 			     (div - 1) << CCLK_SDMMC0_DIV_SHIFT);
1101 		break;
1102 	case HCLK_SDMMC1:
1103 	case CCLK_SDMMC1:
1104 		rk_clrsetreg(&cru->periclksel_con[17],
1105 			     CCLK_SDMMC1_SEL_MASK | CCLK_SDMMC1_DIV_MASK,
1106 			     sel << CCLK_SDMMC1_SEL_SHIFT |
1107 			     (div - 1) << CCLK_SDMMC1_DIV_SHIFT);
1108 		break;
1109 	default:
1110 		return -ENOENT;
1111 	}
1112 
1113 	return rk3562_sdmmc_get_rate(priv, clk_id);
1114 }
1115 
1116 static ulong rk3562_vop_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1117 {
1118 	struct rk3562_cru *cru = priv->cru;
1119 	u32 con, sel, div;
1120 	ulong prate;
1121 
1122 	switch (clk_id) {
1123 	case ACLK_VOP:
1124 		con = readl(&cru->clksel_con[28]);
1125 		div = (con & ACLK_VOP_DIV_MASK) >> ACLK_VOP_DIV_SHIFT;
1126 		sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT;
1127 		if (sel == ACLK_VOP_SEL_GPLL)
1128 			prate = priv->gpll_hz;
1129 		else if (sel == ACLK_VOP_SEL_CPLL)
1130 			prate = priv->cpll_hz;
1131 		else if (sel == ACLK_VOP_SEL_HPLL)
1132 			prate = priv->hpll_hz;
1133 		else if (sel == ACLK_VOP_SEL_VPLL)
1134 			prate = priv->vpll_hz;
1135 		else
1136 			return -ENOENT;
1137 
1138 		return DIV_TO_RATE(prate, div);
1139 	case DCLK_VOP:
1140 		con = readl(&cru->clksel_con[30]);
1141 		div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1142 		sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1143 		if (sel == DCLK_VOP_SEL_VPLL)
1144 			priv->vpll_hz =
1145 				rockchip_pll_get_rate(&rk3562_pll_clks[VPLL],
1146 						      priv->cru, VPLL);
1147 		break;
1148 	case DCLK_VOP1:
1149 		con = readl(&cru->clksel_con[31]);
1150 		div = (con & DCLK_VOP1_DIV_MASK) >> DCLK_VOP1_DIV_SHIFT;
1151 		sel = (con & DCLK_VOP1_SEL_MASK) >> DCLK_VOP1_SEL_SHIFT;
1152 		break;
1153 	default:
1154 		return -ENOENT;
1155 	}
1156 
1157 	if (sel == DCLK_VOP_SEL_GPLL)
1158 		prate = priv->gpll_hz;
1159 	else if (sel == DCLK_VOP_SEL_HPLL)
1160 		prate = priv->hpll_hz;
1161 	else if (sel == DCLK_VOP_SEL_VPLL)
1162 		prate = priv->vpll_hz;
1163 	else
1164 		return -ENOENT;
1165 
1166 	return DIV_TO_RATE(prate, div);
1167 }
1168 
1169 #define RK3562_VOP_PLL_LIMIT_FREQ 600000000
1170 
1171 static ulong rk3562_vop_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1172 				 ulong rate)
1173 {
1174 	struct rk3562_cru *cru = priv->cru;
1175 	u32 i, div, sel, best_div = 0, best_sel = 0;
1176 	ulong pll_rate, now, best_rate = 0;
1177 
1178 	switch (clk_id) {
1179 	case ACLK_VOP:
1180 		if ((priv->cpll_hz % rate) == 0) {
1181 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1182 			sel = ACLK_VOP_SEL_CPLL;
1183 		} else if ((priv->hpll_hz % rate) == 0) {
1184 			div = DIV_ROUND_UP(priv->hpll_hz, rate);
1185 			sel = ACLK_VOP_SEL_HPLL;
1186 		} else if ((priv->vpll_hz % rate) == 0) {
1187 			div = DIV_ROUND_UP(priv->vpll_hz, rate);
1188 			sel = ACLK_VOP_SEL_VPLL;
1189 		} else {
1190 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1191 			sel = ACLK_VOP_SEL_GPLL;
1192 		}
1193 		rk_clrsetreg(&cru->clksel_con[28],
1194 			     ACLK_VOP_SEL_MASK | ACLK_VOP_DIV_MASK,
1195 			     sel << ACLK_VOP_SEL_SHIFT |
1196 			     ((div - 1) << ACLK_VOP_DIV_SHIFT));
1197 
1198 		return rk3562_vop_get_rate(priv, clk_id);
1199 	case DCLK_VOP:
1200 		div = DIV_ROUND_UP(RK3562_VOP_PLL_LIMIT_FREQ, rate);
1201 		rk_clrsetreg(&cru->clksel_con[30],
1202 			     DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1203 			     DCLK_VOP_SEL_VPLL << DCLK_VOP_SEL_SHIFT |
1204 			     ((div - 1) << DCLK_VOP_DIV_SHIFT));
1205 		rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru,
1206 				      VPLL, div * rate);
1207 		break;
1208 	case DCLK_VOP1:
1209 		for (i = 0; i <= DCLK_VOP_SEL_APLL; i++) {
1210 			switch (i) {
1211 			case DCLK_VOP_SEL_GPLL:
1212 				pll_rate = priv->gpll_hz;
1213 				break;
1214 			case DCLK_VOP_SEL_HPLL:
1215 				pll_rate = priv->hpll_hz;
1216 				break;
1217 			case DCLK_VOP_SEL_VPLL:
1218 			case DCLK_VOP_SEL_APLL:
1219 				continue;
1220 			default:
1221 				printf("do not support this vop pll sel\n");
1222 				return -EINVAL;
1223 			}
1224 
1225 			div = DIV_ROUND_UP(pll_rate, rate);
1226 			if (div > 255)
1227 				continue;
1228 			now = pll_rate / div;
1229 			if (abs(rate - now) < abs(rate - best_rate)) {
1230 				best_rate = now;
1231 				best_div = div;
1232 				best_sel = i;
1233 			}
1234 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1235 			      pll_rate, best_rate, best_div, best_sel);
1236 		}
1237 		if (best_rate) {
1238 			rk_clrsetreg(&cru->clksel_con[31],
1239 				     DCLK_VOP1_SEL_MASK | DCLK_VOP1_DIV_MASK,
1240 				     best_sel << DCLK_VOP1_SEL_SHIFT |
1241 				     (best_div - 1) << DCLK_VOP1_DIV_SHIFT);
1242 		} else {
1243 			printf("do not support this vop freq %lu\n", rate);
1244 			return -EINVAL;
1245 		}
1246 		break;
1247 	default:
1248 		return -ENOENT;
1249 	}
1250 
1251 	return rk3562_vop_get_rate(priv, clk_id);
1252 }
1253 
1254 static ulong rk3562_gmac_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1255 {
1256 	struct rk3562_cru *cru = priv->cru;
1257 	u32 con, sel, div;
1258 	ulong prate;
1259 
1260 	switch (clk_id) {
1261 	case CLK_GMAC_125M_CRU_I:
1262 		con = readl(&cru->clksel_con[45]);
1263 		sel = (con & CLK_GMAC_125M_SEL_MASK) >> CLK_GMAC_125M_SEL_SHIFT;
1264 		if (sel == CLK_GMAC_125M)
1265 			return 125000000;
1266 		else
1267 			return OSC_HZ;
1268 	case CLK_GMAC_50M_CRU_I:
1269 		con = readl(&cru->clksel_con[45]);
1270 		sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT;
1271 		if (sel == CLK_GMAC_50M)
1272 			return 50000000;
1273 		else
1274 			return OSC_HZ;
1275 	case CLK_MAC100_50M_MATRIX:
1276 		con = readl(&cru->clksel_con[47]);
1277 		sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT;
1278 		if (sel == CLK_GMAC_50M)
1279 			return 50000000;
1280 		else
1281 			return OSC_HZ;
1282 	case CLK_GMAC_ETH_OUT2IO:
1283 		con = readl(&cru->clksel_con[46]);
1284 		sel = (con & CLK_GMAC_ETH_OUT2IO_SEL_MASK) >> CLK_GMAC_ETH_OUT2IO_SEL_SHIFT;
1285 		div = (con & CLK_GMAC_ETH_OUT2IO_DIV_MASK) >> CLK_GMAC_ETH_OUT2IO_DIV_SHIFT;
1286 		if (sel == CLK_GMAC_ETH_OUT2IO_GPLL)
1287 			prate = priv->gpll_hz;
1288 		else
1289 			prate = priv->cpll_hz;
1290 		break;
1291 	default:
1292 		return -ENOENT;
1293 	}
1294 
1295 	return DIV_TO_RATE(prate, div);
1296 }
1297 
1298 static ulong rk3562_gmac_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1299 				  ulong rate)
1300 {
1301 	struct rk3562_cru *cru = priv->cru;
1302 	u32 sel, div;
1303 
1304 	switch (clk_id) {
1305 	case CLK_GMAC_125M_CRU_I:
1306 		if (rate == 125000000)
1307 			sel = CLK_GMAC_125M;
1308 		else
1309 			sel = CLK_GMAC_24M;
1310 		rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_125M_SEL_MASK,
1311 			     sel << CLK_GMAC_125M_SEL_SHIFT);
1312 		break;
1313 	case CLK_GMAC_50M_CRU_I:
1314 		if (rate == 50000000)
1315 			sel = CLK_GMAC_50M;
1316 		else
1317 			sel = CLK_GMAC_24M;
1318 		rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_50M_SEL_MASK,
1319 			     sel << CLK_GMAC_50M_SEL_SHIFT);
1320 		break;
1321 	case CLK_MAC100_50M_MATRIX:
1322 		if (rate == 50000000)
1323 			sel = CLK_GMAC_50M;
1324 		else
1325 			sel = CLK_GMAC_24M;
1326 		rk_clrsetreg(&cru->clksel_con[47], CLK_GMAC_50M_SEL_MASK,
1327 			     sel << CLK_GMAC_50M_SEL_SHIFT);
1328 		break;
1329 	case CLK_GMAC_ETH_OUT2IO:
1330 		if ((priv->cpll_hz % rate) == 0) {
1331 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1332 			sel = CLK_GMAC_ETH_OUT2IO_CPLL;
1333 		} else {
1334 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1335 			sel = CLK_GMAC_ETH_OUT2IO_GPLL;
1336 		}
1337 		rk_clrsetreg(&cru->clksel_con[46],
1338 			     CLK_GMAC_ETH_OUT2IO_SEL_MASK | CLK_GMAC_ETH_OUT2IO_DIV_MASK,
1339 			     sel << CLK_GMAC_ETH_OUT2IO_SEL_SHIFT |
1340 			     (div - 1) << CLK_GMAC_ETH_OUT2IO_DIV_SHIFT);
1341 		break;
1342 	default:
1343 		return -ENOENT;
1344 	}
1345 
1346 	return rk3562_gmac_get_rate(priv, clk_id);
1347 }
1348 
1349 static ulong rk3562_clk_get_rate(struct clk *clk)
1350 {
1351 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1352 	ulong rate = 0;
1353 
1354 	if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) {
1355 		printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n",
1356 		       __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz);
1357 		return -ENOENT;
1358 	}
1359 
1360 	switch (clk->id) {
1361 	case PLL_APLL:
1362 	case ARMCLK:
1363 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru,
1364 					     APLL);
1365 		break;
1366 	case PLL_GPLL:
1367 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL], priv->cru,
1368 					     GPLL);
1369 		break;
1370 
1371 	case PLL_VPLL:
1372 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL], priv->cru,
1373 					     VPLL);
1374 		break;
1375 	case PLL_HPLL:
1376 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL], priv->cru,
1377 					     HPLL);
1378 		break;
1379 	case PLL_CPLL:
1380 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[CPLL], priv->cru,
1381 					     CPLL);
1382 		break;
1383 	case PLL_DPLL:
1384 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[DPLL], priv->cru,
1385 					     DPLL);
1386 		break;
1387 	case ACLK_BUS:
1388 	case HCLK_BUS:
1389 	case PCLK_BUS:
1390 		rate = rk3562_bus_get_rate(priv, clk->id);
1391 		break;
1392 	case ACLK_PERI:
1393 	case HCLK_PERI:
1394 	case PCLK_PERI:
1395 		rate = rk3562_peri_get_rate(priv, clk->id);
1396 		break;
1397 	case CLK_PMU0_I2C0:
1398 	case CLK_I2C:
1399 	case CLK_I2C1:
1400 	case CLK_I2C2:
1401 	case CLK_I2C3:
1402 	case CLK_I2C4:
1403 	case CLK_I2C5:
1404 		rate = rk3562_i2c_get_rate(priv, clk->id);
1405 		break;
1406 	case SCLK_PMU1_UART0:
1407 	case SCLK_UART1:
1408 	case SCLK_UART2:
1409 	case SCLK_UART3:
1410 	case SCLK_UART4:
1411 	case SCLK_UART5:
1412 	case SCLK_UART6:
1413 	case SCLK_UART7:
1414 	case SCLK_UART8:
1415 	case SCLK_UART9:
1416 		rate = rk3562_uart_get_rate(priv, clk->id);
1417 		break;
1418 	case CLK_PMU1_PWM0:
1419 	case CLK_PWM1_PERI:
1420 	case CLK_PWM2_PERI:
1421 	case CLK_PWM3_PERI:
1422 		rate = rk3562_pwm_get_rate(priv, clk->id);
1423 		break;
1424 	case CLK_PMU1_SPI0:
1425 	case CLK_SPI1:
1426 	case CLK_SPI2:
1427 		rate = rk3562_spi_get_rate(priv, clk->id);
1428 		break;
1429 	case CLK_TSADC:
1430 	case CLK_TSADC_TSEN:
1431 		rate = rk3562_tsadc_get_rate(priv, clk->id);
1432 		break;
1433 	case CLK_SARADC:
1434 	case CLK_SARADC_VCCIO156:
1435 		rate = rk3562_saradc_get_rate(priv, clk->id);
1436 		break;
1437 	case SCLK_SFC:
1438 		rate = rk3562_sfc_get_rate(priv);
1439 		break;
1440 	case CCLK_EMMC:
1441 	case BCLK_EMMC:
1442 		rate = rk3562_emmc_get_rate(priv, clk->id);
1443 		break;
1444 	case HCLK_SDMMC0:
1445 	case HCLK_SDMMC1:
1446 	case CCLK_SDMMC0:
1447 	case CCLK_SDMMC1:
1448 	case SCLK_SDMMC0_SAMPLE:
1449 	case SCLK_SDMMC1_SAMPLE:
1450 		rate = rk3562_sdmmc_get_rate(priv, clk->id);
1451 		break;
1452 	case ACLK_VOP:
1453 	case DCLK_VOP:
1454 	case DCLK_VOP1:
1455 		rate = rk3562_vop_get_rate(priv, clk->id);
1456 		break;
1457 	case CLK_GMAC_125M_CRU_I:
1458 	case CLK_GMAC_50M_CRU_I:
1459 	case CLK_GMAC_ETH_OUT2IO:
1460 	case CLK_MAC100_50M_MATRIX:
1461 		rate = rk3562_gmac_get_rate(priv, clk->id);
1462 		break;
1463 	default:
1464 		return -ENOENT;
1465 	}
1466 
1467 	return rate;
1468 };
1469 
1470 static ulong rk3562_clk_set_rate(struct clk *clk, ulong rate)
1471 {
1472 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1473 	ulong ret = 0;
1474 
1475 	if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) {
1476 		printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n",
1477 		       __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz);
1478 		return -ENOENT;
1479 	}
1480 
1481 	debug("%s: id=%ld, rate=%ld\n", __func__, clk->id, rate);
1482 
1483 	switch (clk->id) {
1484 	case PLL_APLL:
1485 	case ARMCLK:
1486 		if (priv->armclk_hz)
1487 			rk3562_armclk_set_rate(priv, rate);
1488 		priv->armclk_hz = rate;
1489 		break;
1490 	case PLL_GPLL:
1491 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru,
1492 					    GPLL, rate);
1493 		priv->gpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL],
1494 						      priv->cru, GPLL);
1495 		break;
1496 	case PLL_VPLL:
1497 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru,
1498 					    VPLL, rate);
1499 		priv->vpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL],
1500 						      priv->cru, VPLL);
1501 		break;
1502 	case PLL_HPLL:
1503 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru,
1504 					    HPLL, rate);
1505 		priv->hpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL],
1506 						      priv->cru, HPLL);
1507 		break;
1508 	case ACLK_BUS:
1509 	case HCLK_BUS:
1510 	case PCLK_BUS:
1511 		ret = rk3562_bus_set_rate(priv, clk->id, rate);
1512 		break;
1513 	case ACLK_PERI:
1514 	case HCLK_PERI:
1515 	case PCLK_PERI:
1516 		ret = rk3562_peri_set_rate(priv, clk->id, rate);
1517 		break;
1518 	case CLK_PMU0_I2C0:
1519 	case CLK_I2C:
1520 	case CLK_I2C1:
1521 	case CLK_I2C2:
1522 	case CLK_I2C3:
1523 	case CLK_I2C4:
1524 	case CLK_I2C5:
1525 		ret = rk3562_i2c_set_rate(priv, clk->id, rate);
1526 		break;
1527 	case SCLK_PMU1_UART0:
1528 	case SCLK_UART1:
1529 	case SCLK_UART2:
1530 	case SCLK_UART3:
1531 	case SCLK_UART4:
1532 	case SCLK_UART5:
1533 	case SCLK_UART6:
1534 	case SCLK_UART7:
1535 	case SCLK_UART8:
1536 	case SCLK_UART9:
1537 		ret = rk3562_uart_set_rate(priv, clk->id, rate);
1538 		break;
1539 	case CLK_PMU1_PWM0:
1540 	case CLK_PWM1_PERI:
1541 	case CLK_PWM2_PERI:
1542 	case CLK_PWM3_PERI:
1543 		ret = rk3562_pwm_set_rate(priv, clk->id, rate);
1544 		break;
1545 	case CLK_PMU1_SPI0:
1546 	case CLK_SPI1:
1547 	case CLK_SPI2:
1548 		ret = rk3562_spi_set_rate(priv, clk->id, rate);
1549 		break;
1550 	case CLK_TSADC:
1551 	case CLK_TSADC_TSEN:
1552 		ret = rk3562_tsadc_set_rate(priv, clk->id, rate);
1553 		break;
1554 	case CLK_SARADC:
1555 	case CLK_SARADC_VCCIO156:
1556 		ret = rk3562_saradc_set_rate(priv, clk->id, rate);
1557 		break;
1558 	case SCLK_SFC:
1559 		ret = rk3562_sfc_set_rate(priv, rate);
1560 		break;
1561 	case CCLK_EMMC:
1562 	case BCLK_EMMC:
1563 		ret = rk3562_emmc_set_rate(priv, clk->id, rate);
1564 		break;
1565 	case HCLK_SDMMC0:
1566 	case HCLK_SDMMC1:
1567 	case CCLK_SDMMC0:
1568 	case CCLK_SDMMC1:
1569 		ret = rk3562_sdmmc_set_rate(priv, clk->id, rate);
1570 		break;
1571 	case ACLK_VOP:
1572 	case DCLK_VOP:
1573 	case DCLK_VOP1:
1574 		ret = rk3562_vop_set_rate(priv, clk->id, rate);
1575 		break;
1576 	case CLK_GMAC_125M_CRU_I:
1577 	case CLK_GMAC_50M_CRU_I:
1578 	case CLK_GMAC_ETH_OUT2IO:
1579 	case CLK_MAC100_50M_MATRIX:
1580 		ret = rk3562_gmac_set_rate(priv, clk->id, rate);
1581 		break;
1582 	default:
1583 		return -ENOENT;
1584 	}
1585 
1586 	return ret;
1587 };
1588 
1589 #define ROCKCHIP_MMC_DELAY_SEL		BIT(11)
1590 #define ROCKCHIP_MMC_DEGREE_SHIFT	1
1591 #define ROCKCHIP_MMC_DEGREE_MASK	(0x3 << ROCKCHIP_MMC_DEGREE_SHIFT)
1592 #define ROCKCHIP_MMC_DELAYNUM_SHIFT	3
1593 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_SHIFT)
1594 #define PSECS_PER_SEC 1000000000000LL
1595 
1596 /*
1597  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1598  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1599  */
1600 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1601 
1602 int rk3562_mmc_get_phase(struct clk *clk)
1603 {
1604 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1605 	struct rk3562_cru *cru = priv->cru;
1606 	u32 raw_value, delay_num;
1607 	u16 degrees = 0;
1608 	ulong rate;
1609 
1610 	rate = rk3562_clk_get_rate(clk);
1611 	if (rate < 0)
1612 		return rate;
1613 
1614 	if (clk->id == SCLK_SDMMC0_SAMPLE)
1615 		raw_value = readl(&cru->sdmmc0_con[1]);
1616 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
1617 		raw_value = readl(&cru->sdmmc1_con[1]);
1618 	else
1619 		return -ENONET;
1620 
1621 	raw_value &= ROCKCHIP_MMC_DEGREE_MASK;
1622 	degrees = (raw_value >>  ROCKCHIP_MMC_DEGREE_SHIFT) * 90;
1623 
1624 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1625 		/* degrees/delaynum * 10000 */
1626 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1627 					36 * (rate / 1000000);
1628 
1629 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1630 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_SHIFT;
1631 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1632 	}
1633 
1634 	return degrees % 360;
1635 }
1636 
1637 int rk3562_mmc_set_phase(struct clk *clk, u32 degrees)
1638 {
1639 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1640 	struct rk3562_cru *cru = priv->cru;
1641 	u8 nineties, remainder, delay_num;
1642 	u32 raw_value, delay;
1643 	ulong rate;
1644 
1645 	rate = rk3562_clk_get_rate(clk);
1646 	if (rate < 0)
1647 		return rate;
1648 
1649 	nineties = degrees / 90;
1650 	remainder = (degrees % 90);
1651 
1652 	/*
1653 	 * Convert to delay; do a little extra work to make sure we
1654 	 * don't overflow 32-bit / 64-bit numbers.
1655 	 */
1656 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1657 	delay *= remainder;
1658 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1659 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1660 
1661 	delay_num = (u8)min_t(u32, delay, 255);
1662 
1663 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1664 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_SHIFT;
1665 	raw_value |= nineties << ROCKCHIP_MMC_DEGREE_SHIFT;
1666 
1667 	if (clk->id == SCLK_SDMMC0_SAMPLE)
1668 		writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]);
1669 	else
1670 		writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]);
1671 
1672 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1673 	      degrees, delay_num, raw_value, rk3562_mmc_get_phase(clk));
1674 
1675 	return 0;
1676 }
1677 
1678 static int rk3562_clk_get_phase(struct clk *clk)
1679 {
1680 	int ret;
1681 
1682 	switch (clk->id) {
1683 	case SCLK_SDMMC0_SAMPLE:
1684 	case SCLK_SDMMC1_SAMPLE:
1685 		ret = rk3562_mmc_get_phase(clk);
1686 		break;
1687 	default:
1688 		return -ENOENT;
1689 	}
1690 
1691 	return ret;
1692 }
1693 
1694 static int rk3562_clk_set_phase(struct clk *clk, int degrees)
1695 {
1696 	int ret;
1697 
1698 	switch (clk->id) {
1699 	case SCLK_SDMMC0_SAMPLE:
1700 	case SCLK_SDMMC1_SAMPLE:
1701 		ret = rk3562_mmc_set_phase(clk, degrees);
1702 		break;
1703 	default:
1704 		return -ENOENT;
1705 	}
1706 
1707 	return ret;
1708 }
1709 
1710 static struct clk_ops rk3562_clk_ops = {
1711 	.get_rate = rk3562_clk_get_rate,
1712 	.set_rate = rk3562_clk_set_rate,
1713 	.get_phase = rk3562_clk_get_phase,
1714 	.set_phase = rk3562_clk_set_phase,
1715 };
1716 
1717 #ifndef CONFIG_SPL_BUILD
1718 /**
1719  * soc_clk_dump() - Print clock frequencies
1720  * Returns zero on success
1721  *
1722  * Implementation for the clk dump command.
1723  */
1724 int soc_clk_dump(void)
1725 {
1726 	const struct rk3562_clk_info *clk_dump;
1727 	struct rk3562_clk_priv *priv;
1728 	struct udevice *cru_dev;
1729 	struct clk clk;
1730 	ulong clk_count = ARRAY_SIZE(clks_dump);
1731 	ulong rate;
1732 	int i, ret;
1733 
1734 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1735 					  DM_GET_DRIVER(rockchip_rk3562_cru),
1736 					  &cru_dev);
1737 	if (ret) {
1738 		printf("%s failed to get cru device\n", __func__);
1739 		return ret;
1740 	}
1741 
1742 	priv = dev_get_priv(cru_dev);
1743 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1744 	       priv->sync_kernel ? "sync kernel" : "uboot",
1745 	       priv->armclk_enter_hz / 1000,
1746 	       priv->armclk_init_hz / 1000,
1747 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1748 	       priv->set_armclk_rate ? " KHz" : "N/A");
1749 	for (i = 0; i < clk_count; i++) {
1750 		clk_dump = &clks_dump[i];
1751 		if (clk_dump->name) {
1752 			clk.id = clk_dump->id;
1753 			ret = clk_request(cru_dev, &clk);
1754 			if (ret < 0)
1755 				return ret;
1756 
1757 			rate = clk_get_rate(&clk);
1758 			clk_free(&clk);
1759 			if (i == 0) {
1760 				if (rate < 0)
1761 					printf("  %s %s\n", clk_dump->name,
1762 					       "unknown");
1763 				else
1764 					printf("  %s %lu KHz\n", clk_dump->name,
1765 					       rate / 1000);
1766 			} else {
1767 				if (rate < 0)
1768 					printf("  %s %s\n", clk_dump->name,
1769 					       "unknown");
1770 				else
1771 					printf("  %s %lu KHz\n", clk_dump->name,
1772 					       rate / 1000);
1773 			}
1774 		}
1775 	}
1776 
1777 	return 0;
1778 }
1779 #endif
1780 
1781 static void rk3562_clk_init(struct rk3562_clk_priv *priv)
1782 {
1783 	int ret;
1784 
1785 	priv->sync_kernel = false;
1786 	if (!priv->armclk_enter_hz)
1787 		priv->armclk_enter_hz =
1788 			rockchip_pll_get_rate(&rk3562_pll_clks[APLL],
1789 					      priv->cru, APLL);
1790 
1791 	if (!priv->armclk_init_hz) {
1792 #ifdef CONFIG_SPL_BUILD
1793 		ret = rk3562_armclk_set_rate(priv, APLL_HZ);
1794 		if (!ret)
1795 			priv->armclk_init_hz = APLL_HZ;
1796 
1797 #else
1798 		struct clk clk;
1799 
1800 		ret = rockchip_get_scmi_clk(&clk.dev);
1801 		if (ret) {
1802 			printf("Failed to get scmi clk dev\n");
1803 			return;
1804 		}
1805 
1806 		clk.id = ARMCLK;
1807 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
1808 		if (ret < 0) {
1809 			printf("Failed to set scmi cpu %dhz\n", CPU_PVTPLL_HZ);
1810 			return;
1811 		} else {
1812 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
1813 		}
1814 #endif
1815 	}
1816 	if (priv->cpll_hz != CPLL_HZ) {
1817 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[CPLL], priv->cru,
1818 					    CPLL, CPLL_HZ);
1819 		if (!ret)
1820 			priv->cpll_hz = CPLL_HZ;
1821 	}
1822 
1823 	if (priv->gpll_hz != GPLL_HZ) {
1824 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru,
1825 					    GPLL, GPLL_HZ);
1826 		if (!ret)
1827 			priv->gpll_hz = GPLL_HZ;
1828 	}
1829 
1830 	if (priv->hpll_hz != HPLL_HZ) {
1831 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru,
1832 					    HPLL, HPLL_HZ);
1833 		if (!ret)
1834 			priv->hpll_hz = HPLL_HZ;
1835 	}
1836 }
1837 
1838 static int rk3562_clk_probe(struct udevice *dev)
1839 {
1840 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
1841 	int ret;
1842 
1843 	rk3562_clk_init(priv);
1844 
1845 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1846 	ret = clk_set_defaults(dev);
1847 	if (ret)
1848 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1849 	else
1850 		priv->sync_kernel = true;
1851 
1852 	return 0;
1853 }
1854 
1855 static int rk3562_clk_ofdata_to_platdata(struct udevice *dev)
1856 {
1857 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
1858 
1859 	priv->cru = dev_read_addr_ptr(dev);
1860 
1861 	return 0;
1862 }
1863 
1864 static int rk3562_clk_bind(struct udevice *dev)
1865 {
1866 	struct udevice *sys_child, *sf_child;
1867 	struct softreset_reg *sf_priv;
1868 	struct sysreset_reg *priv;
1869 	int ret;
1870 
1871 	/* The reset driver does not have a device node, so bind it here */
1872 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1873 				 &sys_child);
1874 	if (ret) {
1875 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1876 	} else {
1877 		priv = malloc(sizeof(struct sysreset_reg));
1878 		priv->glb_srst_fst_value = offsetof(struct rk3562_cru,
1879 						    glb_srst_fst);
1880 		priv->glb_srst_snd_value = offsetof(struct rk3562_cru,
1881 						    glb_srst_snd);
1882 		sys_child->priv = priv;
1883 	}
1884 
1885 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1886 					 dev_ofnode(dev), &sf_child);
1887 	if (ret) {
1888 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1889 	} else {
1890 		sf_priv = malloc(sizeof(struct softreset_reg));
1891 		sf_priv->sf_reset_offset = offsetof(struct rk3562_cru,
1892 						    softrst_con[0]);
1893 		/* (0x30444 - 0x400) / 4 + 1 = 49170 */
1894 		sf_priv->sf_reset_num = 49170;
1895 		sf_child->priv = sf_priv;
1896 	}
1897 
1898 	return 0;
1899 }
1900 
1901 static const struct udevice_id rk3562_clk_ids[] = {
1902 	{ .compatible = "rockchip,rk3562-cru" },
1903 	{ }
1904 };
1905 
1906 U_BOOT_DRIVER(rockchip_rk3562_cru) = {
1907 	.name		= "rockchip_rk3562_cru",
1908 	.id		= UCLASS_CLK,
1909 	.of_match	= rk3562_clk_ids,
1910 	.priv_auto_alloc_size = sizeof(struct rk3562_clk_priv),
1911 	.ofdata_to_platdata = rk3562_clk_ofdata_to_platdata,
1912 	.ops		= &rk3562_clk_ops,
1913 	.bind		= rk3562_clk_bind,
1914 	.probe		= rk3562_clk_probe,
1915 };
1916 
1917 /* spl scmi clk */
1918 #ifdef CONFIG_SPL_BUILD
1919 
1920 static ulong rk3562_crypto_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1921 {
1922 	struct rk3562_cru *cru = priv->cru;
1923 	u32 sel, con;
1924 	ulong rate;
1925 
1926 	con = readl(&cru->periclksel_con[43]);
1927 	switch (clk_id) {
1928 	case CLK_CORE_CRYPTO:
1929 		sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
1930 		       CLK_CORE_CRYPTO_SEL_SHIFT;
1931 		if (sel == CLK_CORE_CRYPTO_SEL_200M)
1932 			rate = 200 * MHz;
1933 		else if (sel == CLK_CORE_CRYPTO_SEL_100M)
1934 			rate = 100 * MHz;
1935 		else
1936 			rate = OSC_HZ;
1937 		break;
1938 	case CLK_PKA_CRYPTO:
1939 		sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
1940 		       CLK_PKA_CRYPTO_SEL_SHIFT;
1941 		if (sel == CLK_PKA_CRYPTO_SEL_300M)
1942 			rate = 300 * MHz;
1943 		else if (sel == CLK_PKA_CRYPTO_SEL_200M)
1944 			rate = 200 * MHz;
1945 		else if (sel == CLK_PKA_CRYPTO_SEL_100M)
1946 			rate = 100 * MHz;
1947 		else
1948 			rate = OSC_HZ;
1949 		break;
1950 	default:
1951 		return -ENOENT;
1952 	}
1953 
1954 	return rate;
1955 }
1956 
1957 static ulong rk3562_crypto_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1958 				    ulong rate)
1959 {
1960 	struct rk3562_cru *cru = priv->cru;
1961 	u32 mask, shift, sel;
1962 
1963 	switch (clk_id) {
1964 	case CLK_CORE_CRYPTO:
1965 		mask = CLK_CORE_CRYPTO_SEL_MASK;
1966 		shift =	CLK_CORE_CRYPTO_SEL_SHIFT;
1967 		if (rate == 200 * MHz)
1968 			sel = CLK_CORE_CRYPTO_SEL_200M;
1969 		else if (rate == 100 * MHz)
1970 			sel = CLK_CORE_CRYPTO_SEL_100M;
1971 		else
1972 			sel = CLK_CORE_CRYPTO_SEL_24M;
1973 		break;
1974 	case CLK_PKA_CRYPTO:
1975 		mask = CLK_PKA_CRYPTO_SEL_MASK;
1976 		shift =	CLK_PKA_CRYPTO_SEL_SHIFT;
1977 		if (rate == 300 * MHz)
1978 			sel = CLK_PKA_CRYPTO_SEL_300M;
1979 		else if (rate == 200 * MHz)
1980 			sel = CLK_PKA_CRYPTO_SEL_200M;
1981 		else if (rate == 100 * MHz)
1982 			sel = CLK_PKA_CRYPTO_SEL_100M;
1983 		else
1984 			sel = CLK_PKA_CRYPTO_SEL_24M;
1985 		break;
1986 	default:
1987 		return -ENOENT;
1988 	}
1989 	rk_clrsetreg(&cru->periclksel_con[43], mask, sel << shift);
1990 
1991 	return rk3562_crypto_get_rate(priv, clk_id);
1992 }
1993 
1994 static ulong rk3562_clk_scmi_get_rate(struct clk *clk)
1995 {
1996 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1997 
1998 	switch (clk->id) {
1999 	case CLK_CORE_CRYPTO:
2000 	case CLK_PKA_CRYPTO:
2001 		return rk3562_crypto_get_rate(priv, clk->id);
2002 	default:
2003 		return -ENOENT;
2004 	}
2005 };
2006 
2007 static ulong rk3562_clk_scmi_set_rate(struct clk *clk, ulong rate)
2008 {
2009 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
2010 
2011 	switch (clk->id) {
2012 	case CLK_CORE_CRYPTO:
2013 	case CLK_PKA_CRYPTO:
2014 		return rk3562_crypto_set_rate(priv, clk->id, rate);
2015 	default:
2016 		return -ENOENT;
2017 	}
2018 	return 0;
2019 };
2020 
2021 static int rk3562_scmi_clk_ofdata_to_platdata(struct udevice *dev)
2022 {
2023 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
2024 
2025 	priv->cru = (struct rk3562_cru *)0xff100000;
2026 
2027 	return 0;
2028 }
2029 
2030 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2031 static const struct clk_ops scmi_clk_ops = {
2032 	.get_rate = rk3562_clk_scmi_get_rate,
2033 	.set_rate = rk3562_clk_scmi_set_rate,
2034 };
2035 
2036 U_BOOT_DRIVER(scmi_clock) = {
2037 	.name = "scmi_clk",
2038 	.id = UCLASS_CLK,
2039 	.ops = &scmi_clk_ops,
2040 	.priv_auto_alloc_size = sizeof(struct rk3562_clk_priv),
2041 	.ofdata_to_platdata = rk3562_scmi_clk_ofdata_to_platdata,
2042 };
2043 #endif
2044