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