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