xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1126.c (revision f36ea2f6e17621c4d9dd97c4dbfab62d03d061df)
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 	case PCLK_WDT:
650 		con = readl(&cru->clksel_con[3]);
651 		div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT;
652 		sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT;
653 		if (sel == PCLK_PDBUS_SEL_GPLL)
654 			parent = priv->gpll_hz;
655 		else if (sel == PCLK_PDBUS_SEL_CPLL)
656 			parent = priv->cpll_hz;
657 		else
658 			return -ENOENT;
659 		break;
660 	default:
661 		return -ENOENT;
662 	}
663 
664 	return DIV_TO_RATE(parent, div);
665 }
666 
667 static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
668 				  ulong rate)
669 {
670 	struct rv1126_cru *cru = priv->cru;
671 	int src_clk_div, clk_sel;
672 
673 	switch (clk_id) {
674 	case ACLK_PDBUS:
675 		if (CPLL_HZ % rate) {
676 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
677 			clk_sel = ACLK_PDBUS_SEL_GPLL;
678 		} else {
679 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
680 			clk_sel = ACLK_PDBUS_SEL_CPLL;
681 		}
682 		assert(src_clk_div - 1 <= 31);
683 		rk_clrsetreg(&cru->clksel_con[2],
684 			     ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK,
685 			     clk_sel << ACLK_PDBUS_SEL_SHIFT |
686 			     (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT);
687 		break;
688 	case HCLK_PDBUS:
689 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
690 		assert(src_clk_div - 1 <= 31);
691 		rk_clrsetreg(&cru->clksel_con[2],
692 			     HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK,
693 			     HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT |
694 			     (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT);
695 		break;
696 	case PCLK_PDBUS:
697 	case PCLK_WDT:
698 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
699 		assert(src_clk_div - 1 <= 31);
700 		rk_clrsetreg(&cru->clksel_con[3],
701 			     PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK,
702 			     PCLK_PDBUS_SEL_GPLL << PCLK_PDBUS_SEL_SHIFT |
703 			     (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT);
704 		break;
705 
706 	default:
707 		printf("do not support this pdbus freq\n");
708 		return -EINVAL;
709 	}
710 
711 	return rv1126_pdbus_get_clk(priv, clk_id);
712 }
713 
714 static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
715 {
716 	struct rv1126_cru *cru = priv->cru;
717 	u32 con, div, parent;
718 
719 	switch (clk_id) {
720 	case ACLK_PDPHP:
721 		con = readl(&cru->clksel_con[53]);
722 		div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT;
723 		parent = priv->gpll_hz;
724 		break;
725 	case HCLK_PDPHP:
726 		con = readl(&cru->clksel_con[53]);
727 		div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT;
728 		parent = priv->gpll_hz;
729 		break;
730 	default:
731 		return -ENOENT;
732 	}
733 
734 	return DIV_TO_RATE(parent, div);
735 }
736 
737 static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
738 				  ulong rate)
739 {
740 	struct rv1126_cru *cru = priv->cru;
741 	int src_clk_div;
742 
743 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
744 	assert(src_clk_div - 1 <= 31);
745 
746 	switch (clk_id) {
747 	case ACLK_PDPHP:
748 		rk_clrsetreg(&cru->clksel_con[53],
749 			     ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK,
750 			     ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT |
751 			     (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT);
752 		break;
753 	case HCLK_PDPHP:
754 		rk_clrsetreg(&cru->clksel_con[53],
755 			     HCLK_PDPHP_DIV_MASK,
756 			     (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT);
757 		break;
758 	default:
759 		printf("do not support this pdphp freq\n");
760 		return -EINVAL;
761 	}
762 
763 	return rv1126_pdphp_get_clk(priv, clk_id);
764 }
765 
766 static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv)
767 {
768 	struct rv1126_cru *cru = priv->cru;
769 	u32 con, div;
770 
771 	con = readl(&cru->clksel_con[26]);
772 	div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT;
773 
774 	return DIV_TO_RATE(priv->gpll_hz, div);
775 }
776 
777 static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate)
778 {
779 	struct rv1126_cru *cru = priv->cru;
780 	int src_clk_div;
781 
782 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
783 	assert(src_clk_div - 1 <= 31);
784 
785 	rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK,
786 		     (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT);
787 
788 	return rv1126_pdaudio_get_clk(priv);
789 }
790 
791 static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
792 {
793 	struct rv1126_cru *cru = priv->cru;
794 	u32 div, con;
795 
796 	switch (clk_id) {
797 	case CLK_I2C1:
798 		con = readl(&cru->clksel_con[5]);
799 		div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
800 		break;
801 	case CLK_I2C3:
802 		con = readl(&cru->clksel_con[5]);
803 		div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT;
804 		break;
805 	case CLK_I2C4:
806 		con = readl(&cru->clksel_con[6]);
807 		div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT;
808 		break;
809 	case CLK_I2C5:
810 		con = readl(&cru->clksel_con[6]);
811 		div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT;
812 		break;
813 	default:
814 		return -ENOENT;
815 	}
816 
817 	return DIV_TO_RATE(priv->gpll_hz, div);
818 }
819 
820 static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
821 				ulong rate)
822 {
823 	struct rv1126_cru *cru = priv->cru;
824 	int src_clk_div;
825 
826 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
827 	assert(src_clk_div - 1 <= 127);
828 
829 	switch (clk_id) {
830 	case CLK_I2C1:
831 		rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK,
832 			     (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT);
833 		break;
834 	case CLK_I2C3:
835 		rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK,
836 			     (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT);
837 		break;
838 	case CLK_I2C4:
839 		rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK,
840 			     (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT);
841 		break;
842 	case CLK_I2C5:
843 		rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK,
844 			     (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT);
845 		break;
846 	default:
847 		return -ENOENT;
848 	}
849 
850 	return rv1126_i2c_get_clk(priv, clk_id);
851 }
852 
853 static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv)
854 {
855 	struct rv1126_cru *cru = priv->cru;
856 	u32 div, con;
857 
858 	con = readl(&cru->clksel_con[8]);
859 	div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT;
860 
861 	return DIV_TO_RATE(priv->gpll_hz, div);
862 }
863 
864 static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate)
865 {
866 	struct rv1126_cru *cru = priv->cru;
867 	int src_clk_div;
868 
869 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
870 	assert(src_clk_div - 1 <= 127);
871 
872 	rk_clrsetreg(&cru->clksel_con[8],
873 		     CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK,
874 		     CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT |
875 		     (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT);
876 
877 	return rv1126_spi_get_clk(priv);
878 }
879 
880 static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv)
881 {
882 	struct rv1126_cru *cru = priv->cru;
883 	u32 div, sel, con;
884 
885 	con = readl(&cru->clksel_con[9]);
886 	sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
887 	div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT;
888 	if (sel == CLK_PWM2_SEL_XIN24M)
889 		return OSC_HZ;
890 
891 	return DIV_TO_RATE(priv->gpll_hz, div);
892 }
893 
894 static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate)
895 {
896 	struct rv1126_cru *cru = priv->cru;
897 	int src_clk_div;
898 
899 	if (rate == OSC_HZ) {
900 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
901 			     CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT);
902 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0);
903 	} else {
904 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
905 		assert(src_clk_div - 1 <= 127);
906 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK,
907 			     (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT);
908 		rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
909 			     CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT);
910 	}
911 
912 	return rv1126_pwm_get_clk(priv);
913 }
914 
915 static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv)
916 {
917 	struct rv1126_cru *cru = priv->cru;
918 	u32 div, con;
919 
920 	con = readl(&cru->clksel_con[20]);
921 	div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
922 
923 	return DIV_TO_RATE(OSC_HZ, div);
924 }
925 
926 static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
927 {
928 	struct rv1126_cru *cru = priv->cru;
929 	int src_clk_div;
930 
931 	src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
932 	assert(src_clk_div - 1 <= 2047);
933 	rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK,
934 		     (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT);
935 
936 	return rv1126_saradc_get_clk(priv);
937 }
938 
939 static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
940 {
941 	struct rv1126_cru *cru = priv->cru;
942 	u32 div, sel, con, parent;
943 
944 	switch (clk_id) {
945 	case CLK_CRYPTO_CORE:
946 		con = readl(&cru->clksel_con[7]);
947 		div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT;
948 		sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT;
949 		if (sel == CLK_CRYPTO_CORE_SEL_GPLL)
950 			parent = priv->gpll_hz;
951 		else if (sel == CLK_CRYPTO_CORE_SEL_CPLL)
952 			parent = priv->cpll_hz;
953 		else
954 			return -ENOENT;
955 		break;
956 	case CLK_CRYPTO_PKA:
957 		con = readl(&cru->clksel_con[7]);
958 		div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT;
959 		sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT;
960 		if (sel == CLK_CRYPTO_PKA_SEL_GPLL)
961 			parent = priv->gpll_hz;
962 		else if (sel == CLK_CRYPTO_PKA_SEL_CPLL)
963 			parent = priv->cpll_hz;
964 		else
965 			return -ENOENT;
966 		break;
967 	case ACLK_CRYPTO:
968 		con = readl(&cru->clksel_con[4]);
969 		div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT;
970 		sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT;
971 		if (sel == ACLK_CRYPTO_SEL_GPLL)
972 			parent = priv->gpll_hz;
973 		else if (sel == ACLK_CRYPTO_SEL_CPLL)
974 			parent = priv->cpll_hz;
975 		else
976 			return -ENOENT;
977 		break;
978 	default:
979 		return -ENOENT;
980 	}
981 
982 	return DIV_TO_RATE(parent, div);
983 }
984 
985 static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
986 				   ulong rate)
987 {
988 	struct rv1126_cru *cru = priv->cru;
989 	int src_clk_div;
990 
991 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
992 	assert(src_clk_div - 1 <= 31);
993 
994 	switch (clk_id) {
995 	case CLK_CRYPTO_CORE:
996 		rk_clrsetreg(&cru->clksel_con[7],
997 			     CLK_CRYPTO_CORE_SEL_MASK |
998 			     CLK_CRYPTO_CORE_DIV_MASK,
999 			     CLK_CRYPTO_CORE_SEL_GPLL <<
1000 			     CLK_CRYPTO_CORE_SEL_SHIFT |
1001 			     (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT);
1002 		break;
1003 	case CLK_CRYPTO_PKA:
1004 		rk_clrsetreg(&cru->clksel_con[7],
1005 			     CLK_CRYPTO_PKA_SEL_MASK |
1006 			     CLK_CRYPTO_PKA_DIV_MASK,
1007 			     CLK_CRYPTO_PKA_SEL_GPLL <<
1008 			     CLK_CRYPTO_PKA_SEL_SHIFT |
1009 			     (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT);
1010 		break;
1011 	case ACLK_CRYPTO:
1012 		rk_clrsetreg(&cru->clksel_con[4],
1013 			     ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK,
1014 			     ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT |
1015 			     (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT);
1016 		break;
1017 	default:
1018 		return -ENOENT;
1019 	}
1020 
1021 	return rv1126_crypto_get_clk(priv, clk_id);
1022 }
1023 
1024 static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
1025 {
1026 	struct rv1126_cru *cru = priv->cru;
1027 	u32 div, sel, con, con_id;
1028 
1029 	switch (clk_id) {
1030 	case HCLK_SDMMC:
1031 	case CLK_SDMMC:
1032 		con_id = 55;
1033 		break;
1034 	case HCLK_SDIO:
1035 	case CLK_SDIO:
1036 		con_id = 56;
1037 		break;
1038 	case HCLK_EMMC:
1039 	case CLK_EMMC:
1040 	case SCLK_EMMC_SAMPLE:
1041 		con_id = 57;
1042 		break;
1043 	default:
1044 		return -ENOENT;
1045 	}
1046 
1047 	con = readl(&cru->clksel_con[con_id]);
1048 	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
1049 	sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT;
1050 	if (sel == EMMC_SEL_GPLL)
1051 		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
1052 	else if (sel == EMMC_SEL_CPLL)
1053 		return DIV_TO_RATE(priv->cpll_hz, div) / 2;
1054 	else if (sel == EMMC_SEL_XIN24M)
1055 		return DIV_TO_RATE(OSC_HZ, div) / 2;
1056 
1057 	return -ENOENT;
1058 }
1059 
1060 static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
1061 				 ulong rate)
1062 {
1063 	struct rv1126_cru *cru = priv->cru;
1064 	int src_clk_div;
1065 	u32 con_id;
1066 
1067 	switch (clk_id) {
1068 	case HCLK_SDMMC:
1069 	case CLK_SDMMC:
1070 		con_id = 55;
1071 		break;
1072 	case HCLK_SDIO:
1073 	case CLK_SDIO:
1074 		con_id = 56;
1075 		break;
1076 	case HCLK_EMMC:
1077 	case CLK_EMMC:
1078 		con_id = 57;
1079 		break;
1080 	default:
1081 		return -ENOENT;
1082 	}
1083 
1084 	/* Select clk_sdmmc/emmc source from GPLL by default */
1085 	/* mmc clock defaulg div 2 internal, need provide double in cru */
1086 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate);
1087 
1088 	if (src_clk_div > 127) {
1089 		/* use 24MHz source for 400KHz clock */
1090 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate);
1091 		rk_clrsetreg(&cru->clksel_con[con_id],
1092 			     EMMC_SEL_MASK | EMMC_DIV_MASK,
1093 			     EMMC_SEL_XIN24M << EMMC_SEL_SHIFT |
1094 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
1095 	} else {
1096 		rk_clrsetreg(&cru->clksel_con[con_id],
1097 			     EMMC_SEL_MASK | EMMC_DIV_MASK,
1098 			     EMMC_SEL_GPLL << EMMC_SEL_SHIFT |
1099 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
1100 	}
1101 
1102 	return rv1126_mmc_get_clk(priv, clk_id);
1103 }
1104 
1105 static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv)
1106 {
1107 	struct rv1126_cru *cru = priv->cru;
1108 	u32 div, sel, con, parent;
1109 
1110 	con = readl(&cru->clksel_con[58]);
1111 	div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
1112 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1113 	if (sel == SCLK_SFC_SEL_GPLL)
1114 		parent = priv->gpll_hz;
1115 	else if (sel == SCLK_SFC_SEL_CPLL)
1116 		parent = priv->cpll_hz;
1117 	else
1118 		return -ENOENT;
1119 
1120 	return DIV_TO_RATE(parent, div);
1121 }
1122 
1123 static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1124 {
1125 	struct rv1126_cru *cru = priv->cru;
1126 	int src_clk_div;
1127 
1128 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1129 	rk_clrsetreg(&cru->clksel_con[58],
1130 		     SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
1131 		     SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT |
1132 		     (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT);
1133 
1134 	return rv1126_sfc_get_clk(priv);
1135 }
1136 
1137 static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv)
1138 {
1139 	struct rv1126_cru *cru = priv->cru;
1140 	u32 div, sel, con, parent;
1141 
1142 	con = readl(&cru->clksel_con[59]);
1143 	div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT;
1144 	sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT;
1145 	if (sel == CLK_NANDC_SEL_GPLL)
1146 		parent = priv->gpll_hz;
1147 	else if (sel == CLK_NANDC_SEL_CPLL)
1148 		parent = priv->cpll_hz;
1149 	else
1150 		return -ENOENT;
1151 
1152 	return DIV_TO_RATE(parent, div);
1153 }
1154 
1155 static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1156 {
1157 	struct rv1126_cru *cru = priv->cru;
1158 	int src_clk_div;
1159 
1160 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1161 	rk_clrsetreg(&cru->clksel_con[59],
1162 		     CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK,
1163 		     CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT |
1164 		     (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT);
1165 
1166 	return rv1126_nand_get_clk(priv);
1167 }
1168 
1169 static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv)
1170 {
1171 	struct rv1126_cru *cru = priv->cru;
1172 	u32 div, sel, con, parent;
1173 
1174 	con = readl(&cru->clksel_con[45]);
1175 	div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT;
1176 	sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT;
1177 	if (sel == ACLK_PDVO_SEL_GPLL)
1178 		parent = priv->gpll_hz;
1179 	else if (sel == ACLK_PDVO_SEL_CPLL)
1180 		parent = priv->cpll_hz;
1181 	else
1182 		return -ENOENT;
1183 
1184 	return DIV_TO_RATE(parent, div);
1185 }
1186 
1187 static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1188 {
1189 	struct rv1126_cru *cru = priv->cru;
1190 	int src_clk_div;
1191 
1192 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1193 	assert(src_clk_div - 1 <= 31);
1194 	rk_clrsetreg(&cru->clksel_con[45],
1195 		     ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK,
1196 		     ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT |
1197 		     (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT);
1198 
1199 	return rv1126_aclk_vop_get_clk(priv);
1200 }
1201 
1202 static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv)
1203 {
1204 	struct rv1126_cru *cru = priv->cru;
1205 	u32 div, sel, con, parent;
1206 
1207 	con = readl(&cru->clksel_con[47]);
1208 	div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1209 	sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1210 	if (sel == DCLK_VOP_SEL_GPLL)
1211 		parent = priv->gpll_hz;
1212 	else if (sel == DCLK_VOP_SEL_CPLL)
1213 		parent = priv->cpll_hz;
1214 	else
1215 		return -ENOENT;
1216 
1217 	return DIV_TO_RATE(parent, div);
1218 }
1219 
1220 static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1221 {
1222 	struct rv1126_cru *cru = priv->cru;
1223 	ulong pll_rate, now, best_rate = 0;
1224 	u32 i, div, best_div = 0, best_sel = 0;
1225 
1226 	for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1227 		switch (i) {
1228 		case DCLK_VOP_SEL_GPLL:
1229 			pll_rate = priv->gpll_hz;
1230 			break;
1231 		case DCLK_VOP_SEL_CPLL:
1232 			pll_rate = priv->cpll_hz;
1233 			break;
1234 		default:
1235 			printf("do not support this vop pll sel\n");
1236 			return -EINVAL;
1237 		}
1238 
1239 		div = DIV_ROUND_UP(pll_rate, rate);
1240 		if (div > 255)
1241 			continue;
1242 		now = pll_rate / div;
1243 		if (abs(rate - now) < abs(rate - best_rate)) {
1244 			best_rate = now;
1245 			best_div = div;
1246 			best_sel = i;
1247 		}
1248 		debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n",
1249 		      pll_rate, best_rate, best_div, best_sel);
1250 	}
1251 
1252 	if (best_rate) {
1253 		rk_clrsetreg(&cru->clksel_con[47],
1254 			     DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1255 			     best_sel << DCLK_VOP_SEL_SHIFT |
1256 			     (best_div - 1) << DCLK_VOP_DIV_SHIFT);
1257 	} else {
1258 		printf("do not support this vop freq %lu\n", rate);
1259 		return -EINVAL;
1260 	}
1261 
1262 
1263 	return rv1126_dclk_vop_get_clk(priv);
1264 }
1265 
1266 static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv)
1267 {
1268 	struct rv1126_cru *cru = priv->cru;
1269 	u32 div, sel, con, parent;
1270 
1271 	con = readl(&cru->clksel_con[3]);
1272 	div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT;
1273 	sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT;
1274 	if (sel == CLK_SCR1_SEL_GPLL)
1275 		parent = priv->gpll_hz;
1276 	else if (sel == CLK_SCR1_SEL_CPLL)
1277 		parent = priv->cpll_hz;
1278 	else
1279 		return -ENOENT;
1280 
1281 	return DIV_TO_RATE(parent, div);
1282 }
1283 
1284 static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1285 {
1286 	struct rv1126_cru *cru = priv->cru;
1287 	int src_clk_div;
1288 
1289 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1290 	assert(src_clk_div - 1 <= 31);
1291 	rk_clrsetreg(&cru->clksel_con[3],
1292 		     CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK,
1293 		     CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT |
1294 		     (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT);
1295 
1296 	return rv1126_scr1_get_clk(priv);
1297 }
1298 
1299 static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv)
1300 {
1301 	struct rv1126_cru *cru = priv->cru;
1302 	u32 div, sel, con, parent;
1303 
1304 	con = readl(&cru->clksel_con[63]);
1305 	div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
1306 	sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
1307 	if (sel == CLK_GMAC_SRC_SEL_CPLL)
1308 		parent = priv->cpll_hz;
1309 	else if (sel == CLK_GMAC_SRC_SEL_GPLL)
1310 		parent = priv->gpll_hz;
1311 	else
1312 		return -ENOENT;
1313 
1314 	return DIV_TO_RATE(parent, div);
1315 }
1316 
1317 static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1318 {
1319 	struct rv1126_cru *cru = priv->cru;
1320 	int src_clk_div;
1321 
1322 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1323 	assert(src_clk_div - 1 <= 31);
1324 	rk_clrsetreg(&cru->clksel_con[63],
1325 		     CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
1326 		     CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
1327 		     (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
1328 
1329 	return rv1126_gmac_src_get_clk(priv);
1330 }
1331 
1332 static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
1333 {
1334 	struct rv1126_cru *cru = priv->cru;
1335 	u32 div, sel, con, parent;
1336 
1337 	con = readl(&cru->clksel_con[61]);
1338 	div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
1339 	sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
1340 	if (sel == CLK_GMAC_OUT_SEL_CPLL)
1341 		parent = priv->cpll_hz;
1342 	else if (sel == CLK_GMAC_OUT_SEL_GPLL)
1343 		parent = priv->gpll_hz;
1344 	else
1345 		return -ENOENT;
1346 
1347 	return DIV_TO_RATE(parent, div);
1348 }
1349 
1350 static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1351 {
1352 	struct rv1126_cru *cru = priv->cru;
1353 	int src_clk_div;
1354 
1355 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1356 	assert(src_clk_div - 1 <= 31);
1357 	rk_clrsetreg(&cru->clksel_con[61],
1358 		     CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
1359 		     CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
1360 		     (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
1361 
1362 	return rv1126_gmac_out_get_clk(priv);
1363 }
1364 
1365 static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1366 {
1367 	struct rv1126_cru *cru = priv->cru;
1368 	u32 con, sel, div_sel;
1369 
1370 	con = readl(&cru->gmac_con);
1371 	sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
1372 
1373 	if (sel == GMAC_RGMII_MODE) {
1374 		if (rate == 2500000)
1375 			div_sel = RGMII_CLK_DIV50;
1376 		else if (rate == 25000000)
1377 			div_sel = RGMII_CLK_DIV5;
1378 		else
1379 			div_sel = RGMII_CLK_DIV0;
1380 		rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
1381 			     div_sel << RGMII_CLK_SEL_SHIFT);
1382 	} else if (sel == GMAC_RMII_MODE) {
1383 		if (rate == 2500000)
1384 			div_sel = RMII_CLK_DIV20;
1385 		else
1386 			div_sel = RMII_CLK_DIV2;
1387 		rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
1388 			     div_sel << RMII_CLK_SEL_SHIFT);
1389 	}
1390 
1391 	return 0;
1392 }
1393 
1394 static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
1395 {
1396 	struct rv1126_cru *cru = priv->cru;
1397 	u32 div, con, parent;
1398 
1399 	parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
1400 
1401 	con = readl(&cru->clksel_con[63]);
1402 	div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
1403 
1404 	return DIV_TO_RATE(parent, div);
1405 }
1406 
1407 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1408 static ulong rv1126_clk_pdvi_ispp_get_clk(struct rv1126_clk_priv *priv,
1409 					  ulong clk_id)
1410 {
1411 	struct rv1126_cru *cru = priv->cru;
1412 	u32 div, sel, con, parent, con_id;
1413 
1414 	switch (clk_id) {
1415 	case ACLK_PDVI:
1416 		con_id = 49;
1417 		break;
1418 	case ACLK_PDISPP:
1419 		con_id = 68;
1420 		break;
1421 	case CLK_ISPP:
1422 		con_id = 69;
1423 		break;
1424 	default:
1425 		return -ENOENT;
1426 	}
1427 
1428 	con = readl(&cru->clksel_con[con_id]);
1429 	div = (con & ACLK_PDVI_DIV_MASK) >> ACLK_PDVI_DIV_SHIFT;
1430 	sel = (con & ACLK_PDVI_SEL_MASK) >> ACLK_PDVI_SEL_SHIFT;
1431 	if (sel == ACLK_PDVI_SEL_GPLL)
1432 		parent = priv->gpll_hz;
1433 	else if (sel == ACLK_PDVI_SEL_CPLL)
1434 		parent = priv->cpll_hz;
1435 	else if (sel == ACLK_PDVI_SEL_HPLL)
1436 		parent = priv->hpll_hz;
1437 	else
1438 		return -ENOENT;
1439 
1440 	return DIV_TO_RATE(parent, div);
1441 }
1442 
1443 static ulong rv1126_clk_pdvi_ispp_set_clk(struct rv1126_clk_priv *priv,
1444 					  ulong clk_id, ulong rate)
1445 {
1446 	struct rv1126_cru *cru = priv->cru;
1447 	u32 parent, sel, src_clk_div, con_id;
1448 
1449 	switch (clk_id) {
1450 	case ACLK_PDVI:
1451 		con_id = 49;
1452 		break;
1453 	case ACLK_PDISPP:
1454 		con_id = 68;
1455 		break;
1456 	case CLK_ISPP:
1457 		con_id = 69;
1458 		break;
1459 	default:
1460 		return -ENOENT;
1461 	}
1462 
1463 	if (!(priv->cpll_hz % rate)) {
1464 		parent = priv->cpll_hz;
1465 		sel = ACLK_PDVI_SEL_CPLL;
1466 	} else if (!(priv->hpll_hz % rate)) {
1467 		parent = priv->hpll_hz;
1468 		sel = ACLK_PDVI_SEL_HPLL;
1469 	} else {
1470 		parent = priv->gpll_hz;
1471 		sel = ACLK_PDVI_SEL_GPLL;
1472 	}
1473 
1474 	src_clk_div = DIV_ROUND_UP(parent, rate);
1475 	assert(src_clk_div - 1 <= 31);
1476 	rk_clrsetreg(&cru->clksel_con[con_id],
1477 		     ACLK_PDVI_SEL_MASK | ACLK_PDVI_DIV_MASK,
1478 		     sel << ACLK_PDVI_SEL_SHIFT |
1479 		     (src_clk_div - 1) << ACLK_PDVI_DIV_SHIFT);
1480 
1481 	return rv1126_clk_pdvi_ispp_get_clk(priv, clk_id);
1482 }
1483 
1484 static ulong rv1126_clk_isp_get_clk(struct rv1126_clk_priv *priv)
1485 {
1486 	struct rv1126_cru *cru = priv->cru;
1487 	u32 div, sel, con, parent;
1488 
1489 	con = readl(&cru->clksel_con[50]);
1490 	div = (con & CLK_ISP_DIV_MASK) >> CLK_ISP_DIV_SHIFT;
1491 	sel = (con & CLK_ISP_SEL_MASK) >> CLK_ISP_SEL_SHIFT;
1492 	if (sel == CLK_ISP_SEL_GPLL)
1493 		parent = priv->gpll_hz;
1494 	else if (sel == CLK_ISP_SEL_CPLL)
1495 		parent = priv->cpll_hz;
1496 	else if (sel == CLK_ISP_SEL_HPLL)
1497 		parent = priv->hpll_hz;
1498 	else
1499 		return -ENOENT;
1500 
1501 	return DIV_TO_RATE(parent, div);
1502 }
1503 
1504 static ulong rv1126_clk_isp_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1505 {
1506 	struct rv1126_cru *cru = priv->cru;
1507 	u32 parent, sel, src_clk_div;
1508 
1509 	if (!(priv->cpll_hz % rate)) {
1510 		parent = priv->cpll_hz;
1511 		sel = CLK_ISP_SEL_CPLL;
1512 	} else if (!(priv->hpll_hz % rate)) {
1513 		parent = priv->hpll_hz;
1514 		sel = CLK_ISP_SEL_HPLL;
1515 	} else {
1516 		parent = priv->gpll_hz;
1517 		sel = CLK_ISP_SEL_GPLL;
1518 	}
1519 
1520 	src_clk_div = DIV_ROUND_UP(parent, rate);
1521 	assert(src_clk_div - 1 <= 31);
1522 	rk_clrsetreg(&cru->clksel_con[50],
1523 		     CLK_ISP_SEL_MASK | CLK_ISP_DIV_MASK,
1524 		     sel << CLK_ISP_SEL_SHIFT |
1525 		     (src_clk_div - 1) << CLK_ISP_DIV_SHIFT);
1526 
1527 	return rv1126_clk_isp_get_clk(priv);
1528 }
1529 #endif
1530 
1531 static ulong rv1126_dclk_decom_get_clk(struct rv1126_clk_priv *priv)
1532 {
1533 	struct rv1126_cru *cru = priv->cru;
1534 	u32 div, sel, con, parent;
1535 
1536 	con = readl(&cru->clksel_con[25]);
1537 	div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
1538 	sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
1539 	if (sel == DCLK_DECOM_SEL_GPLL)
1540 		parent = priv->gpll_hz;
1541 	else if (sel == DCLK_DECOM_SEL_CPLL)
1542 		parent = priv->cpll_hz;
1543 	else
1544 		return -ENOENT;
1545 
1546 	return DIV_TO_RATE(parent, div);
1547 }
1548 
1549 static ulong rv1126_dclk_decom_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1550 {
1551 	struct rv1126_cru *cru = priv->cru;
1552 	u32 src_clk_div;
1553 
1554 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1555 	assert(src_clk_div - 1 <= 127);
1556 	rk_clrsetreg(&cru->clksel_con[25],
1557 		     DCLK_DECOM_SEL_MASK | DCLK_DECOM_DIV_MASK,
1558 		     DCLK_DECOM_SEL_GPLL << DCLK_DECOM_SEL_SHIFT |
1559 		     (src_clk_div - 1) << DCLK_DECOM_DIV_SHIFT);
1560 
1561 	return rv1126_dclk_decom_get_clk(priv);
1562 }
1563 
1564 static ulong rv1126_clk_get_rate(struct clk *clk)
1565 {
1566 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1567 	ulong rate = 0;
1568 
1569 	if (!priv->gpll_hz) {
1570 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1571 		return -ENOENT;
1572 	}
1573 
1574 	switch (clk->id) {
1575 	case PLL_APLL:
1576 	case ARMCLK:
1577 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru,
1578 					     APLL);
1579 		break;
1580 	case PLL_CPLL:
1581 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru,
1582 					     CPLL);
1583 		break;
1584 	case PLL_HPLL:
1585 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru,
1586 					     HPLL);
1587 		break;
1588 	case PLL_DPLL:
1589 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[DPLL], priv->cru,
1590 					     DPLL);
1591 		break;
1592 	case HCLK_PDCORE_NIU:
1593 		rate = rv1126_pdcore_get_clk(priv);
1594 		break;
1595 	case ACLK_PDBUS:
1596 	case HCLK_PDBUS:
1597 	case PCLK_PDBUS:
1598 	case PCLK_WDT:
1599 		rate = rv1126_pdbus_get_clk(priv, clk->id);
1600 		break;
1601 	case ACLK_PDPHP:
1602 	case HCLK_PDPHP:
1603 		rate = rv1126_pdphp_get_clk(priv, clk->id);
1604 		break;
1605 	case HCLK_PDAUDIO:
1606 		rate = rv1126_pdaudio_get_clk(priv);
1607 		break;
1608 	case CLK_I2C1:
1609 	case CLK_I2C3:
1610 	case CLK_I2C4:
1611 	case CLK_I2C5:
1612 		rate = rv1126_i2c_get_clk(priv, clk->id);
1613 		break;
1614 	case CLK_SPI1:
1615 		rate = rv1126_spi_get_clk(priv);
1616 		break;
1617 	case CLK_PWM2:
1618 		rate = rv1126_pwm_get_clk(priv);
1619 		break;
1620 	case CLK_SARADC:
1621 		rate = rv1126_saradc_get_clk(priv);
1622 		break;
1623 	case CLK_CRYPTO_CORE:
1624 	case CLK_CRYPTO_PKA:
1625 	case ACLK_CRYPTO:
1626 		rate = rv1126_crypto_get_clk(priv, clk->id);
1627 		break;
1628 	case CLK_SDMMC:
1629 	case HCLK_SDMMC:
1630 	case CLK_SDIO:
1631 	case HCLK_SDIO:
1632 	case CLK_EMMC:
1633 	case HCLK_EMMC:
1634 	case SCLK_EMMC_SAMPLE:
1635 		rate = rv1126_mmc_get_clk(priv, clk->id);
1636 		break;
1637 	case SCLK_SFC:
1638 		rate = rv1126_sfc_get_clk(priv);
1639 		break;
1640 	case CLK_NANDC:
1641 		rate = rv1126_nand_get_clk(priv);
1642 		break;
1643 	case ACLK_PDVO:
1644 	case ACLK_VOP:
1645 		rate = rv1126_aclk_vop_get_clk(priv);
1646 		break;
1647 	case DCLK_VOP:
1648 		rate = rv1126_dclk_vop_get_clk(priv);
1649 		break;
1650 	case CLK_SCR1_CORE:
1651 		rate = rv1126_scr1_get_clk(priv);
1652 		break;
1653 	case CLK_GMAC_SRC:
1654 		rate = rv1126_gmac_src_get_clk(priv);
1655 		break;
1656 	case CLK_GMAC_ETHERNET_OUT:
1657 		rate = rv1126_gmac_out_get_clk(priv);
1658 		break;
1659 	case PCLK_GMAC:
1660 		rate = rv1126_pclk_gmac_get_clk(priv);
1661 		break;
1662 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1663 	case CLK_ISP:
1664 		rate = rv1126_clk_isp_get_clk(priv);
1665 		break;
1666 	case ACLK_PDVI:
1667 	case ACLK_PDISPP:
1668 	case CLK_ISPP:
1669 		rate = rv1126_clk_pdvi_ispp_get_clk(priv, clk->id);
1670 		break;
1671 #endif
1672 	case DCLK_DECOM:
1673 		rate = rv1126_dclk_decom_get_clk(priv);
1674 		break;
1675 	default:
1676 		return -ENOENT;
1677 	}
1678 
1679 	return rate;
1680 };
1681 
1682 static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
1683 {
1684 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1685 	ulong ret = 0;
1686 
1687 	if (!priv->gpll_hz) {
1688 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1689 		return -ENOENT;
1690 	}
1691 
1692 	switch (clk->id) {
1693 	case PLL_APLL:
1694 	case ARMCLK:
1695 		if (priv->armclk_hz)
1696 			rv1126_armclk_set_clk(priv, rate);
1697 		priv->armclk_hz = rate;
1698 		break;
1699 	case PLL_CPLL:
1700 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
1701 					    CPLL, rate);
1702 		break;
1703 	case PLL_HPLL:
1704 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
1705 					    HPLL, rate);
1706 		break;
1707 	case ACLK_PDBUS:
1708 	case HCLK_PDBUS:
1709 	case PCLK_PDBUS:
1710 	case PCLK_WDT:
1711 		ret = rv1126_pdbus_set_clk(priv, clk->id, rate);
1712 		break;
1713 	case ACLK_PDPHP:
1714 	case HCLK_PDPHP:
1715 		ret = rv1126_pdphp_set_clk(priv, clk->id, rate);
1716 		break;
1717 	case HCLK_PDCORE_NIU:
1718 		ret = rv1126_pdcore_set_clk(priv, rate);
1719 		break;
1720 	case HCLK_PDAUDIO:
1721 		ret = rv1126_pdaudio_set_clk(priv, rate);
1722 		break;
1723 	case CLK_I2C1:
1724 	case CLK_I2C3:
1725 	case CLK_I2C4:
1726 	case CLK_I2C5:
1727 		ret = rv1126_i2c_set_clk(priv, clk->id, rate);
1728 		break;
1729 	case CLK_SPI1:
1730 		ret = rv1126_spi_set_clk(priv, rate);
1731 		break;
1732 	case CLK_PWM2:
1733 		ret = rv1126_pwm_set_clk(priv, rate);
1734 		break;
1735 	case CLK_SARADC:
1736 		ret = rv1126_saradc_set_clk(priv, rate);
1737 		break;
1738 	case CLK_CRYPTO_CORE:
1739 	case CLK_CRYPTO_PKA:
1740 	case ACLK_CRYPTO:
1741 		ret = rv1126_crypto_set_clk(priv, clk->id, rate);
1742 		break;
1743 	case CLK_SDMMC:
1744 	case HCLK_SDMMC:
1745 	case CLK_SDIO:
1746 	case HCLK_SDIO:
1747 	case CLK_EMMC:
1748 	case HCLK_EMMC:
1749 		ret = rv1126_mmc_set_clk(priv, clk->id, rate);
1750 		break;
1751 	case SCLK_SFC:
1752 		ret = rv1126_sfc_set_clk(priv, rate);
1753 		break;
1754 	case CLK_NANDC:
1755 		ret = rv1126_nand_set_clk(priv, rate);
1756 		break;
1757 	case ACLK_PDVO:
1758 	case ACLK_VOP:
1759 		ret = rv1126_aclk_vop_set_clk(priv, rate);
1760 		break;
1761 	case DCLK_VOP:
1762 		ret = rv1126_dclk_vop_set_clk(priv, rate);
1763 		break;
1764 	case CLK_SCR1_CORE:
1765 		ret = rv1126_scr1_set_clk(priv, rate);
1766 		break;
1767 	case CLK_GMAC_SRC:
1768 		ret = rv1126_gmac_src_set_clk(priv, rate);
1769 		break;
1770 	case CLK_GMAC_ETHERNET_OUT:
1771 		ret = rv1126_gmac_out_set_clk(priv, rate);
1772 		break;
1773 	case CLK_GMAC_TX_RX:
1774 		ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
1775 		break;
1776 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1777 	case CLK_ISP:
1778 		ret = rv1126_clk_isp_set_clk(priv, rate);
1779 		break;
1780 	case ACLK_PDVI:
1781 	case ACLK_PDISPP:
1782 	case CLK_ISPP:
1783 		ret = rv1126_clk_pdvi_ispp_set_clk(priv, clk->id, rate);
1784 		break;
1785 #endif
1786 	case DCLK_DECOM:
1787 		ret = rv1126_dclk_decom_set_clk(priv, rate);
1788 		break;
1789 	default:
1790 		return -ENOENT;
1791 	}
1792 
1793 	return ret;
1794 };
1795 
1796 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1797 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1798 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1799 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1800 
1801 #define PSECS_PER_SEC 1000000000000LL
1802 /*
1803  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1804  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1805  */
1806 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1807 
1808 int rv1126_mmc_get_phase(struct clk *clk)
1809 {
1810 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1811 	struct rv1126_cru *cru = priv->cru;
1812 	u32 raw_value, delay_num;
1813 	u16 degrees = 0;
1814 	ulong rate;
1815 
1816 	rate = rv1126_clk_get_rate(clk);
1817 	if (rate < 0)
1818 		return rate;
1819 
1820 	if (clk->id == SCLK_EMMC_SAMPLE)
1821 		raw_value = readl(&cru->emmc_con[1]);
1822 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1823 		raw_value = readl(&cru->sdmmc_con[1]);
1824 	else
1825 		raw_value = readl(&cru->sdio_con[1]);
1826 
1827 	raw_value >>= 1;
1828 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1829 
1830 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1831 		/* degrees/delaynum * 10000 */
1832 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1833 					36 * (rate / 1000000);
1834 
1835 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1836 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1837 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1838 	}
1839 
1840 	return degrees % 360;
1841 }
1842 
1843 int rv1126_mmc_set_phase(struct clk *clk, u32 degrees)
1844 {
1845 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1846 	struct rv1126_cru *cru = priv->cru;
1847 	u8 nineties, remainder, delay_num;
1848 	u32 raw_value, delay;
1849 	ulong rate;
1850 
1851 	rate = rv1126_clk_get_rate(clk);
1852 	if (rate < 0)
1853 		return rate;
1854 
1855 	nineties = degrees / 90;
1856 	remainder = (degrees % 90);
1857 
1858 	/*
1859 	 * Convert to delay; do a little extra work to make sure we
1860 	 * don't overflow 32-bit / 64-bit numbers.
1861 	 */
1862 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1863 	delay *= remainder;
1864 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1865 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1866 
1867 	delay_num = (u8)min_t(u32, delay, 255);
1868 
1869 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1870 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1871 	raw_value |= nineties;
1872 
1873 	raw_value <<= 1;
1874 	if (clk->id == SCLK_EMMC_SAMPLE)
1875 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1876 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1877 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1878 	else
1879 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1880 
1881 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1882 	      degrees, delay_num, raw_value, rv1126_mmc_get_phase(clk));
1883 
1884 	return 0;
1885 }
1886 
1887 static int rv1126_clk_get_phase(struct clk *clk)
1888 {
1889 	int ret;
1890 
1891 	debug("%s %ld\n", __func__, clk->id);
1892 	switch (clk->id) {
1893 	case SCLK_EMMC_SAMPLE:
1894 	case SCLK_SDMMC_SAMPLE:
1895 	case SCLK_SDIO_SAMPLE:
1896 		ret = rv1126_mmc_get_phase(clk);
1897 		break;
1898 	default:
1899 		return -ENOENT;
1900 	}
1901 
1902 	return ret;
1903 }
1904 
1905 static int rv1126_clk_set_phase(struct clk *clk, int degrees)
1906 {
1907 	int ret;
1908 
1909 	debug("%s %ld\n", __func__, clk->id);
1910 	switch (clk->id) {
1911 	case SCLK_EMMC_SAMPLE:
1912 	case SCLK_SDMMC_SAMPLE:
1913 	case SCLK_SDIO_SAMPLE:
1914 		ret = rv1126_mmc_set_phase(clk, degrees);
1915 		break;
1916 	default:
1917 		return -ENOENT;
1918 	}
1919 
1920 	return ret;
1921 }
1922 
1923 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1924 static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent)
1925 {
1926 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1927 	struct rv1126_grf *grf = priv->grf;
1928 
1929 	if (parent->id == CLK_GMAC_SRC_M0)
1930 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1931 			     GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT);
1932 	else if(parent->id == CLK_GMAC_SRC_M1)
1933 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1934 			     GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT);
1935 
1936 	return 0;
1937 }
1938 
1939 static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent)
1940 {
1941 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1942 	struct rv1126_cru *cru = priv->cru;
1943 
1944 	if (parent->id == CLK_GMAC_DIV)
1945 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1946 			     GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT);
1947 	else
1948 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1949 			     GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT);
1950 
1951 	return 0;
1952 }
1953 
1954 static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
1955 {
1956 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1957 	struct rv1126_cru *cru = priv->cru;
1958 
1959 	if (parent->id == CLK_GMAC_DIV)
1960 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
1961 			     GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT);
1962 	else
1963 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
1964 			     GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT);
1965 
1966 	return 0;
1967 }
1968 
1969 static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
1970 {
1971 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1972 	struct rv1126_cru *cru = priv->cru;
1973 
1974 	if (parent->id == RGMII_MODE_CLK)
1975 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1976 			     GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
1977 	else
1978 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1979 			     GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
1980 
1981 	return 0;
1982 }
1983 
1984 static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
1985 {
1986 	switch (clk->id) {
1987 	case CLK_GMAC_SRC:
1988 		return rv1126_gmac_src_set_parent(clk, parent);
1989 	case CLK_GMAC_SRC_M0:
1990 		return rv1126_gmac_src_m0_set_parent(clk, parent);
1991 	case CLK_GMAC_SRC_M1:
1992 		return rv1126_gmac_src_m1_set_parent(clk, parent);
1993 	case CLK_GMAC_TX_RX:
1994 		return rv1126_gmac_tx_rx_set_parent(clk, parent);
1995 	default:
1996 		return -ENOENT;
1997 	}
1998 
1999 	return 0;
2000 }
2001 #endif
2002 
2003 static struct clk_ops rv1126_clk_ops = {
2004 	.get_rate = rv1126_clk_get_rate,
2005 	.set_rate = rv1126_clk_set_rate,
2006 	.get_phase = rv1126_clk_get_phase,
2007 	.set_phase = rv1126_clk_set_phase,
2008 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
2009 	.set_parent = rv1126_clk_set_parent,
2010 #endif
2011 };
2012 
2013 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
2014 				  struct rv1126_pmuclk_priv *pmu_priv,
2015 				  ulong rate)
2016 {
2017 	ulong emmc_rate, sfc_rate, nandc_rate;
2018 	bool restore = false;
2019 
2020 	if (priv->gpll_hz != OSC_HZ) {
2021 		emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC);
2022 		sfc_rate = rv1126_sfc_get_clk(priv);
2023 		nandc_rate = rv1126_nand_get_clk(priv);
2024 		debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__,
2025 		      emmc_rate, sfc_rate, nandc_rate);
2026 		restore = true;
2027 	}
2028 
2029 	/*
2030 	 * the child div is big enough for gpll 1188MHz,
2031 	 * even maskrom has change some clocks.
2032 	 */
2033 	if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL],
2034 				  pmu_priv->pmucru, GPLL, rate))
2035 		return -EINVAL;
2036 	pmu_priv->gpll_hz = rate;
2037 	priv->gpll_hz = rate;
2038 
2039 	if (restore) {
2040 		rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate);
2041 		rv1126_sfc_set_clk(priv,  sfc_rate);
2042 		rv1126_nand_set_clk(priv, nandc_rate);
2043 	}
2044 
2045 	return 0;
2046 }
2047 
2048 static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate)
2049 {
2050 	struct udevice *pmucru_dev;
2051 	struct rv1126_pmuclk_priv *pmu_priv;
2052 	int ret;
2053 
2054 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2055 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
2056 					  &pmucru_dev);
2057 	if (ret) {
2058 		printf("%s: could not find pmucru device\n", __func__);
2059 		return ret;
2060 	}
2061 	pmu_priv = dev_get_priv(pmucru_dev);
2062 	priv->gpll_hz = pmu_priv->gpll_hz;
2063 
2064 	if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
2065 		printf("%s: failed to set gpll rate %lu\n", __func__, rate);
2066 		return -EINVAL;
2067 	}
2068 
2069 	rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ);
2070 	rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ);
2071 
2072 	return 0;
2073 }
2074 
2075 static void rv1126_clk_init(struct rv1126_clk_priv *priv)
2076 {
2077 	int ret;
2078 
2079 	priv->sync_kernel = false;
2080 	if (!priv->armclk_enter_hz) {
2081 		priv->armclk_enter_hz =
2082 			rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
2083 					      priv->cru, APLL);
2084 		priv->armclk_init_hz = priv->armclk_enter_hz ;
2085 	}
2086 
2087 	if (priv->armclk_init_hz != APLL_HZ) {
2088 		ret = rv1126_armclk_set_clk(priv, APLL_HZ);
2089 		if (!ret)
2090 			priv->armclk_init_hz = APLL_HZ;
2091 	}
2092 	if (priv->cpll_hz != CPLL_HZ) {
2093 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
2094 					    CPLL, CPLL_HZ);
2095 		if (!ret)
2096 			priv->cpll_hz = CPLL_HZ;
2097 	}
2098 	if (priv->hpll_hz != HPLL_HZ) {
2099 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
2100 					    HPLL, HPLL_HZ);
2101 		if (!ret)
2102 			priv->hpll_hz = HPLL_HZ;
2103 	}
2104 	if (priv->gpll_hz != GPLL_HZ)
2105 		rv1126_gpll_set_clk(priv, GPLL_HZ);
2106 
2107 	rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ);
2108 	rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ);
2109 	rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ);
2110 	rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ);
2111 	rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ);
2112 	rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ);
2113 	rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ);
2114 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
2115 	rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDVI, ACLK_PDVI_HZ);
2116 	rv1126_clk_isp_set_clk(priv, CLK_ISP_HZ);
2117 	rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDISPP, ACLK_PDISPP_HZ);
2118 	rv1126_clk_pdvi_ispp_set_clk(priv, CLK_ISPP, CLK_ISPP_HZ);
2119 	rv1126_aclk_vop_set_clk(priv, ACLK_VOP_HZ);
2120 	rv1126_dclk_vop_set_clk(priv, DCLK_VOP_HZ);
2121 #endif
2122 }
2123 
2124 static int rv1126_clk_probe(struct udevice *dev)
2125 {
2126 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
2127 	int ret;
2128 
2129 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2130 	if (IS_ERR(priv->grf))
2131 		return PTR_ERR(priv->grf);
2132 
2133 	rv1126_clk_init(priv);
2134 
2135 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2136 	ret = clk_set_defaults(dev);
2137 	if (ret)
2138 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2139 	else
2140 		priv->sync_kernel = true;
2141 
2142 	return 0;
2143 }
2144 
2145 static int rv1126_clk_ofdata_to_platdata(struct udevice *dev)
2146 {
2147 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
2148 
2149 	priv->cru = dev_read_addr_ptr(dev);
2150 
2151 	return 0;
2152 }
2153 
2154 static int rv1126_clk_bind(struct udevice *dev)
2155 {
2156 	int ret;
2157 	struct udevice *sys_child, *sf_child;
2158 	struct sysreset_reg *priv;
2159 	struct softreset_reg *sf_priv;
2160 
2161 	/* The reset driver does not have a device node, so bind it here */
2162 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2163 				 &sys_child);
2164 	if (ret) {
2165 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2166 	} else {
2167 		priv = malloc(sizeof(struct sysreset_reg));
2168 		priv->glb_srst_fst_value = offsetof(struct rv1126_cru,
2169 						    glb_srst_fst);
2170 		priv->glb_srst_snd_value = offsetof(struct rv1126_cru,
2171 						    glb_srst_snd);
2172 		sys_child->priv = priv;
2173 	}
2174 
2175 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2176 					 dev_ofnode(dev), &sf_child);
2177 	if (ret) {
2178 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2179 	} else {
2180 		sf_priv = malloc(sizeof(struct softreset_reg));
2181 		sf_priv->sf_reset_offset = offsetof(struct rv1126_cru,
2182 						    softrst_con[0]);
2183 		sf_priv->sf_reset_num = 15;
2184 		sf_child->priv = sf_priv;
2185 	}
2186 
2187 	return 0;
2188 }
2189 
2190 static const struct udevice_id rv1126_clk_ids[] = {
2191 	{ .compatible = "rockchip,rv1126-cru" },
2192 	{ }
2193 };
2194 
2195 U_BOOT_DRIVER(rockchip_rv1126_cru) = {
2196 	.name		= "rockchip_rv1126_cru",
2197 	.id		= UCLASS_CLK,
2198 	.of_match	= rv1126_clk_ids,
2199 	.priv_auto_alloc_size = sizeof(struct rv1126_clk_priv),
2200 	.ofdata_to_platdata = rv1126_clk_ofdata_to_platdata,
2201 	.ops		= &rv1126_clk_ops,
2202 	.bind		= rv1126_clk_bind,
2203 	.probe		= rv1126_clk_probe,
2204 };
2205 
2206 #ifndef CONFIG_SPL_BUILD
2207 /**
2208  * soc_clk_dump() - Print clock frequencies
2209  * Returns zero on success
2210  *
2211  * Implementation for the clk dump command.
2212  */
2213 int soc_clk_dump(void)
2214 {
2215 	struct udevice *cru_dev, *pmucru_dev;
2216 	struct rv1126_clk_priv *priv;
2217 	const struct rv1126_clk_info *clk_dump;
2218 	struct clk clk;
2219 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2220 	unsigned long rate;
2221 	int i, ret;
2222 
2223 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2224 					  DM_GET_DRIVER(rockchip_rv1126_cru),
2225 					  &cru_dev);
2226 	if (ret) {
2227 		printf("%s failed to get cru device\n", __func__);
2228 		return ret;
2229 	}
2230 
2231 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2232 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
2233 					  &pmucru_dev);
2234 	if (ret) {
2235 		printf("%s failed to get pmucru device\n", __func__);
2236 		return ret;
2237 	}
2238 
2239 	priv = dev_get_priv(cru_dev);
2240 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2241 	       priv->sync_kernel ? "sync kernel" : "uboot",
2242 	       priv->armclk_enter_hz / 1000,
2243 	       priv->armclk_init_hz / 1000,
2244 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2245 	       priv->set_armclk_rate ? " KHz" : "N/A");
2246 	for (i = 0; i < clk_count; i++) {
2247 		clk_dump = &clks_dump[i];
2248 		if (clk_dump->name) {
2249 			clk.id = clk_dump->id;
2250 			if (clk_dump->is_cru)
2251 				ret = clk_request(cru_dev, &clk);
2252 			else
2253 				ret = clk_request(pmucru_dev, &clk);
2254 			if (ret < 0)
2255 				return ret;
2256 
2257 			rate = clk_get_rate(&clk);
2258 			clk_free(&clk);
2259 			if (i == 0) {
2260 				if (rate < 0)
2261 					printf("  %s %s\n", clk_dump->name,
2262 					       "unknown");
2263 				else
2264 					printf("  %s %lu KHz\n", clk_dump->name,
2265 					       rate / 1000);
2266 			} else {
2267 				if (rate < 0)
2268 					printf("  %s %s\n", clk_dump->name,
2269 					       "unknown");
2270 				else
2271 					printf("  %s %lu KHz\n", clk_dump->name,
2272 					       rate / 1000);
2273 			}
2274 		}
2275 	}
2276 
2277 	return 0;
2278 }
2279 #endif
2280