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