xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rv1126.c (revision a1daefc8e61099cd3e2c89eba707e5fa507c749b)
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_gmac_src_get_clk(struct rv1126_clk_priv *priv)
1292 {
1293 	struct rv1126_cru *cru = priv->cru;
1294 	u32 div, sel, con, parent;
1295 
1296 	con = readl(&cru->clksel_con[63]);
1297 	div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
1298 	sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
1299 	if (sel == CLK_GMAC_SRC_SEL_CPLL)
1300 		parent = priv->cpll_hz;
1301 	else if (sel == CLK_GMAC_SRC_SEL_GPLL)
1302 		parent = priv->gpll_hz;
1303 	else
1304 		return -ENOENT;
1305 
1306 	return DIV_TO_RATE(parent, div);
1307 }
1308 
1309 static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1310 {
1311 	struct rv1126_cru *cru = priv->cru;
1312 	int src_clk_div;
1313 
1314 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1315 	assert(src_clk_div - 1 <= 31);
1316 	rk_clrsetreg(&cru->clksel_con[63],
1317 		     CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
1318 		     CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
1319 		     (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
1320 
1321 	return rv1126_gmac_src_get_clk(priv);
1322 }
1323 
1324 static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
1325 {
1326 	struct rv1126_cru *cru = priv->cru;
1327 	u32 div, sel, con, parent;
1328 
1329 	con = readl(&cru->clksel_con[61]);
1330 	div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
1331 	sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
1332 	if (sel == CLK_GMAC_OUT_SEL_CPLL)
1333 		parent = priv->cpll_hz;
1334 	else if (sel == CLK_GMAC_OUT_SEL_GPLL)
1335 		parent = priv->gpll_hz;
1336 	else
1337 		return -ENOENT;
1338 
1339 	return DIV_TO_RATE(parent, div);
1340 }
1341 
1342 static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1343 {
1344 	struct rv1126_cru *cru = priv->cru;
1345 	int src_clk_div;
1346 
1347 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1348 	assert(src_clk_div - 1 <= 31);
1349 	rk_clrsetreg(&cru->clksel_con[61],
1350 		     CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
1351 		     CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
1352 		     (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
1353 
1354 	return rv1126_gmac_out_get_clk(priv);
1355 }
1356 
1357 static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1358 {
1359 	struct rv1126_cru *cru = priv->cru;
1360 	u32 con, sel, div_sel;
1361 
1362 	con = readl(&cru->gmac_con);
1363 	sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
1364 
1365 	if (sel == GMAC_RGMII_MODE) {
1366 		if (rate == 2500000)
1367 			div_sel = RGMII_CLK_DIV50;
1368 		else if (rate == 25000000)
1369 			div_sel = RGMII_CLK_DIV5;
1370 		else
1371 			div_sel = RGMII_CLK_DIV0;
1372 		rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
1373 			     div_sel << RGMII_CLK_SEL_SHIFT);
1374 	} else if (sel == GMAC_RMII_MODE) {
1375 		if (rate == 2500000)
1376 			div_sel = RMII_CLK_DIV20;
1377 		else
1378 			div_sel = RMII_CLK_DIV2;
1379 		rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
1380 			     div_sel << RMII_CLK_SEL_SHIFT);
1381 	}
1382 
1383 	return 0;
1384 }
1385 
1386 static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
1387 {
1388 	struct rv1126_cru *cru = priv->cru;
1389 	u32 div, con, parent;
1390 
1391 	parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
1392 
1393 	con = readl(&cru->clksel_con[63]);
1394 	div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
1395 
1396 	return DIV_TO_RATE(parent, div);
1397 }
1398 
1399 static ulong rv1126_clk_get_rate(struct clk *clk)
1400 {
1401 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1402 	ulong rate = 0;
1403 
1404 	if (!priv->gpll_hz) {
1405 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1406 		return -ENOENT;
1407 	}
1408 
1409 	switch (clk->id) {
1410 	case PLL_APLL:
1411 	case ARMCLK:
1412 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru,
1413 					     APLL);
1414 		break;
1415 	case PLL_CPLL:
1416 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru,
1417 					     CPLL);
1418 		break;
1419 	case PLL_HPLL:
1420 		rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru,
1421 					     HPLL);
1422 		break;
1423 	case HCLK_PDCORE_NIU:
1424 		rate = rv1126_pdcore_get_clk(priv);
1425 		break;
1426 	case ACLK_PDBUS:
1427 	case HCLK_PDBUS:
1428 	case PCLK_PDBUS:
1429 		rate = rv1126_pdbus_get_clk(priv, clk->id);
1430 		break;
1431 	case ACLK_PDPHP:
1432 	case HCLK_PDPHP:
1433 		rate = rv1126_pdphp_get_clk(priv, clk->id);
1434 		break;
1435 	case HCLK_PDAUDIO:
1436 		rate = rv1126_pdaudio_get_clk(priv);
1437 		break;
1438 	case CLK_I2C1:
1439 	case CLK_I2C3:
1440 	case CLK_I2C4:
1441 	case CLK_I2C5:
1442 		rate = rv1126_i2c_get_clk(priv, clk->id);
1443 		break;
1444 	case CLK_SPI1:
1445 		rate = rv1126_spi_get_clk(priv);
1446 		break;
1447 	case CLK_PWM2:
1448 		rate = rv1126_pwm_get_clk(priv);
1449 		break;
1450 	case CLK_SARADC:
1451 		rate = rv1126_saradc_get_clk(priv);
1452 		break;
1453 	case CLK_CRYPTO_CORE:
1454 	case CLK_CRYPTO_PKA:
1455 	case ACLK_CRYPTO:
1456 		rate = rv1126_crypto_get_clk(priv, clk->id);
1457 		break;
1458 	case CLK_SDMMC:
1459 	case HCLK_SDMMC:
1460 	case CLK_SDIO:
1461 	case HCLK_SDIO:
1462 	case CLK_EMMC:
1463 	case HCLK_EMMC:
1464 	case SCLK_EMMC_SAMPLE:
1465 		rate = rv1126_mmc_get_clk(priv, clk->id);
1466 		break;
1467 	case SCLK_SFC:
1468 		rate = rv1126_sfc_get_clk(priv);
1469 		break;
1470 	case CLK_NANDC:
1471 		rate = rv1126_nand_get_clk(priv);
1472 		break;
1473 	case ACLK_PDVO:
1474 	case ACLK_VOP:
1475 		rate = rv1126_aclk_vop_get_clk(priv);
1476 		break;
1477 	case DCLK_VOP:
1478 		rate = rv1126_dclk_vop_get_clk(priv);
1479 		break;
1480 	case CLK_SCR1_CORE:
1481 		rate = rv1126_scr1_get_clk(priv);
1482 		break;
1483 	case CLK_GMAC_SRC:
1484 		rate = rv1126_gmac_src_get_clk(priv);
1485 		break;
1486 	case CLK_GMAC_ETHERNET_OUT:
1487 		rate = rv1126_gmac_out_get_clk(priv);
1488 		break;
1489 	case PCLK_GMAC:
1490 		rate = rv1126_pclk_gmac_get_clk(priv);
1491 		break;
1492 	default:
1493 		return -ENOENT;
1494 	}
1495 
1496 	return rate;
1497 };
1498 
1499 static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
1500 {
1501 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1502 	ulong ret = 0;
1503 
1504 	if (!priv->gpll_hz) {
1505 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1506 		return -ENOENT;
1507 	}
1508 
1509 	switch (clk->id) {
1510 	case PLL_APLL:
1511 	case ARMCLK:
1512 		if (priv->armclk_hz)
1513 			rv1126_armclk_set_clk(priv, rate);
1514 		priv->armclk_hz = rate;
1515 		break;
1516 	case PLL_CPLL:
1517 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
1518 					    CPLL, rate);
1519 		break;
1520 	case PLL_HPLL:
1521 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
1522 					    HPLL, rate);
1523 		break;
1524 	case ACLK_PDBUS:
1525 	case HCLK_PDBUS:
1526 	case PCLK_PDBUS:
1527 		ret = rv1126_pdbus_set_clk(priv, clk->id, rate);
1528 		break;
1529 	case ACLK_PDPHP:
1530 	case HCLK_PDPHP:
1531 		ret = rv1126_pdphp_set_clk(priv, clk->id, rate);
1532 		break;
1533 	case HCLK_PDCORE_NIU:
1534 		ret = rv1126_pdcore_set_clk(priv, rate);
1535 		break;
1536 	case HCLK_PDAUDIO:
1537 		ret = rv1126_pdaudio_set_clk(priv, rate);
1538 		break;
1539 	case CLK_I2C1:
1540 	case CLK_I2C3:
1541 	case CLK_I2C4:
1542 	case CLK_I2C5:
1543 		ret = rv1126_i2c_set_clk(priv, clk->id, rate);
1544 		break;
1545 	case CLK_SPI1:
1546 		ret = rv1126_spi_set_clk(priv, rate);
1547 		break;
1548 	case CLK_PWM2:
1549 		ret = rv1126_pwm_set_clk(priv, rate);
1550 		break;
1551 	case CLK_SARADC:
1552 		ret = rv1126_saradc_set_clk(priv, rate);
1553 		break;
1554 	case CLK_CRYPTO_CORE:
1555 	case CLK_CRYPTO_PKA:
1556 	case ACLK_CRYPTO:
1557 		ret = rv1126_crypto_set_clk(priv, clk->id, rate);
1558 		break;
1559 	case CLK_SDMMC:
1560 	case HCLK_SDMMC:
1561 	case CLK_SDIO:
1562 	case HCLK_SDIO:
1563 	case CLK_EMMC:
1564 	case HCLK_EMMC:
1565 		ret = rv1126_mmc_set_clk(priv, clk->id, rate);
1566 		break;
1567 	case SCLK_SFC:
1568 		ret = rv1126_sfc_set_clk(priv, rate);
1569 		break;
1570 	case CLK_NANDC:
1571 		ret = rv1126_nand_set_clk(priv, rate);
1572 		break;
1573 	case ACLK_PDVO:
1574 	case ACLK_VOP:
1575 		ret = rv1126_aclk_vop_set_clk(priv, rate);
1576 		break;
1577 	case DCLK_VOP:
1578 		ret = rv1126_dclk_vop_set_clk(priv, rate);
1579 		break;
1580 	case CLK_SCR1_CORE:
1581 		ret = rv1126_scr1_set_clk(priv, rate);
1582 		break;
1583 	case CLK_GMAC_SRC:
1584 		ret = rv1126_gmac_src_set_clk(priv, rate);
1585 		break;
1586 	case CLK_GMAC_ETHERNET_OUT:
1587 		ret = rv1126_gmac_out_set_clk(priv, rate);
1588 		break;
1589 	case CLK_GMAC_TX_RX:
1590 		ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
1591 		break;
1592 	default:
1593 		return -ENOENT;
1594 	}
1595 
1596 	return ret;
1597 };
1598 
1599 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1600 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1601 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1602 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1603 
1604 #define PSECS_PER_SEC 1000000000000LL
1605 /*
1606  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1607  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1608  */
1609 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1610 
1611 int rv1126_mmc_get_phase(struct clk *clk)
1612 {
1613 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1614 	struct rv1126_cru *cru = priv->cru;
1615 	u32 raw_value, delay_num;
1616 	u16 degrees = 0;
1617 	ulong rate;
1618 
1619 	rate = rv1126_clk_get_rate(clk);
1620 	if (rate < 0)
1621 		return rate;
1622 
1623 	if (clk->id == SCLK_EMMC_SAMPLE)
1624 		raw_value = readl(&cru->emmc_con[1]);
1625 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1626 		raw_value = readl(&cru->sdmmc_con[1]);
1627 	else
1628 		raw_value = readl(&cru->sdio_con[1]);
1629 
1630 	raw_value >>= 1;
1631 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1632 
1633 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1634 		/* degrees/delaynum * 10000 */
1635 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1636 					36 * (rate / 1000000);
1637 
1638 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1639 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1640 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1641 	}
1642 
1643 	return degrees % 360;
1644 }
1645 
1646 int rv1126_mmc_set_phase(struct clk *clk, u32 degrees)
1647 {
1648 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1649 	struct rv1126_cru *cru = priv->cru;
1650 	u8 nineties, remainder, delay_num;
1651 	u32 raw_value, delay;
1652 	ulong rate;
1653 
1654 	rate = rv1126_clk_get_rate(clk);
1655 	if (rate < 0)
1656 		return rate;
1657 
1658 	nineties = degrees / 90;
1659 	remainder = (degrees % 90);
1660 
1661 	/*
1662 	 * Convert to delay; do a little extra work to make sure we
1663 	 * don't overflow 32-bit / 64-bit numbers.
1664 	 */
1665 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1666 	delay *= remainder;
1667 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1668 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1669 
1670 	delay_num = (u8)min_t(u32, delay, 255);
1671 
1672 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1673 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1674 	raw_value |= nineties;
1675 
1676 	raw_value <<= 1;
1677 	if (clk->id == SCLK_EMMC_SAMPLE)
1678 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1679 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1680 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1681 	else
1682 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1683 
1684 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1685 	      degrees, delay_num, raw_value, rv1126_mmc_get_phase(clk));
1686 
1687 	return 0;
1688 }
1689 
1690 static int rv1126_clk_get_phase(struct clk *clk)
1691 {
1692 	int ret;
1693 
1694 	debug("%s %ld\n", __func__, clk->id);
1695 	switch (clk->id) {
1696 	case SCLK_EMMC_SAMPLE:
1697 	case SCLK_SDMMC_SAMPLE:
1698 	case SCLK_SDIO_SAMPLE:
1699 		ret = rv1126_mmc_get_phase(clk);
1700 		break;
1701 	default:
1702 		return -ENOENT;
1703 	}
1704 
1705 	return ret;
1706 }
1707 
1708 static int rv1126_clk_set_phase(struct clk *clk, int degrees)
1709 {
1710 	int ret;
1711 
1712 	debug("%s %ld\n", __func__, clk->id);
1713 	switch (clk->id) {
1714 	case SCLK_EMMC_SAMPLE:
1715 	case SCLK_SDMMC_SAMPLE:
1716 	case SCLK_SDIO_SAMPLE:
1717 		ret = rv1126_mmc_set_phase(clk, degrees);
1718 		break;
1719 	default:
1720 		return -ENOENT;
1721 	}
1722 
1723 	return ret;
1724 }
1725 
1726 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1727 static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent)
1728 {
1729 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1730 	struct rv1126_grf *grf = priv->grf;
1731 
1732 	if (parent->id == CLK_GMAC_SRC_M0)
1733 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1734 			     GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT);
1735 	else if(parent->id == CLK_GMAC_SRC_M1)
1736 		rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1737 			     GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT);
1738 
1739 	return 0;
1740 }
1741 
1742 static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent)
1743 {
1744 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1745 	struct rv1126_cru *cru = priv->cru;
1746 
1747 	if (parent->id == CLK_GMAC_DIV)
1748 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1749 			     GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT);
1750 	else
1751 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK,
1752 			     GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT);
1753 
1754 	return 0;
1755 }
1756 
1757 static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
1758 {
1759 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1760 	struct rv1126_cru *cru = priv->cru;
1761 
1762 	if (parent->id == CLK_GMAC_DIV)
1763 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
1764 			     GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT);
1765 	else
1766 		rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK,
1767 			     GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT);
1768 
1769 	return 0;
1770 }
1771 
1772 static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
1773 {
1774 	struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1775 	struct rv1126_cru *cru = priv->cru;
1776 
1777 	if (parent->id == RGMII_MODE_CLK)
1778 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1779 			     GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
1780 	else
1781 		rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
1782 			     GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
1783 
1784 	return 0;
1785 }
1786 
1787 static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
1788 {
1789 	switch (clk->id) {
1790 	case CLK_GMAC_SRC:
1791 		return rv1126_gmac_src_set_parent(clk, parent);
1792 	case CLK_GMAC_SRC_M0:
1793 		return rv1126_gmac_src_m0_set_parent(clk, parent);
1794 	case CLK_GMAC_SRC_M1:
1795 		return rv1126_gmac_src_m1_set_parent(clk, parent);
1796 	case CLK_GMAC_TX_RX:
1797 		return rv1126_gmac_tx_rx_set_parent(clk, parent);
1798 	default:
1799 		return -ENOENT;
1800 	}
1801 
1802 	return 0;
1803 }
1804 #endif
1805 
1806 static struct clk_ops rv1126_clk_ops = {
1807 	.get_rate = rv1126_clk_get_rate,
1808 	.set_rate = rv1126_clk_set_rate,
1809 	.get_phase = rv1126_clk_get_phase,
1810 	.set_phase = rv1126_clk_set_phase,
1811 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1812 	.set_parent = rv1126_clk_set_parent,
1813 #endif
1814 };
1815 
1816 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
1817 				  struct rv1126_pmuclk_priv *pmu_priv,
1818 				  ulong rate)
1819 {
1820 	ulong emmc_rate, sfc_rate, nandc_rate;
1821 	bool restore = false;
1822 
1823 	if (priv->gpll_hz != OSC_HZ) {
1824 		emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC);
1825 		sfc_rate = rv1126_sfc_get_clk(priv);
1826 		nandc_rate = rv1126_nand_get_clk(priv);
1827 		debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__,
1828 		      emmc_rate, sfc_rate, nandc_rate);
1829 		restore = true;
1830 	}
1831 
1832 	/*
1833 	 * the child div is big enough for gpll 1188MHz,
1834 	 * even maskrom has change some clocks.
1835 	 */
1836 	if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL],
1837 				  pmu_priv->pmucru, GPLL, rate))
1838 		return -EINVAL;
1839 	pmu_priv->gpll_hz = rate;
1840 	priv->gpll_hz = rate;
1841 
1842 	if (restore) {
1843 		rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate);
1844 		rv1126_sfc_set_clk(priv,  sfc_rate);
1845 		rv1126_nand_set_clk(priv, nandc_rate);
1846 	}
1847 
1848 	return 0;
1849 }
1850 
1851 static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1852 {
1853 	struct udevice *pmucru_dev;
1854 	struct rv1126_pmuclk_priv *pmu_priv;
1855 	int ret;
1856 
1857 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1858 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
1859 					  &pmucru_dev);
1860 	if (ret) {
1861 		printf("%s: could not find pmucru device\n", __func__);
1862 		return ret;
1863 	}
1864 	pmu_priv = dev_get_priv(pmucru_dev);
1865 	priv->gpll_hz = pmu_priv->gpll_hz;
1866 
1867 	if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
1868 		printf("%s: failed to set gpll rate %lu\n", __func__, rate);
1869 		return -EINVAL;
1870 	}
1871 
1872 	rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ);
1873 	rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ);
1874 
1875 	return 0;
1876 }
1877 
1878 static void rv1126_clk_init(struct rv1126_clk_priv *priv)
1879 {
1880 	int ret;
1881 
1882 	priv->sync_kernel = false;
1883 	if (!priv->armclk_enter_hz) {
1884 		priv->armclk_enter_hz =
1885 			rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
1886 					      priv->cru, APLL);
1887 		priv->armclk_init_hz = priv->armclk_enter_hz ;
1888 	}
1889 
1890 	if (priv->armclk_init_hz != APLL_HZ) {
1891 		ret = rv1126_armclk_set_clk(priv, APLL_HZ);
1892 		if (!ret)
1893 			priv->armclk_init_hz = APLL_HZ;
1894 	}
1895 	if (priv->cpll_hz != CPLL_HZ) {
1896 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
1897 					    CPLL, CPLL_HZ);
1898 		if (!ret)
1899 			priv->cpll_hz = CPLL_HZ;
1900 	}
1901 	if (priv->hpll_hz != HPLL_HZ) {
1902 		ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
1903 					    HPLL, HPLL_HZ);
1904 		if (!ret)
1905 			priv->hpll_hz = HPLL_HZ;
1906 	}
1907 	if (priv->gpll_hz != GPLL_HZ)
1908 		rv1126_gpll_set_clk(priv, GPLL_HZ);
1909 
1910 	rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ);
1911 	rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ);
1912 	rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ);
1913 	rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ);
1914 	rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ);
1915 	rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ);
1916 	rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ);
1917 }
1918 
1919 static int rv1126_clk_probe(struct udevice *dev)
1920 {
1921 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
1922 	int ret;
1923 
1924 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1925 	if (IS_ERR(priv->grf))
1926 		return PTR_ERR(priv->grf);
1927 
1928 	rv1126_clk_init(priv);
1929 
1930 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1931 	ret = clk_set_defaults(dev);
1932 	if (ret)
1933 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1934 	else
1935 		priv->sync_kernel = true;
1936 
1937 	return 0;
1938 }
1939 
1940 static int rv1126_clk_ofdata_to_platdata(struct udevice *dev)
1941 {
1942 	struct rv1126_clk_priv *priv = dev_get_priv(dev);
1943 
1944 	priv->cru = dev_read_addr_ptr(dev);
1945 
1946 	return 0;
1947 }
1948 
1949 static int rv1126_clk_bind(struct udevice *dev)
1950 {
1951 	int ret;
1952 	struct udevice *sys_child, *sf_child;
1953 	struct sysreset_reg *priv;
1954 	struct softreset_reg *sf_priv;
1955 
1956 	/* The reset driver does not have a device node, so bind it here */
1957 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1958 				 &sys_child);
1959 	if (ret) {
1960 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1961 	} else {
1962 		priv = malloc(sizeof(struct sysreset_reg));
1963 		priv->glb_srst_fst_value = offsetof(struct rv1126_cru,
1964 						    glb_srst_fst);
1965 		priv->glb_srst_snd_value = offsetof(struct rv1126_cru,
1966 						    glb_srst_snd);
1967 		sys_child->priv = priv;
1968 	}
1969 
1970 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1971 					 dev_ofnode(dev), &sf_child);
1972 	if (ret) {
1973 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1974 	} else {
1975 		sf_priv = malloc(sizeof(struct softreset_reg));
1976 		sf_priv->sf_reset_offset = offsetof(struct rv1126_cru,
1977 						    softrst_con[0]);
1978 		sf_priv->sf_reset_num = 15;
1979 		sf_child->priv = sf_priv;
1980 	}
1981 
1982 	return 0;
1983 }
1984 
1985 static const struct udevice_id rv1126_clk_ids[] = {
1986 	{ .compatible = "rockchip,rv1126-cru" },
1987 	{ }
1988 };
1989 
1990 U_BOOT_DRIVER(rockchip_rv1126_cru) = {
1991 	.name		= "rockchip_rv1126_cru",
1992 	.id		= UCLASS_CLK,
1993 	.of_match	= rv1126_clk_ids,
1994 	.priv_auto_alloc_size = sizeof(struct rv1126_clk_priv),
1995 	.ofdata_to_platdata = rv1126_clk_ofdata_to_platdata,
1996 	.ops		= &rv1126_clk_ops,
1997 	.bind		= rv1126_clk_bind,
1998 	.probe		= rv1126_clk_probe,
1999 };
2000 
2001 #ifndef CONFIG_SPL_BUILD
2002 /**
2003  * soc_clk_dump() - Print clock frequencies
2004  * Returns zero on success
2005  *
2006  * Implementation for the clk dump command.
2007  */
2008 int soc_clk_dump(void)
2009 {
2010 	struct udevice *cru_dev, *pmucru_dev;
2011 	struct rv1126_clk_priv *priv;
2012 	const struct rv1126_clk_info *clk_dump;
2013 	struct clk clk;
2014 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2015 	unsigned long rate;
2016 	int i, ret;
2017 
2018 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2019 					  DM_GET_DRIVER(rockchip_rv1126_cru),
2020 					  &cru_dev);
2021 	if (ret) {
2022 		printf("%s failed to get cru device\n", __func__);
2023 		return ret;
2024 	}
2025 
2026 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2027 					  DM_GET_DRIVER(rockchip_rv1126_pmucru),
2028 					  &pmucru_dev);
2029 	if (ret) {
2030 		printf("%s failed to get pmucru device\n", __func__);
2031 		return ret;
2032 	}
2033 
2034 	priv = dev_get_priv(cru_dev);
2035 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2036 	       priv->sync_kernel ? "sync kernel" : "uboot",
2037 	       priv->armclk_enter_hz / 1000,
2038 	       priv->armclk_init_hz / 1000,
2039 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2040 	       priv->set_armclk_rate ? " KHz" : "N/A");
2041 	for (i = 0; i < clk_count; i++) {
2042 		clk_dump = &clks_dump[i];
2043 		if (clk_dump->name) {
2044 			clk.id = clk_dump->id;
2045 			if (clk_dump->is_cru)
2046 				ret = clk_request(cru_dev, &clk);
2047 			else
2048 				ret = clk_request(pmucru_dev, &clk);
2049 			if (ret < 0)
2050 				return ret;
2051 
2052 			rate = clk_get_rate(&clk);
2053 			clk_free(&clk);
2054 			if (i == 0) {
2055 				if (rate < 0)
2056 					printf("  %s %s\n", clk_dump->name,
2057 					       "unknown");
2058 				else
2059 					printf("  %s %lu KHz\n", clk_dump->name,
2060 					       rate / 1000);
2061 			} else {
2062 				if (rate < 0)
2063 					printf("  %s %s\n", clk_dump->name,
2064 					       "unknown");
2065 				else
2066 					printf("  %s %lu KHz\n", clk_dump->name,
2067 					       rate / 1000);
2068 			}
2069 		}
2070 	}
2071 
2072 	return 0;
2073 }
2074 #endif
2075