xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1126.c (revision 2a3fb7bb049d69d96f3bc7dae8caa756fdc8a613)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Finley Xiao <finley.xiao@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_rv1126.h>
15 #include <asm/arch/grf_rv1126.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rv1126-cru.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
24 {								\
25 	.rate	= _rate##U,					\
26 	.aclk_div = _aclk_div,					\
27 	.pclk_div = _pclk_div,					\
28 }
29 
30 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
31 
32 static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = {
33 	RV1126_CPUCLK_RATE(1200000000, 1, 5),
34 	RV1126_CPUCLK_RATE(1008000000, 1, 5),
35 	RV1126_CPUCLK_RATE(816000000, 1, 3),
36 	RV1126_CPUCLK_RATE(600000000, 1, 3),
37 	RV1126_CPUCLK_RATE(408000000, 1, 1),
38 };
39 
40 static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
41 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
42 	RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
43 	RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
44 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
45 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
46 	RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
47 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
48 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
49 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
50 	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
51 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
52 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
53 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
54 	RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
55 	RK3036_PLL_RATE(100000000, 1, 100, 6, 4, 1, 0),
56 	{ /* sentinel */ },
57 };
58 
59 static struct rockchip_pll_clock rv1126_pll_clks[] = {
60 	[APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0),
61 		     RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates),
62 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8),
63 		     RV1126_MODE_CON, 2, 10, 0, NULL),
64 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16),
65 		     RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates),
66 	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24),
67 		     RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates),
68 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0),
69 		     RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates),
70 };
71 
72 #ifndef CONFIG_SPL_BUILD
73 #define RV1126_CLK_DUMP(_id, _name, _iscru)	\
74 {						\
75 	.id = _id,				\
76 	.name = _name,				\
77 	.is_cru = _iscru,			\
78 }
79 
80 static const struct rv1126_clk_info clks_dump[] = {
81 	RV1126_CLK_DUMP(PLL_APLL, "apll", true),
82 	RV1126_CLK_DUMP(PLL_DPLL, "dpll", true),
83 	RV1126_CLK_DUMP(PLL_GPLL, "gpll", false),
84 	RV1126_CLK_DUMP(PLL_CPLL, "cpll", true),
85 	RV1126_CLK_DUMP(PLL_HPLL, "hpll", true),
86 	RV1126_CLK_DUMP(ACLK_PDBUS, "aclk_pdbus", true),
87 	RV1126_CLK_DUMP(HCLK_PDBUS, "hclk_pdbus", true),
88 	RV1126_CLK_DUMP(PCLK_PDBUS, "pclk_pdbus", true),
89 	RV1126_CLK_DUMP(ACLK_PDPHP, "aclk_pdphp", true),
90 	RV1126_CLK_DUMP(HCLK_PDPHP, "hclk_pdphp", true),
91 	RV1126_CLK_DUMP(HCLK_PDAUDIO, "hclk_pdaudio", true),
92 	RV1126_CLK_DUMP(HCLK_PDCORE_NIU, "hclk_pdcore", true),
93 	RV1126_CLK_DUMP(PCLK_PDPMU, "pclk_pdpmu", false),
94 };
95 #endif
96 
97 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
98 				  struct rv1126_pmuclk_priv *pmu_priv,
99 				  ulong rate);
100 /*
101  *
102  * rational_best_approximation(31415, 10000,
103  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
104  *
105  * you may look at given_numerator as a fixed point number,
106  * with the fractional part size described in given_denominator.
107  *
108  * for theoretical background, see:
109  * http://en.wikipedia.org/wiki/Continued_fraction
110  */
111 static void rational_best_approximation(unsigned long given_numerator,
112 					unsigned long given_denominator,
113 					unsigned long max_numerator,
114 					unsigned long max_denominator,
115 					unsigned long *best_numerator,
116 					unsigned long *best_denominator)
117 {
118 	unsigned long n, d, n0, d0, n1, d1;
119 
120 	n = given_numerator;
121 	d = given_denominator;
122 	n0 = 0;
123 	d1 = 0;
124 	n1 = 1;
125 	d0 = 1;
126 	for (;;) {
127 		unsigned long t, a;
128 
129 		if (n1 > max_numerator || d1 > max_denominator) {
130 			n1 = n0;
131 			d1 = d0;
132 			break;
133 		}
134 		if (d == 0)
135 			break;
136 		t = d;
137 		a = n / d;
138 		d = n % d;
139 		n = t;
140 		t = n0 + a * n1;
141 		n0 = n1;
142 		n1 = t;
143 		t = d0 + a * d1;
144 		d0 = d1;
145 		d1 = t;
146 	}
147 	*best_numerator = n1;
148 	*best_denominator = d1;
149 }
150 
151 static ulong rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv *priv)
152 {
153 	return rockchip_pll_get_rate(&rv1126_pll_clks[GPLL],
154 				     priv->pmucru, GPLL);
155 }
156 
157 static ulong rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv *pmu_priv, ulong rate)
158 {
159 	struct udevice *cru_dev;
160 	struct rv1126_clk_priv *priv;
161 	int ret;
162 
163 	ret = uclass_get_device_by_driver(UCLASS_CLK,
164 					  DM_GET_DRIVER(rockchip_rv1126_cru),
165 					  &cru_dev);
166 	if (ret) {
167 		printf("%s: could not find cru device\n", __func__);
168 		return ret;
169 	}
170 	priv = dev_get_priv(cru_dev);
171 
172 	if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
173 		printf("%s: failed to set gpll rate %lu\n", __func__, rate);
174 		return -EINVAL;
175 	}
176 	return 0;
177 }
178 
179 static ulong rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv *priv)
180 {
181 	struct rv1126_pmucru *pmucru = priv->pmucru;
182 	unsigned long m, n;
183 	u32 fracdiv;
184 
185 	fracdiv = readl(&pmucru->pmu_clksel_con[13]);
186 	m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK;
187 	m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT;
188 	n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK;
189 	n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT;
190 
191 	return OSC_HZ * m / n;
192 }
193 
194 static ulong rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv *priv,
195 				      ulong rate)
196 {
197 	struct rv1126_pmucru *pmucru = priv->pmucru;
198 	unsigned long m, n, val;
199 
200 	rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
201 		     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
202 
203 	rational_best_approximation(rate, OSC_HZ,
204 				    GENMASK(16 - 1, 0),
205 				    GENMASK(16 - 1, 0),
206 				    &m, &n);
207 	val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n;
208 	writel(val, &pmucru->pmu_clksel_con[13]);
209 
210 	return rv1126_rtc32k_get_pmuclk(priv);
211 }
212 
213 static ulong rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv *priv,
214 				   ulong clk_id)
215 {
216 	struct rv1126_pmucru *pmucru = priv->pmucru;
217 	u32 div, con;
218 
219 	switch (clk_id) {
220 	case CLK_I2C0:
221 		con = readl(&pmucru->pmu_clksel_con[2]);
222 		div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
223 		break;
224 	case CLK_I2C2:
225 		con = readl(&pmucru->pmu_clksel_con[3]);
226 		div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
227 		break;
228 	default:
229 		return -ENOENT;
230 	}
231 
232 	return DIV_TO_RATE(priv->gpll_hz, div);
233 }
234 
235 static ulong rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv *priv,
236 				   ulong clk_id, ulong rate)
237 {
238 	struct rv1126_pmucru *pmucru = priv->pmucru;
239 	int src_clk_div;
240 
241 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
242 	assert(src_clk_div - 1 <= 127);
243 
244 	switch (clk_id) {
245 	case CLK_I2C0:
246 		rk_clrsetreg(&pmucru->pmu_clksel_con[2], CLK_I2C0_DIV_MASK,
247 			     (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
248 		break;
249 	case CLK_I2C2:
250 		rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C2_DIV_MASK,
251 			     (src_clk_div - 1) << CLK_I2C2_DIV_SHIFT);
252 		break;
253 	default:
254 		return -ENOENT;
255 	}
256 
257 	return rv1126_i2c_get_pmuclk(priv, clk_id);
258 }
259 
260 static ulong rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv *priv,
261 				   ulong clk_id)
262 {
263 	struct rv1126_pmucru *pmucru = priv->pmucru;
264 	u32 div, sel, con;
265 
266 	switch (clk_id) {
267 	case CLK_PWM0:
268 		con = readl(&pmucru->pmu_clksel_con[6]);
269 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
270 		div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
271 		if (sel == CLK_PWM0_SEL_XIN24M)
272 			return OSC_HZ;
273 		break;
274 	case CLK_PWM1:
275 		con = readl(&pmucru->pmu_clksel_con[6]);
276 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
277 		div = (con & CLK_PWM1_DIV_MASK) >> CLK_PWM1_DIV_SHIFT;
278 		if (sel == CLK_PWM1_SEL_XIN24M)
279 			return OSC_HZ;
280 		break;
281 	default:
282 		return -ENOENT;
283 	}
284 
285 	return DIV_TO_RATE(priv->gpll_hz, div);
286 }
287 
288 static ulong rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv *priv,
289 				   ulong clk_id, ulong rate)
290 {
291 	struct rv1126_pmucru *pmucru = priv->pmucru;
292 	int src_clk_div;
293 
294 	switch (clk_id) {
295 	case CLK_PWM0:
296 		if (rate == OSC_HZ) {
297 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
298 				     CLK_PWM0_SEL_MASK,
299 				     CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT);
300 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
301 				     CLK_PWM0_DIV_MASK, 0);
302 		} else {
303 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
304 			assert(src_clk_div - 1 <= 127);
305 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
306 				     CLK_PWM0_DIV_MASK,
307 				     (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
308 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
309 				     CLK_PWM0_SEL_MASK,
310 				     CLK_PWM0_SEL_GPLL << CLK_PWM0_SEL_SHIFT);
311 		}
312 		break;
313 	case CLK_PWM1:
314 		if (rate == OSC_HZ) {
315 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
316 				     CLK_PWM1_SEL_MASK,
317 				     CLK_PWM1_SEL_XIN24M << CLK_PWM1_SEL_SHIFT);
318 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
319 				     CLK_PWM1_DIV_MASK, 0);
320 		} else {
321 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
322 			assert(src_clk_div - 1 <= 127);
323 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
324 				     CLK_PWM1_DIV_MASK,
325 				     (src_clk_div - 1) << CLK_PWM1_DIV_SHIFT);
326 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
327 				     CLK_PWM1_SEL_MASK,
328 				     CLK_PWM1_SEL_GPLL << CLK_PWM1_SEL_SHIFT);
329 		}
330 		break;
331 	default:
332 		return -ENOENT;
333 	}
334 
335 	return rv1126_pwm_get_pmuclk(priv, clk_id);
336 }
337 
338 static ulong rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv *priv)
339 {
340 	struct rv1126_pmucru *pmucru = priv->pmucru;
341 	u32 div, con;
342 
343 	con = readl(&pmucru->pmu_clksel_con[9]);
344 	div = (con & CLK_SPI0_DIV_MASK) >> CLK_SPI0_DIV_SHIFT;
345 
346 	return DIV_TO_RATE(priv->gpll_hz, div);
347 }
348 
349 static ulong rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv *priv,
350 				   ulong rate)
351 {
352 	struct rv1126_pmucru *pmucru = priv->pmucru;
353 	int src_clk_div;
354 
355 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
356 	assert(src_clk_div - 1 <= 127);
357 
358 	rk_clrsetreg(&pmucru->pmu_clksel_con[9],
359 		     CLK_SPI0_SEL_MASK | CLK_SPI0_DIV_MASK,
360 		     CLK_SPI0_SEL_GPLL << CLK_SPI0_SEL_SHIFT |
361 		     (src_clk_div - 1) << CLK_SPI0_DIV_SHIFT);
362 
363 	return rv1126_spi_get_pmuclk(priv);
364 }
365 
366 static ulong rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv *priv)
367 {
368 	struct rv1126_pmucru *pmucru = priv->pmucru;
369 	u32 div, con;
370 
371 	con = readl(&pmucru->pmu_clksel_con[1]);
372 	div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
373 
374 	return DIV_TO_RATE(priv->gpll_hz, div);
375 }
376 
377 static ulong rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv *priv,
378 				     ulong rate)
379 {
380 	struct rv1126_pmucru *pmucru = priv->pmucru;
381 	int src_clk_div;
382 
383 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
384 	assert(src_clk_div - 1 <= 31);
385 
386 	rk_clrsetreg(&pmucru->pmu_clksel_con[1],
387 		     PCLK_PDPMU_DIV_MASK,
388 		     (src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT);
389 
390 	return rv1126_pdpmu_get_pmuclk(priv);
391 }
392 
393 static ulong rv1126_pmuclk_get_rate(struct clk *clk)
394 {
395 	struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
396 	ulong rate = 0;
397 
398 	if (!priv->gpll_hz) {
399 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
400 		return -ENOENT;
401 	}
402 
403 	debug("%s %ld\n", __func__, clk->id);
404 	switch (clk->id) {
405 	case PLL_GPLL:
406 		rate = rv1126_gpll_get_pmuclk(priv);
407 		break;
408 	case CLK_RTC32K:
409 		rate = rv1126_rtc32k_get_pmuclk(priv);
410 		break;
411 	case CLK_I2C0:
412 	case CLK_I2C2:
413 		rate = rv1126_i2c_get_pmuclk(priv, clk->id);
414 		break;
415 	case CLK_PWM0:
416 	case CLK_PWM1:
417 		rate = rv1126_pwm_get_pmuclk(priv, clk->id);
418 		break;
419 	case CLK_SPI0:
420 		rate = rv1126_spi_get_pmuclk(priv);
421 		break;
422 	case PCLK_PDPMU:
423 		rate = rv1126_pdpmu_get_pmuclk(priv);
424 		break;
425 	default:
426 		return -ENOENT;
427 	}
428 
429 	return rate;
430 }
431 
432 static ulong rv1126_pmuclk_set_rate(struct clk *clk, ulong rate)
433 {
434 	struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
435 	ulong ret = 0;
436 
437 	if (!priv->gpll_hz) {
438 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
439 		return -ENOENT;
440 	}
441 
442 	debug("%s %ld %ld\n", __func__, clk->id, rate);
443 	switch (clk->id) {
444 	case PLL_GPLL:
445 		ret = rv1126_gpll_set_pmuclk(priv, rate);
446 		break;
447 	case CLK_RTC32K:
448 		ret = rv1126_rtc32k_set_pmuclk(priv, rate);
449 		break;
450 	case CLK_I2C0:
451 	case CLK_I2C2:
452 		ret = rv1126_i2c_set_pmuclk(priv, clk->id, rate);
453 		break;
454 	case CLK_PWM0:
455 	case CLK_PWM1:
456 		ret = rv1126_pwm_set_pmuclk(priv, clk->id, rate);
457 		break;
458 	case CLK_SPI0:
459 		ret = rv1126_spi_set_pmuclk(priv, rate);
460 		break;
461 	case PCLK_PDPMU:
462 		ret = rv1126_pdpmu_set_pmuclk(priv, rate);
463 		break;
464 	default:
465 		return -ENOENT;
466 	}
467 
468 	return ret;
469 }
470 
471 static int rv1126_rtc32k_set_parent(struct clk *clk, struct clk *parent)
472 {
473 	struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
474 	struct rv1126_pmucru *pmucru = priv->pmucru;
475 
476 	if (parent->id == CLK_OSC0_DIV32K)
477 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
478 			     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
479 	else
480 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
481 			     RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
482 
483 	return 0;
484 }
485 
486 static int rv1126_pmuclk_set_parent(struct clk *clk, struct clk *parent)
487 {
488 	switch (clk->id) {
489 	case CLK_RTC32K:
490 		return rv1126_rtc32k_set_parent(clk, parent);
491 	default:
492 		return -ENOENT;
493 	}
494 }
495 static struct clk_ops rv1126_pmuclk_ops = {
496 	.get_rate = rv1126_pmuclk_get_rate,
497 	.set_rate = rv1126_pmuclk_set_rate,
498 	.set_parent = rv1126_pmuclk_set_parent,
499 };
500 
501 static int rv1126_pmuclk_probe(struct udevice *dev)
502 {
503 	struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
504 
505 	priv->gpll_hz =	rv1126_gpll_get_pmuclk(priv);
506 
507 	return 0;
508 }
509 
510 static int rv1126_pmuclk_ofdata_to_platdata(struct udevice *dev)
511 {
512 	struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
513 
514 	priv->pmucru = dev_read_addr_ptr(dev);
515 
516 	return 0;
517 }
518 
519 static int rv1126_pmuclk_bind(struct udevice *dev)
520 {
521 	int ret = 0;
522 	struct udevice *sf_child;
523 	struct softreset_reg *sf_priv;
524 
525 	ret = device_bind_driver_to_node(dev, "rockchip_reset",
526 					 "reset", dev_ofnode(dev),
527 					 &sf_child);
528 	if (ret) {
529 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
530 	} else {
531 		sf_priv = malloc(sizeof(struct softreset_reg));
532 		sf_priv->sf_reset_offset = offsetof(struct rv1126_pmucru,
533 						    pmu_softrst_con[0]);
534 		sf_priv->sf_reset_num = 2;
535 		sf_child->priv = sf_priv;
536 	}
537 
538 	return 0;
539 }
540 
541 static const struct udevice_id rv1126_pmuclk_ids[] = {
542 	{ .compatible = "rockchip,rv1126-pmucru" },
543 	{ }
544 };
545 
546 U_BOOT_DRIVER(rockchip_rv1126_pmucru) = {
547 	.name		= "rockchip_rv1126_pmucru",
548 	.id		= UCLASS_CLK,
549 	.of_match	= rv1126_pmuclk_ids,
550 	.priv_auto_alloc_size = sizeof(struct rv1126_pmuclk_priv),
551 	.ofdata_to_platdata = rv1126_pmuclk_ofdata_to_platdata,
552 	.ops		= &rv1126_pmuclk_ops,
553 	.bind		= rv1126_pmuclk_bind,
554 	.probe		= rv1126_pmuclk_probe,
555 };
556 
557 
558 static int rv1126_armclk_set_clk(struct rv1126_clk_priv *priv, ulong hz)
559 {
560 	struct rv1126_cru *cru = priv->cru;
561 	const struct rockchip_cpu_rate_table *rate;
562 	ulong old_rate;
563 
564 	rate = rockchip_get_cpu_settings(rv1126_cpu_rates, hz);
565 	if (!rate) {
566 		printf("%s unsupported rate\n", __func__);
567 		return -EINVAL;
568 	}
569 
570 	/*
571 	 * set up dependent divisors for DBG and ACLK clocks.
572 	 */
573 	old_rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
574 					 priv->cru, APLL);
575 	if (old_rate > hz) {
576 		if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
577 					  priv->cru, APLL, hz))
578 			return -EINVAL;
579 		rk_clrsetreg(&cru->clksel_con[1],
580 			     CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
581 			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
582 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT);
583 	} else if (old_rate < hz) {
584 		rk_clrsetreg(&cru->clksel_con[1],
585 			     CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
586 			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
587 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT);
588 		if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
589 					  priv->cru, APLL, hz))
590 			return -EINVAL;
591 	}
592 
593 	return 0;
594 }
595 
596 static ulong rv1126_pdcore_get_clk(struct rv1126_clk_priv *priv)
597 {
598 	struct rv1126_cru *cru = priv->cru;
599 	u32 con, div;
600 
601 	con = readl(&cru->clksel_con[0]);
602 	div = (con & CORE_HCLK_DIV_MASK) >> CORE_HCLK_DIV_SHIFT;
603 
604 	return DIV_TO_RATE(priv->gpll_hz, div);
605 }
606 
607 static ulong rv1126_pdcore_set_clk(struct rv1126_clk_priv *priv, ulong rate)
608 {
609 	struct rv1126_cru *cru = priv->cru;
610 	int src_clk_div;
611 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
612 	assert(src_clk_div - 1 <= 31);
613 
614 	rk_clrsetreg(&cru->clksel_con[0], CORE_HCLK_DIV_MASK,
615 		     (src_clk_div - 1) << CORE_HCLK_DIV_SHIFT);
616 
617 	return rv1126_pdcore_get_clk(priv);
618 }
619 
620 static ulong rv1126_pdbus_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
621 {
622 	struct rv1126_cru *cru = priv->cru;
623 	u32 con, div, sel, parent;
624 
625 	switch (clk_id) {
626 	case ACLK_PDBUS:
627 		con = readl(&cru->clksel_con[2]);
628 		div = (con & ACLK_PDBUS_DIV_MASK) >> ACLK_PDBUS_DIV_SHIFT;
629 		sel = (con & ACLK_PDBUS_SEL_MASK) >> ACLK_PDBUS_SEL_SHIFT;
630 		if (sel == ACLK_PDBUS_SEL_GPLL)
631 			parent = priv->gpll_hz;
632 		else if (sel == ACLK_PDBUS_SEL_CPLL)
633 			parent = priv->cpll_hz;
634 		else
635 			return -ENOENT;
636 		break;
637 	case HCLK_PDBUS:
638 		con = readl(&cru->clksel_con[2]);
639 		div = (con & HCLK_PDBUS_DIV_MASK) >> HCLK_PDBUS_DIV_SHIFT;
640 		sel = (con & HCLK_PDBUS_SEL_MASK) >> HCLK_PDBUS_SEL_SHIFT;
641 		if (sel == HCLK_PDBUS_SEL_GPLL)
642 			parent = priv->gpll_hz;
643 		else if (sel == HCLK_PDBUS_SEL_CPLL)
644 			parent = priv->cpll_hz;
645 		else
646 			return -ENOENT;
647 		break;
648 	case PCLK_PDBUS:
649 		con = readl(&cru->clksel_con[3]);
650 		div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT;
651 		sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT;
652 		if (sel == PCLK_PDBUS_SEL_GPLL)
653 			parent = priv->gpll_hz;
654 		else if (sel == PCLK_PDBUS_SEL_CPLL)
655 			parent = priv->cpll_hz;
656 		else
657 			return -ENOENT;
658 		break;
659 	default:
660 		return -ENOENT;
661 	}
662 
663 	return DIV_TO_RATE(parent, div);
664 }
665 
666 static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
667 				  ulong rate)
668 {
669 	struct rv1126_cru *cru = priv->cru;
670 	int src_clk_div;
671 
672 	switch (clk_id) {
673 	case ACLK_PDBUS:
674 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
675 		assert(src_clk_div - 1 <= 31);
676 		rk_clrsetreg(&cru->clksel_con[2],
677 			     ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK,
678 			     ACLK_PDBUS_SEL_CPLL << ACLK_PDBUS_SEL_SHIFT |
679 			     (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT);
680 		break;
681 	case HCLK_PDBUS:
682 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
683 		assert(src_clk_div - 1 <= 31);
684 		rk_clrsetreg(&cru->clksel_con[2],
685 			     HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK,
686 			     HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT |
687 			     (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT);
688 		break;
689 	case PCLK_PDBUS:
690 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
691 		assert(src_clk_div - 1 <= 31);
692 		rk_clrsetreg(&cru->clksel_con[3],
693 			     PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK,
694 			     PCLK_PDBUS_SEL_GPLL << PCLK_PDBUS_SEL_SHIFT |
695 			     (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT);
696 		break;
697 
698 	default:
699 		printf("do not support this pdbus freq\n");
700 		return -EINVAL;
701 	}
702 
703 	return rv1126_pdbus_get_clk(priv, clk_id);
704 }
705 
706 static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
707 {
708 	struct rv1126_cru *cru = priv->cru;
709 	u32 con, div, parent;
710 
711 	switch (clk_id) {
712 	case ACLK_PDPHP:
713 		con = readl(&cru->clksel_con[53]);
714 		div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT;
715 		parent = priv->gpll_hz;
716 		break;
717 	case HCLK_PDPHP:
718 		con = readl(&cru->clksel_con[53]);
719 		div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT;
720 		parent = priv->gpll_hz;
721 		break;
722 	default:
723 		return -ENOENT;
724 	}
725 
726 	return DIV_TO_RATE(parent, div);
727 }
728 
729 static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
730 				  ulong rate)
731 {
732 	struct rv1126_cru *cru = priv->cru;
733 	int src_clk_div;
734 
735 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
736 	assert(src_clk_div - 1 <= 31);
737 
738 	switch (clk_id) {
739 	case ACLK_PDPHP:
740 		rk_clrsetreg(&cru->clksel_con[53],
741 			     ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK,
742 			     ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT |
743 			     (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT);
744 		break;
745 	case HCLK_PDPHP:
746 		rk_clrsetreg(&cru->clksel_con[53],
747 			     HCLK_PDPHP_DIV_MASK,
748 			     (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT);
749 		break;
750 	default:
751 		printf("do not support this pdphp freq\n");
752 		return -EINVAL;
753 	}
754 
755 	return rv1126_pdphp_get_clk(priv, clk_id);
756 }
757 
758 static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv)
759 {
760 	struct rv1126_cru *cru = priv->cru;
761 	u32 con, div;
762 
763 	con = readl(&cru->clksel_con[26]);
764 	div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT;
765 
766 	return DIV_TO_RATE(priv->gpll_hz, div);
767 }
768 
769 static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate)
770 {
771 	struct rv1126_cru *cru = priv->cru;
772 	int src_clk_div;
773 
774 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
775 	assert(src_clk_div - 1 <= 31);
776 
777 	rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK,
778 		     (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT);
779 
780 	return rv1126_pdaudio_get_clk(priv);
781 }
782 
783 static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
784 {
785 	struct rv1126_cru *cru = priv->cru;
786 	u32 div, con;
787 
788 	switch (clk_id) {
789 	case CLK_I2C1:
790 		con = readl(&cru->clksel_con[5]);
791 		div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
792 		break;
793 	case CLK_I2C3:
794 		con = readl(&cru->clksel_con[5]);
795 		div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT;
796 		break;
797 	case CLK_I2C4:
798 		con = readl(&cru->clksel_con[6]);
799 		div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT;
800 		break;
801 	case CLK_I2C5:
802 		con = readl(&cru->clksel_con[6]);
803 		div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT;
804 		break;
805 	default:
806 		return -ENOENT;
807 	}
808 
809 	return DIV_TO_RATE(priv->gpll_hz, div);
810 }
811 
812 static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
813 				ulong rate)
814 {
815 	struct rv1126_cru *cru = priv->cru;
816 	int src_clk_div;
817 
818 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
819 	assert(src_clk_div - 1 <= 127);
820 
821 	switch (clk_id) {
822 	case CLK_I2C1:
823 		rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK,
824 			     (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT);
825 		break;
826 	case CLK_I2C3:
827 		rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK,
828 			     (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT);
829 		break;
830 	case CLK_I2C4:
831 		rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK,
832 			     (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT);
833 		break;
834 	case CLK_I2C5:
835 		rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK,
836 			     (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT);
837 		break;
838 	default:
839 		return -ENOENT;
840 	}
841 
842 	return rv1126_i2c_get_clk(priv, clk_id);
843 }
844 
845 static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv)
846 {
847 	struct rv1126_cru *cru = priv->cru;
848 	u32 div, con;
849 
850 	con = readl(&cru->clksel_con[8]);
851 	div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT;
852 
853 	return DIV_TO_RATE(priv->gpll_hz, div);
854 }
855 
856 static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate)
857 {
858 	struct rv1126_cru *cru = priv->cru;
859 	int src_clk_div;
860 
861 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
862 	assert(src_clk_div - 1 <= 127);
863 
864 	rk_clrsetreg(&cru->clksel_con[8],
865 		     CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK,
866 		     CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT |
867 		     (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT);
868 
869 	return rv1126_spi_get_clk(priv);
870 }
871 
872 static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv)
873 {
874 	struct rv1126_cru *cru = priv->cru;
875 	u32 div, sel, con;
876 
877 	con = readl(&cru->clksel_con[9]);
878 	sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
879 	div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT;
880 	if (sel == CLK_PWM2_SEL_XIN24M)
881 		return OSC_HZ;
882 
883 	return DIV_TO_RATE(priv->gpll_hz, div);
884 }
885 
886 static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate)
887 {
888 	struct rv1126_cru *cru = priv->cru;
889 	int src_clk_div;
890 
891 	if (rate == OSC_HZ) {
892 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
893 			     CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT);
894 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0);
895 	} else {
896 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
897 		assert(src_clk_div - 1 <= 127);
898 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK,
899 			     (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT);
900 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
901 			     CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT);
902 	}
903 
904 	return rv1126_pwm_get_clk(priv);
905 }
906 
907 static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv)
908 {
909 	struct rv1126_cru *cru = priv->cru;
910 	u32 div, con;
911 
912 	con = readl(&cru->clksel_con[20]);
913 	div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
914 
915 	return DIV_TO_RATE(OSC_HZ, div);
916 }
917 
918 static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
919 {
920 	struct rv1126_cru *cru = priv->cru;
921 	int src_clk_div;
922 
923 	src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
924 	assert(src_clk_div - 1 <= 2047);
925 	rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK,
926 		     (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT);
927 
928 	return rv1126_saradc_get_clk(priv);
929 }
930 
931 static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
932 {
933 	struct rv1126_cru *cru = priv->cru;
934 	u32 div, sel, con, parent;
935 
936 	switch (clk_id) {
937 	case CLK_CRYPTO_CORE:
938 		con = readl(&cru->clksel_con[7]);
939 		div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT;
940 		sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT;
941 		if (sel == CLK_CRYPTO_CORE_SEL_GPLL)
942 			parent = priv->gpll_hz;
943 		else if (sel == CLK_CRYPTO_CORE_SEL_CPLL)
944 			parent = priv->cpll_hz;
945 		else
946 			return -ENOENT;
947 		break;
948 	case CLK_CRYPTO_PKA:
949 		con = readl(&cru->clksel_con[7]);
950 		div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT;
951 		sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT;
952 		if (sel == CLK_CRYPTO_PKA_SEL_GPLL)
953 			parent = priv->gpll_hz;
954 		else if (sel == CLK_CRYPTO_PKA_SEL_CPLL)
955 			parent = priv->cpll_hz;
956 		else
957 			return -ENOENT;
958 		break;
959 	case ACLK_CRYPTO:
960 		con = readl(&cru->clksel_con[4]);
961 		div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT;
962 		sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT;
963 		if (sel == ACLK_CRYPTO_SEL_GPLL)
964 			parent = priv->gpll_hz;
965 		else if (sel == ACLK_CRYPTO_SEL_CPLL)
966 			parent = priv->cpll_hz;
967 		else
968 			return -ENOENT;
969 		break;
970 	default:
971 		return -ENOENT;
972 	}
973 
974 	return DIV_TO_RATE(parent, div);
975 }
976 
977 static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
978 				   ulong rate)
979 {
980 	struct rv1126_cru *cru = priv->cru;
981 	int src_clk_div;
982 
983 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
984 	assert(src_clk_div - 1 <= 31);
985 
986 	switch (clk_id) {
987 	case CLK_CRYPTO_CORE:
988 		rk_clrsetreg(&cru->clksel_con[7],
989 			     CLK_CRYPTO_CORE_SEL_MASK |
990 			     CLK_CRYPTO_CORE_DIV_MASK,
991 			     CLK_CRYPTO_CORE_SEL_GPLL <<
992 			     CLK_CRYPTO_CORE_SEL_SHIFT |
993 			     (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT);
994 		break;
995 	case CLK_CRYPTO_PKA:
996 		rk_clrsetreg(&cru->clksel_con[7],
997 			     CLK_CRYPTO_PKA_SEL_MASK |
998 			     CLK_CRYPTO_PKA_DIV_MASK,
999 			     CLK_CRYPTO_PKA_SEL_GPLL <<
1000 			     CLK_CRYPTO_PKA_SEL_SHIFT |
1001 			     (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT);
1002 		break;
1003 	case ACLK_CRYPTO:
1004 		rk_clrsetreg(&cru->clksel_con[4],
1005 			     ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK,
1006 			     ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT |
1007 			     (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT);
1008 		break;
1009 	default:
1010 		return -ENOENT;
1011 	}
1012 
1013 	return rv1126_crypto_get_clk(priv, clk_id);
1014 }
1015 
1016 static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
1017 {
1018 	struct rv1126_cru *cru = priv->cru;
1019 	u32 div, sel, con, con_id;
1020 
1021 	switch (clk_id) {
1022 	case HCLK_SDMMC:
1023 	case CLK_SDMMC:
1024 		con_id = 55;
1025 		break;
1026 	case HCLK_SDIO:
1027 	case CLK_SDIO:
1028 		con_id = 56;
1029 		break;
1030 	case HCLK_EMMC:
1031 	case CLK_EMMC:
1032 	case SCLK_EMMC_SAMPLE:
1033 		con_id = 57;
1034 		break;
1035 	default:
1036 		return -ENOENT;
1037 	}
1038 
1039 	con = readl(&cru->clksel_con[con_id]);
1040 	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
1041 	sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT;
1042 	if (sel == EMMC_SEL_GPLL)
1043 		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
1044 	else if (sel == EMMC_SEL_CPLL)
1045 		return DIV_TO_RATE(priv->cpll_hz, div) / 2;
1046 	else if (sel == EMMC_SEL_XIN24M)
1047 		return DIV_TO_RATE(OSC_HZ, div) / 2;
1048 
1049 	return -ENOENT;
1050 }
1051 
1052 static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
1053 				 ulong rate)
1054 {
1055 	struct rv1126_cru *cru = priv->cru;
1056 	int src_clk_div;
1057 	u32 con_id;
1058 
1059 	switch (clk_id) {
1060 	case HCLK_SDMMC:
1061 	case CLK_SDMMC:
1062 		con_id = 55;
1063 		break;
1064 	case HCLK_SDIO:
1065 	case CLK_SDIO:
1066 		con_id = 56;
1067 		break;
1068 	case HCLK_EMMC:
1069 	case CLK_EMMC:
1070 		con_id = 57;
1071 		break;
1072 	default:
1073 		return -ENOENT;
1074 	}
1075 
1076 	/* Select clk_sdmmc/emmc source from GPLL by default */
1077 	/* mmc clock defaulg div 2 internal, need provide double in cru */
1078 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate);
1079 
1080 	if (src_clk_div > 127) {
1081 		/* use 24MHz source for 400KHz clock */
1082 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate);
1083 		rk_clrsetreg(&cru->clksel_con[con_id],
1084 			     EMMC_SEL_MASK | EMMC_DIV_MASK,
1085 			     EMMC_SEL_XIN24M << EMMC_SEL_SHIFT |
1086 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
1087 	} else {
1088 		rk_clrsetreg(&cru->clksel_con[con_id],
1089 			     EMMC_SEL_MASK | EMMC_DIV_MASK,
1090 			     EMMC_SEL_GPLL << EMMC_SEL_SHIFT |
1091 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
1092 	}
1093 
1094 	return rv1126_mmc_get_clk(priv, clk_id);
1095 }
1096 
1097 static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv)
1098 {
1099 	struct rv1126_cru *cru = priv->cru;
1100 	u32 div, sel, con, parent;
1101 
1102 	con = readl(&cru->clksel_con[58]);
1103 	div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
1104 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1105 	if (sel == SCLK_SFC_SEL_GPLL)
1106 		parent = priv->gpll_hz;
1107 	else if (sel == SCLK_SFC_SEL_CPLL)
1108 		parent = priv->cpll_hz;
1109 	else
1110 		return -ENOENT;
1111 
1112 	return DIV_TO_RATE(parent, div);
1113 }
1114 
1115 static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1116 {
1117 	struct rv1126_cru *cru = priv->cru;
1118 	int src_clk_div;
1119 
1120 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1121 	rk_clrsetreg(&cru->clksel_con[58],
1122 		     SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
1123 		     SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT |
1124 		     (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT);
1125 
1126 	return rv1126_sfc_get_clk(priv);
1127 }
1128 
1129 static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv)
1130 {
1131 	struct rv1126_cru *cru = priv->cru;
1132 	u32 div, sel, con, parent;
1133 
1134 	con = readl(&cru->clksel_con[59]);
1135 	div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT;
1136 	sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT;
1137 	if (sel == CLK_NANDC_SEL_GPLL)
1138 		parent = priv->gpll_hz;
1139 	else if (sel == CLK_NANDC_SEL_CPLL)
1140 		parent = priv->cpll_hz;
1141 	else
1142 		return -ENOENT;
1143 
1144 	return DIV_TO_RATE(parent, div);
1145 }
1146 
1147 static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1148 {
1149 	struct rv1126_cru *cru = priv->cru;
1150 	int src_clk_div;
1151 
1152 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1153 	rk_clrsetreg(&cru->clksel_con[59],
1154 		     CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK,
1155 		     CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT |
1156 		     (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT);
1157 
1158 	return rv1126_nand_get_clk(priv);
1159 }
1160 
1161 static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv)
1162 {
1163 	struct rv1126_cru *cru = priv->cru;
1164 	u32 div, sel, con, parent;
1165 
1166 	con = readl(&cru->clksel_con[45]);
1167 	div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT;
1168 	sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT;
1169 	if (sel == ACLK_PDVO_SEL_GPLL)
1170 		parent = priv->gpll_hz;
1171 	else if (sel == ACLK_PDVO_SEL_CPLL)
1172 		parent = priv->cpll_hz;
1173 	else
1174 		return -ENOENT;
1175 
1176 	return DIV_TO_RATE(parent, div);
1177 }
1178 
1179 static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1180 {
1181 	struct rv1126_cru *cru = priv->cru;
1182 	int src_clk_div;
1183 
1184 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1185 	assert(src_clk_div - 1 <= 31);
1186 	rk_clrsetreg(&cru->clksel_con[45],
1187 		     ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK,
1188 		     ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT |
1189 		     (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT);
1190 
1191 	return rv1126_aclk_vop_get_clk(priv);
1192 }
1193 
1194 static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv)
1195 {
1196 	struct rv1126_cru *cru = priv->cru;
1197 	u32 div, sel, con, parent;
1198 
1199 	con = readl(&cru->clksel_con[47]);
1200 	div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1201 	sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1202 	if (sel == DCLK_VOP_SEL_GPLL)
1203 		parent = priv->gpll_hz;
1204 	else if (sel == DCLK_VOP_SEL_CPLL)
1205 		parent = priv->cpll_hz;
1206 	else
1207 		return -ENOENT;
1208 
1209 	return DIV_TO_RATE(parent, div);
1210 }
1211 
1212 static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1213 {
1214 	struct rv1126_cru *cru = priv->cru;
1215 	ulong pll_rate, now, best_rate = 0;
1216 	u32 i, div, best_div = 0, best_sel = 0;
1217 
1218 	for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1219 		switch (i) {
1220 		case DCLK_VOP_SEL_GPLL:
1221 			pll_rate = priv->gpll_hz;
1222 			break;
1223 		case DCLK_VOP_SEL_CPLL:
1224 			pll_rate = priv->cpll_hz;
1225 			break;
1226 		default:
1227 			printf("do not support this vop pll sel\n");
1228 			return -EINVAL;
1229 		}
1230 
1231 		div = DIV_ROUND_UP(pll_rate, rate);
1232 		if (div > 255)
1233 			continue;
1234 		now = pll_rate / div;
1235 		if (abs(rate - now) < abs(rate - best_rate)) {
1236 			best_rate = now;
1237 			best_div = div;
1238 			best_sel = i;
1239 		}
1240 		debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n",
1241 		      pll_rate, best_rate, best_div, best_sel);
1242 	}
1243 
1244 	if (best_rate) {
1245 		rk_clrsetreg(&cru->clksel_con[47],
1246 			     DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1247 			     best_sel << DCLK_VOP_SEL_SHIFT |
1248 			     (best_div - 1) << DCLK_VOP_DIV_SHIFT);
1249 	} else {
1250 		printf("do not support this vop freq %lu\n", rate);
1251 		return -EINVAL;
1252 	}
1253 
1254 
1255 	return rv1126_dclk_vop_get_clk(priv);
1256 }
1257 
1258 static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv)
1259 {
1260 	struct rv1126_cru *cru = priv->cru;
1261 	u32 div, sel, con, parent;
1262 
1263 	con = readl(&cru->clksel_con[3]);
1264 	div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT;
1265 	sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT;
1266 	if (sel == CLK_SCR1_SEL_GPLL)
1267 		parent = priv->gpll_hz;
1268 	else if (sel == CLK_SCR1_SEL_CPLL)
1269 		parent = priv->cpll_hz;
1270 	else
1271 		return -ENOENT;
1272 
1273 	return DIV_TO_RATE(parent, div);
1274 }
1275 
1276 static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1277 {
1278 	struct rv1126_cru *cru = priv->cru;
1279 	int src_clk_div;
1280 
1281 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1282 	assert(src_clk_div - 1 <= 31);
1283 	rk_clrsetreg(&cru->clksel_con[3],
1284 		     CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK,
1285 		     CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT |
1286 		     (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT);
1287 
1288 	return rv1126_scr1_get_clk(priv);
1289 }
1290 
1291 static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv)
1292 {
1293 	struct rv1126_cru *cru = priv->cru;
1294 	u32 div, sel, con, parent;
1295 
1296 	con = readl(&cru->clksel_con[63]);
1297 	div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
1298 	sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
1299 	if (sel == CLK_GMAC_SRC_SEL_CPLL)
1300 		parent = priv->cpll_hz;
1301 	else if (sel == CLK_GMAC_SRC_SEL_GPLL)
1302 		parent = priv->gpll_hz;
1303 	else
1304 		return -ENOENT;
1305 
1306 	return DIV_TO_RATE(parent, div);
1307 }
1308 
1309 static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1310 {
1311 	struct rv1126_cru *cru = priv->cru;
1312 	int src_clk_div;
1313 
1314 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1315 	assert(src_clk_div - 1 <= 31);
1316 	rk_clrsetreg(&cru->clksel_con[63],
1317 		     CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
1318 		     CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
1319 		     (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
1320 
1321 	return rv1126_gmac_src_get_clk(priv);
1322 }
1323 
1324 static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
1325 {
1326 	struct rv1126_cru *cru = priv->cru;
1327 	u32 div, sel, con, parent;
1328 
1329 	con = readl(&cru->clksel_con[61]);
1330 	div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
1331 	sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
1332 	if (sel == CLK_GMAC_OUT_SEL_CPLL)
1333 		parent = priv->cpll_hz;
1334 	else if (sel == CLK_GMAC_OUT_SEL_GPLL)
1335 		parent = priv->gpll_hz;
1336 	else
1337 		return -ENOENT;
1338 
1339 	return DIV_TO_RATE(parent, div);
1340 }
1341 
1342 static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1343 {
1344 	struct rv1126_cru *cru = priv->cru;
1345 	int src_clk_div;
1346 
1347 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1348 	assert(src_clk_div - 1 <= 31);
1349 	rk_clrsetreg(&cru->clksel_con[61],
1350 		     CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
1351 		     CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
1352 		     (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
1353 
1354 	return rv1126_gmac_out_get_clk(priv);
1355 }
1356 
1357 static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1358 {
1359 	struct rv1126_cru *cru = priv->cru;
1360 	u32 con, sel, div_sel;
1361 
1362 	con = readl(&cru->gmac_con);
1363 	sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
1364 
1365 	if (sel == GMAC_RGMII_MODE) {
1366 		if (rate == 2500000)
1367 			div_sel = RGMII_CLK_DIV50;
1368 		else if (rate == 25000000)
1369 			div_sel = RGMII_CLK_DIV5;
1370 		else
1371 			div_sel = RGMII_CLK_DIV0;
1372 		rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
1373 			     div_sel << RGMII_CLK_SEL_SHIFT);
1374 	} else if (sel == GMAC_RMII_MODE) {
1375 		if (rate == 2500000)
1376 			div_sel = RMII_CLK_DIV20;
1377 		else
1378 			div_sel = RMII_CLK_DIV2;
1379 		rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
1380 			     div_sel << RMII_CLK_SEL_SHIFT);
1381 	}
1382 
1383 	return 0;
1384 }
1385 
1386 static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
1387 {
1388 	struct rv1126_cru *cru = priv->cru;
1389 	u32 div, con, parent;
1390 
1391 	parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
1392 
1393 	con = readl(&cru->clksel_con[63]);
1394 	div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
1395 
1396 	return DIV_TO_RATE(parent, div);
1397 }
1398 
1399 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1400 static ulong rv1126_clk_pdvi_ispp_get_clk(struct rv1126_clk_priv *priv,
1401 					  ulong clk_id)
1402 {
1403 	struct rv1126_cru *cru = priv->cru;
1404 	u32 div, sel, con, parent, con_id;
1405 
1406 	switch (clk_id) {
1407 	case ACLK_PDVI:
1408 		con_id = 49;
1409 		break;
1410 	case ACLK_PDISPP:
1411 		con_id = 68;
1412 		break;
1413 	case CLK_ISPP:
1414 		con_id = 69;
1415 		break;
1416 	default:
1417 		return -ENOENT;
1418 	}
1419 
1420 	con = readl(&cru->clksel_con[con_id]);
1421 	div = (con & ACLK_PDVI_DIV_MASK) >> ACLK_PDVI_DIV_SHIFT;
1422 	sel = (con & ACLK_PDVI_SEL_MASK) >> ACLK_PDVI_SEL_SHIFT;
1423 	if (sel == ACLK_PDVI_SEL_GPLL)
1424 		parent = priv->gpll_hz;
1425 	else if (sel == ACLK_PDVI_SEL_CPLL)
1426 		parent = priv->cpll_hz;
1427 	else if (sel == ACLK_PDVI_SEL_HPLL)
1428 		parent = priv->hpll_hz;
1429 	else
1430 		return -ENOENT;
1431 
1432 	return DIV_TO_RATE(parent, div);
1433 }
1434 
1435 static ulong rv1126_clk_pdvi_ispp_set_clk(struct rv1126_clk_priv *priv,
1436 					  ulong clk_id, ulong rate)
1437 {
1438 	struct rv1126_cru *cru = priv->cru;
1439 	u32 parent, sel, src_clk_div, con_id;
1440 
1441 	switch (clk_id) {
1442 	case ACLK_PDVI:
1443 		con_id = 49;
1444 		break;
1445 	case ACLK_PDISPP:
1446 		con_id = 68;
1447 		break;
1448 	case CLK_ISPP:
1449 		con_id = 69;
1450 		break;
1451 	default:
1452 		return -ENOENT;
1453 	}
1454 
1455 	if (!(priv->cpll_hz % rate)) {
1456 		parent = priv->cpll_hz;
1457 		sel = ACLK_PDVI_SEL_CPLL;
1458 	} else if (!(priv->hpll_hz % rate)) {
1459 		parent = priv->hpll_hz;
1460 		sel = ACLK_PDVI_SEL_HPLL;
1461 	} else {
1462 		parent = priv->gpll_hz;
1463 		sel = ACLK_PDVI_SEL_GPLL;
1464 	}
1465 
1466 	src_clk_div = DIV_ROUND_UP(parent, rate);
1467 	assert(src_clk_div - 1 <= 31);
1468 	rk_clrsetreg(&cru->clksel_con[con_id],
1469 		     ACLK_PDVI_SEL_MASK | ACLK_PDVI_DIV_MASK,
1470 		     sel << ACLK_PDVI_SEL_SHIFT |
1471 		     (src_clk_div - 1) << ACLK_PDVI_DIV_SHIFT);
1472 
1473 	return rv1126_clk_pdvi_ispp_get_clk(priv, clk_id);
1474 }
1475 
1476 static ulong rv1126_clk_isp_get_clk(struct rv1126_clk_priv *priv)
1477 {
1478 	struct rv1126_cru *cru = priv->cru;
1479 	u32 div, sel, con, parent;
1480 
1481 	con = readl(&cru->clksel_con[50]);
1482 	div = (con & CLK_ISP_DIV_MASK) >> CLK_ISP_DIV_SHIFT;
1483 	sel = (con & CLK_ISP_SEL_MASK) >> CLK_ISP_SEL_SHIFT;
1484 	if (sel == CLK_ISP_SEL_GPLL)
1485 		parent = priv->gpll_hz;
1486 	else if (sel == CLK_ISP_SEL_CPLL)
1487 		parent = priv->cpll_hz;
1488 	else if (sel == CLK_ISP_SEL_HPLL)
1489 		parent = priv->hpll_hz;
1490 	else
1491 		return -ENOENT;
1492 
1493 	return DIV_TO_RATE(parent, div);
1494 }
1495 
1496 static ulong rv1126_clk_isp_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1497 {
1498 	struct rv1126_cru *cru = priv->cru;
1499 	u32 parent, sel, src_clk_div;
1500 
1501 	if (!(priv->cpll_hz % rate)) {
1502 		parent = priv->cpll_hz;
1503 		sel = CLK_ISP_SEL_CPLL;
1504 	} else if (!(priv->hpll_hz % rate)) {
1505 		parent = priv->hpll_hz;
1506 		sel = CLK_ISP_SEL_HPLL;
1507 	} else {
1508 		parent = priv->gpll_hz;
1509 		sel = CLK_ISP_SEL_GPLL;
1510 	}
1511 
1512 	src_clk_div = DIV_ROUND_UP(parent, rate);
1513 	assert(src_clk_div - 1 <= 31);
1514 	rk_clrsetreg(&cru->clksel_con[50],
1515 		     CLK_ISP_SEL_MASK | CLK_ISP_DIV_MASK,
1516 		     sel << CLK_ISP_SEL_SHIFT |
1517 		     (src_clk_div - 1) << CLK_ISP_DIV_SHIFT);
1518 
1519 	return rv1126_clk_isp_get_clk(priv);
1520 }
1521 #endif
1522 
1523 static ulong rv1126_dclk_decom_get_clk(struct rv1126_clk_priv *priv)
1524 {
1525 	struct rv1126_cru *cru = priv->cru;
1526 	u32 div, sel, con, parent;
1527 
1528 	con = readl(&cru->clksel_con[25]);
1529 	div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
1530 	sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
1531 	if (sel == DCLK_DECOM_SEL_GPLL)
1532 		parent = priv->gpll_hz;
1533 	else if (sel == DCLK_DECOM_SEL_CPLL)
1534 		parent = priv->cpll_hz;
1535 	else
1536 		return -ENOENT;
1537 
1538 	return DIV_TO_RATE(parent, div);
1539 }
1540 
1541 static ulong rv1126_dclk_decom_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1542 {
1543 	struct rv1126_cru *cru = priv->cru;
1544 	u32 src_clk_div;
1545 
1546 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1547 	assert(src_clk_div - 1 <= 127);
1548 	rk_clrsetreg(&cru->clksel_con[25],
1549 		     DCLK_DECOM_SEL_MASK | DCLK_DECOM_DIV_MASK,
1550 		     DCLK_DECOM_SEL_GPLL << DCLK_DECOM_SEL_SHIFT |
1551 		     (src_clk_div - 1) << DCLK_DECOM_DIV_SHIFT);
1552 
1553 	return rv1126_dclk_decom_get_clk(priv);
1554 }
1555 
1556 static ulong rv1126_clk_get_rate(struct clk *clk)
1557 {
1558 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1559 	ulong rate = 0;
1560 
1561 	if (!priv->gpll_hz) {
1562 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1563 		return -ENOENT;
1564 	}
1565 
1566 	switch (clk->id) {
1567 	case PLL_APLL:
1568 	case ARMCLK:
1569 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru,
1570 					     APLL);
1571 		break;
1572 	case PLL_CPLL:
1573 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru,
1574 					     CPLL);
1575 		break;
1576 	case PLL_HPLL:
1577 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru,
1578 					     HPLL);
1579 		break;
1580 	case PLL_DPLL:
1581 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[DPLL], priv->cru,
1582 					     DPLL);
1583 		break;
1584 	case HCLK_PDCORE_NIU:
1585 		rate = rv1126_pdcore_get_clk(priv);
1586 		break;
1587 	case ACLK_PDBUS:
1588 	case HCLK_PDBUS:
1589 	case PCLK_PDBUS:
1590 		rate = rv1126_pdbus_get_clk(priv, clk->id);
1591 		break;
1592 	case ACLK_PDPHP:
1593 	case HCLK_PDPHP:
1594 		rate = rv1126_pdphp_get_clk(priv, clk->id);
1595 		break;
1596 	case HCLK_PDAUDIO:
1597 		rate = rv1126_pdaudio_get_clk(priv);
1598 		break;
1599 	case CLK_I2C1:
1600 	case CLK_I2C3:
1601 	case CLK_I2C4:
1602 	case CLK_I2C5:
1603 		rate = rv1126_i2c_get_clk(priv, clk->id);
1604 		break;
1605 	case CLK_SPI1:
1606 		rate = rv1126_spi_get_clk(priv);
1607 		break;
1608 	case CLK_PWM2:
1609 		rate = rv1126_pwm_get_clk(priv);
1610 		break;
1611 	case CLK_SARADC:
1612 		rate = rv1126_saradc_get_clk(priv);
1613 		break;
1614 	case CLK_CRYPTO_CORE:
1615 	case CLK_CRYPTO_PKA:
1616 	case ACLK_CRYPTO:
1617 		rate = rv1126_crypto_get_clk(priv, clk->id);
1618 		break;
1619 	case CLK_SDMMC:
1620 	case HCLK_SDMMC:
1621 	case CLK_SDIO:
1622 	case HCLK_SDIO:
1623 	case CLK_EMMC:
1624 	case HCLK_EMMC:
1625 	case SCLK_EMMC_SAMPLE:
1626 		rate = rv1126_mmc_get_clk(priv, clk->id);
1627 		break;
1628 	case SCLK_SFC:
1629 		rate = rv1126_sfc_get_clk(priv);
1630 		break;
1631 	case CLK_NANDC:
1632 		rate = rv1126_nand_get_clk(priv);
1633 		break;
1634 	case ACLK_PDVO:
1635 	case ACLK_VOP:
1636 		rate = rv1126_aclk_vop_get_clk(priv);
1637 		break;
1638 	case DCLK_VOP:
1639 		rate = rv1126_dclk_vop_get_clk(priv);
1640 		break;
1641 	case CLK_SCR1_CORE:
1642 		rate = rv1126_scr1_get_clk(priv);
1643 		break;
1644 	case CLK_GMAC_SRC:
1645 		rate = rv1126_gmac_src_get_clk(priv);
1646 		break;
1647 	case CLK_GMAC_ETHERNET_OUT:
1648 		rate = rv1126_gmac_out_get_clk(priv);
1649 		break;
1650 	case PCLK_GMAC:
1651 		rate = rv1126_pclk_gmac_get_clk(priv);
1652 		break;
1653 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1654 	case CLK_ISP:
1655 		rate = rv1126_clk_isp_get_clk(priv);
1656 		break;
1657 	case ACLK_PDVI:
1658 	case ACLK_PDISPP:
1659 	case CLK_ISPP:
1660 		rate = rv1126_clk_pdvi_ispp_get_clk(priv, clk->id);
1661 		break;
1662 #endif
1663 	case DCLK_DECOM:
1664 		rate = rv1126_dclk_decom_get_clk(priv);
1665 		break;
1666 	default:
1667 		return -ENOENT;
1668 	}
1669 
1670 	return rate;
1671 };
1672 
1673 static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
1674 {
1675 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1676 	ulong ret = 0;
1677 
1678 	if (!priv->gpll_hz) {
1679 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1680 		return -ENOENT;
1681 	}
1682 
1683 	switch (clk->id) {
1684 	case PLL_APLL:
1685 	case ARMCLK:
1686 		if (priv->armclk_hz)
1687 			rv1126_armclk_set_clk(priv, rate);
1688 		priv->armclk_hz = rate;
1689 		break;
1690 	case PLL_CPLL:
1691 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
1692 					    CPLL, rate);
1693 		break;
1694 	case PLL_HPLL:
1695 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
1696 					    HPLL, rate);
1697 		break;
1698 	case ACLK_PDBUS:
1699 	case HCLK_PDBUS:
1700 	case PCLK_PDBUS:
1701 		ret = rv1126_pdbus_set_clk(priv, clk->id, rate);
1702 		break;
1703 	case ACLK_PDPHP:
1704 	case HCLK_PDPHP:
1705 		ret = rv1126_pdphp_set_clk(priv, clk->id, rate);
1706 		break;
1707 	case HCLK_PDCORE_NIU:
1708 		ret = rv1126_pdcore_set_clk(priv, rate);
1709 		break;
1710 	case HCLK_PDAUDIO:
1711 		ret = rv1126_pdaudio_set_clk(priv, rate);
1712 		break;
1713 	case CLK_I2C1:
1714 	case CLK_I2C3:
1715 	case CLK_I2C4:
1716 	case CLK_I2C5:
1717 		ret = rv1126_i2c_set_clk(priv, clk->id, rate);
1718 		break;
1719 	case CLK_SPI1:
1720 		ret = rv1126_spi_set_clk(priv, rate);
1721 		break;
1722 	case CLK_PWM2:
1723 		ret = rv1126_pwm_set_clk(priv, rate);
1724 		break;
1725 	case CLK_SARADC:
1726 		ret = rv1126_saradc_set_clk(priv, rate);
1727 		break;
1728 	case CLK_CRYPTO_CORE:
1729 	case CLK_CRYPTO_PKA:
1730 	case ACLK_CRYPTO:
1731 		ret = rv1126_crypto_set_clk(priv, clk->id, rate);
1732 		break;
1733 	case CLK_SDMMC:
1734 	case HCLK_SDMMC:
1735 	case CLK_SDIO:
1736 	case HCLK_SDIO:
1737 	case CLK_EMMC:
1738 	case HCLK_EMMC:
1739 		ret = rv1126_mmc_set_clk(priv, clk->id, rate);
1740 		break;
1741 	case SCLK_SFC:
1742 		ret = rv1126_sfc_set_clk(priv, rate);
1743 		break;
1744 	case CLK_NANDC:
1745 		ret = rv1126_nand_set_clk(priv, rate);
1746 		break;
1747 	case ACLK_PDVO:
1748 	case ACLK_VOP:
1749 		ret = rv1126_aclk_vop_set_clk(priv, rate);
1750 		break;
1751 	case DCLK_VOP:
1752 		ret = rv1126_dclk_vop_set_clk(priv, rate);
1753 		break;
1754 	case CLK_SCR1_CORE:
1755 		ret = rv1126_scr1_set_clk(priv, rate);
1756 		break;
1757 	case CLK_GMAC_SRC:
1758 		ret = rv1126_gmac_src_set_clk(priv, rate);
1759 		break;
1760 	case CLK_GMAC_ETHERNET_OUT:
1761 		ret = rv1126_gmac_out_set_clk(priv, rate);
1762 		break;
1763 	case CLK_GMAC_TX_RX:
1764 		ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
1765 		break;
1766 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1767 	case CLK_ISP:
1768 		ret = rv1126_clk_isp_set_clk(priv, rate);
1769 		break;
1770 	case ACLK_PDVI:
1771 	case ACLK_PDISPP:
1772 	case CLK_ISPP:
1773 		ret = rv1126_clk_pdvi_ispp_set_clk(priv, clk->id, rate);
1774 		break;
1775 #endif
1776 	case DCLK_DECOM:
1777 		ret = rv1126_dclk_decom_set_clk(priv, rate);
1778 		break;
1779 	default:
1780 		return -ENOENT;
1781 	}
1782 
1783 	return ret;
1784 };
1785 
1786 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1787 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1788 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1789 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1790 
1791 #define PSECS_PER_SEC 1000000000000LL
1792 /*
1793  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1794  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1795  */
1796 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1797 
1798 int rv1126_mmc_get_phase(struct clk *clk)
1799 {
1800 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1801 	struct rv1126_cru *cru = priv->cru;
1802 	u32 raw_value, delay_num;
1803 	u16 degrees = 0;
1804 	ulong rate;
1805 
1806 	rate = rv1126_clk_get_rate(clk);
1807 	if (rate < 0)
1808 		return rate;
1809 
1810 	if (clk->id == SCLK_EMMC_SAMPLE)
1811 		raw_value = readl(&cru->emmc_con[1]);
1812 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1813 		raw_value = readl(&cru->sdmmc_con[1]);
1814 	else
1815 		raw_value = readl(&cru->sdio_con[1]);
1816 
1817 	raw_value >>= 1;
1818 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1819 
1820 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1821 		/* degrees/delaynum * 10000 */
1822 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1823 					36 * (rate / 1000000);
1824 
1825 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1826 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1827 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1828 	}
1829 
1830 	return degrees % 360;
1831 }
1832 
1833 int rv1126_mmc_set_phase(struct clk *clk, u32 degrees)
1834 {
1835 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1836 	struct rv1126_cru *cru = priv->cru;
1837 	u8 nineties, remainder, delay_num;
1838 	u32 raw_value, delay;
1839 	ulong rate;
1840 
1841 	rate = rv1126_clk_get_rate(clk);
1842 	if (rate < 0)
1843 		return rate;
1844 
1845 	nineties = degrees / 90;
1846 	remainder = (degrees % 90);
1847 
1848 	/*
1849 	 * Convert to delay; do a little extra work to make sure we
1850 	 * don't overflow 32-bit / 64-bit numbers.
1851 	 */
1852 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1853 	delay *= remainder;
1854 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1855 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1856 
1857 	delay_num = (u8)min_t(u32, delay, 255);
1858 
1859 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1860 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1861 	raw_value |= nineties;
1862 
1863 	raw_value <<= 1;
1864 	if (clk->id == SCLK_EMMC_SAMPLE)
1865 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1866 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1867 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1868 	else
1869 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1870 
1871 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1872 	      degrees, delay_num, raw_value, rv1126_mmc_get_phase(clk));
1873 
1874 	return 0;
1875 }
1876 
1877 static int rv1126_clk_get_phase(struct clk *clk)
1878 {
1879 	int ret;
1880 
1881 	debug("%s %ld\n", __func__, clk->id);
1882 	switch (clk->id) {
1883 	case SCLK_EMMC_SAMPLE:
1884 	case SCLK_SDMMC_SAMPLE:
1885 	case SCLK_SDIO_SAMPLE:
1886 		ret = rv1126_mmc_get_phase(clk);
1887 		break;
1888 	default:
1889 		return -ENOENT;
1890 	}
1891 
1892 	return ret;
1893 }
1894 
1895 static int rv1126_clk_set_phase(struct clk *clk, int degrees)
1896 {
1897 	int ret;
1898 
1899 	debug("%s %ld\n", __func__, clk->id);
1900 	switch (clk->id) {
1901 	case SCLK_EMMC_SAMPLE:
1902 	case SCLK_SDMMC_SAMPLE:
1903 	case SCLK_SDIO_SAMPLE:
1904 		ret = rv1126_mmc_set_phase(clk, degrees);
1905 		break;
1906 	default:
1907 		return -ENOENT;
1908 	}
1909 
1910 	return ret;
1911 }
1912 
1913 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1914 static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent)
1915 {
1916 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1917 	struct rv1126_grf *grf = priv->grf;
1918 
1919 	if (parent->id == CLK_GMAC_SRC_M0)
1920 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1921 			     GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT);
1922 	else if(parent->id == CLK_GMAC_SRC_M1)
1923 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1924 			     GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT);
1925 
1926 	return 0;
1927 }
1928 
1929 static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent)
1930 {
1931 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1932 	struct rv1126_cru *cru = priv->cru;
1933 
1934 	if (parent->id == CLK_GMAC_DIV)
1935 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1936 			     GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT);
1937 	else
1938 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK,
1939 			     GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT);
1940 
1941 	return 0;
1942 }
1943 
1944 static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
1945 {
1946 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1947 	struct rv1126_cru *cru = priv->cru;
1948 
1949 	if (parent->id == CLK_GMAC_DIV)
1950 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1951 			     GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT);
1952 	else
1953 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK,
1954 			     GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT);
1955 
1956 	return 0;
1957 }
1958 
1959 static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
1960 {
1961 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1962 	struct rv1126_cru *cru = priv->cru;
1963 
1964 	if (parent->id == RGMII_MODE_CLK)
1965 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1966 			     GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
1967 	else
1968 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1969 			     GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
1970 
1971 	return 0;
1972 }
1973 
1974 static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
1975 {
1976 	switch (clk->id) {
1977 	case CLK_GMAC_SRC:
1978 		return rv1126_gmac_src_set_parent(clk, parent);
1979 	case CLK_GMAC_SRC_M0:
1980 		return rv1126_gmac_src_m0_set_parent(clk, parent);
1981 	case CLK_GMAC_SRC_M1:
1982 		return rv1126_gmac_src_m1_set_parent(clk, parent);
1983 	case CLK_GMAC_TX_RX:
1984 		return rv1126_gmac_tx_rx_set_parent(clk, parent);
1985 	default:
1986 		return -ENOENT;
1987 	}
1988 
1989 	return 0;
1990 }
1991 #endif
1992 
1993 static struct clk_ops rv1126_clk_ops = {
1994 	.get_rate = rv1126_clk_get_rate,
1995 	.set_rate = rv1126_clk_set_rate,
1996 	.get_phase = rv1126_clk_get_phase,
1997 	.set_phase = rv1126_clk_set_phase,
1998 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1999 	.set_parent = rv1126_clk_set_parent,
2000 #endif
2001 };
2002 
2003 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
2004 				  struct rv1126_pmuclk_priv *pmu_priv,
2005 				  ulong rate)
2006 {
2007 	ulong emmc_rate, sfc_rate, nandc_rate;
2008 	bool restore = false;
2009 
2010 	if (priv->gpll_hz != OSC_HZ) {
2011 		emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC);
2012 		sfc_rate = rv1126_sfc_get_clk(priv);
2013 		nandc_rate = rv1126_nand_get_clk(priv);
2014 		debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__,
2015 		      emmc_rate, sfc_rate, nandc_rate);
2016 		restore = true;
2017 	}
2018 
2019 	/*
2020 	 * the child div is big enough for gpll 1188MHz,
2021 	 * even maskrom has change some clocks.
2022 	 */
2023 	if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL],
2024 				  pmu_priv->pmucru, GPLL, rate))
2025 		return -EINVAL;
2026 	pmu_priv->gpll_hz = rate;
2027 	priv->gpll_hz = rate;
2028 
2029 	if (restore) {
2030 		rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate);
2031 		rv1126_sfc_set_clk(priv,  sfc_rate);
2032 		rv1126_nand_set_clk(priv, nandc_rate);
2033 	}
2034 
2035 	return 0;
2036 }
2037 
2038 static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate)
2039 {
2040 	struct udevice *pmucru_dev;
2041 	struct rv1126_pmuclk_priv *pmu_priv;
2042 	int ret;
2043 
2044 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2045 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
2046 					  &pmucru_dev);
2047 	if (ret) {
2048 		printf("%s: could not find pmucru device\n", __func__);
2049 		return ret;
2050 	}
2051 	pmu_priv = dev_get_priv(pmucru_dev);
2052 	priv->gpll_hz = pmu_priv->gpll_hz;
2053 
2054 	if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
2055 		printf("%s: failed to set gpll rate %lu\n", __func__, rate);
2056 		return -EINVAL;
2057 	}
2058 
2059 	rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ);
2060 	rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ);
2061 
2062 	return 0;
2063 }
2064 
2065 static void rv1126_clk_init(struct rv1126_clk_priv *priv)
2066 {
2067 	int ret;
2068 
2069 	priv->sync_kernel = false;
2070 	if (!priv->armclk_enter_hz) {
2071 		priv->armclk_enter_hz =
2072 			rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
2073 					      priv->cru, APLL);
2074 		priv->armclk_init_hz = priv->armclk_enter_hz ;
2075 	}
2076 
2077 	if (priv->armclk_init_hz != APLL_HZ) {
2078 		ret = rv1126_armclk_set_clk(priv, APLL_HZ);
2079 		if (!ret)
2080 			priv->armclk_init_hz = APLL_HZ;
2081 	}
2082 	if (priv->cpll_hz != CPLL_HZ) {
2083 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
2084 					    CPLL, CPLL_HZ);
2085 		if (!ret)
2086 			priv->cpll_hz = CPLL_HZ;
2087 	}
2088 	if (priv->hpll_hz != HPLL_HZ) {
2089 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
2090 					    HPLL, HPLL_HZ);
2091 		if (!ret)
2092 			priv->hpll_hz = HPLL_HZ;
2093 	}
2094 	if (priv->gpll_hz != GPLL_HZ)
2095 		rv1126_gpll_set_clk(priv, GPLL_HZ);
2096 
2097 	rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ);
2098 	rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ);
2099 	rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ);
2100 	rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ);
2101 	rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ);
2102 	rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ);
2103 	rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ);
2104 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
2105 	rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDVI, ACLK_PDVI_HZ);
2106 	rv1126_clk_isp_set_clk(priv, CLK_ISP_HZ);
2107 	rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDISPP, ACLK_PDISPP_HZ);
2108 	rv1126_clk_pdvi_ispp_set_clk(priv, CLK_ISPP, CLK_ISPP_HZ);
2109 	rv1126_aclk_vop_set_clk(priv, ACLK_VOP_HZ);
2110 	rv1126_dclk_vop_set_clk(priv, DCLK_VOP_HZ);
2111 #endif
2112 }
2113 
2114 static int rv1126_clk_probe(struct udevice *dev)
2115 {
2116 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
2117 	int ret;
2118 
2119 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2120 	if (IS_ERR(priv->grf))
2121 		return PTR_ERR(priv->grf);
2122 
2123 	rv1126_clk_init(priv);
2124 
2125 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2126 	ret = clk_set_defaults(dev);
2127 	if (ret)
2128 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2129 	else
2130 		priv->sync_kernel = true;
2131 
2132 	return 0;
2133 }
2134 
2135 static int rv1126_clk_ofdata_to_platdata(struct udevice *dev)
2136 {
2137 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
2138 
2139 	priv->cru = dev_read_addr_ptr(dev);
2140 
2141 	return 0;
2142 }
2143 
2144 static int rv1126_clk_bind(struct udevice *dev)
2145 {
2146 	int ret;
2147 	struct udevice *sys_child, *sf_child;
2148 	struct sysreset_reg *priv;
2149 	struct softreset_reg *sf_priv;
2150 
2151 	/* The reset driver does not have a device node, so bind it here */
2152 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2153 				 &sys_child);
2154 	if (ret) {
2155 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2156 	} else {
2157 		priv = malloc(sizeof(struct sysreset_reg));
2158 		priv->glb_srst_fst_value = offsetof(struct rv1126_cru,
2159 						    glb_srst_fst);
2160 		priv->glb_srst_snd_value = offsetof(struct rv1126_cru,
2161 						    glb_srst_snd);
2162 		sys_child->priv = priv;
2163 	}
2164 
2165 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2166 					 dev_ofnode(dev), &sf_child);
2167 	if (ret) {
2168 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2169 	} else {
2170 		sf_priv = malloc(sizeof(struct softreset_reg));
2171 		sf_priv->sf_reset_offset = offsetof(struct rv1126_cru,
2172 						    softrst_con[0]);
2173 		sf_priv->sf_reset_num = 15;
2174 		sf_child->priv = sf_priv;
2175 	}
2176 
2177 	return 0;
2178 }
2179 
2180 static const struct udevice_id rv1126_clk_ids[] = {
2181 	{ .compatible = "rockchip,rv1126-cru" },
2182 	{ }
2183 };
2184 
2185 U_BOOT_DRIVER(rockchip_rv1126_cru) = {
2186 	.name		= "rockchip_rv1126_cru",
2187 	.id		= UCLASS_CLK,
2188 	.of_match	= rv1126_clk_ids,
2189 	.priv_auto_alloc_size = sizeof(struct rv1126_clk_priv),
2190 	.ofdata_to_platdata = rv1126_clk_ofdata_to_platdata,
2191 	.ops		= &rv1126_clk_ops,
2192 	.bind		= rv1126_clk_bind,
2193 	.probe		= rv1126_clk_probe,
2194 };
2195 
2196 #ifndef CONFIG_SPL_BUILD
2197 /**
2198  * soc_clk_dump() - Print clock frequencies
2199  * Returns zero on success
2200  *
2201  * Implementation for the clk dump command.
2202  */
2203 int soc_clk_dump(void)
2204 {
2205 	struct udevice *cru_dev, *pmucru_dev;
2206 	struct rv1126_clk_priv *priv;
2207 	const struct rv1126_clk_info *clk_dump;
2208 	struct clk clk;
2209 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2210 	unsigned long rate;
2211 	int i, ret;
2212 
2213 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2214 					  DM_GET_DRIVER(rockchip_rv1126_cru),
2215 					  &cru_dev);
2216 	if (ret) {
2217 		printf("%s failed to get cru device\n", __func__);
2218 		return ret;
2219 	}
2220 
2221 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2222 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
2223 					  &pmucru_dev);
2224 	if (ret) {
2225 		printf("%s failed to get pmucru device\n", __func__);
2226 		return ret;
2227 	}
2228 
2229 	priv = dev_get_priv(cru_dev);
2230 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2231 	       priv->sync_kernel ? "sync kernel" : "uboot",
2232 	       priv->armclk_enter_hz / 1000,
2233 	       priv->armclk_init_hz / 1000,
2234 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2235 	       priv->set_armclk_rate ? " KHz" : "N/A");
2236 	for (i = 0; i < clk_count; i++) {
2237 		clk_dump = &clks_dump[i];
2238 		if (clk_dump->name) {
2239 			clk.id = clk_dump->id;
2240 			if (clk_dump->is_cru)
2241 				ret = clk_request(cru_dev, &clk);
2242 			else
2243 				ret = clk_request(pmucru_dev, &clk);
2244 			if (ret < 0)
2245 				return ret;
2246 
2247 			rate = clk_get_rate(&clk);
2248 			clk_free(&clk);
2249 			if (i == 0) {
2250 				if (rate < 0)
2251 					printf("  %s %s\n", clk_dump->name,
2252 					       "unknown");
2253 				else
2254 					printf("  %s %lu KHz\n", clk_dump->name,
2255 					       rate / 1000);
2256 			} else {
2257 				if (rate < 0)
2258 					printf("  %s %s\n", clk_dump->name,
2259 					       "unknown");
2260 				else
2261 					printf("  %s %lu KHz\n", clk_dump->name,
2262 					       rate / 1000);
2263 			}
2264 		}
2265 	}
2266 
2267 	return 0;
2268 }
2269 #endif
2270