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