xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk3568.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Joseph Chen <chenjh@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_rk3568.h>
15 #include <asm/arch/grf_rk3568.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rk3568-cru.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define RK3568_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 rk3568_cpu_rates[] = {
33 	RK3568_CPUCLK_RATE(1416000000, 1, 5),
34 	RK3568_CPUCLK_RATE(1296000000, 1, 5),
35 	RK3568_CPUCLK_RATE(1200000000, 1, 3),
36 	RK3568_CPUCLK_RATE(1104000000, 1, 3),
37 	RK3568_CPUCLK_RATE(1008000000, 1, 3),
38 	RK3568_CPUCLK_RATE(912000000, 1, 3),
39 	RK3568_CPUCLK_RATE(816000000, 1, 3),
40 	RK3568_CPUCLK_RATE(600000000, 1, 1),
41 	RK3568_CPUCLK_RATE(408000000, 1, 1),
42 	{ /* sentinel */ },
43 };
44 
45 static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
46 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
47 	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
48 	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
49 	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
50 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
51 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
52 	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
53 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
54 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
55 	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
56 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
57 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
58 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
59 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
60 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
61 	RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
62 	RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
63 	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
64 	{ /* sentinel */ },
65 };
66 
67 static struct rockchip_pll_clock rk3568_pll_clks[] = {
68 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0),
69 		     RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates),
70 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8),
71 		     RK3568_MODE_CON, 2, 10, 0, NULL),
72 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24),
73 		     RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates),
74 	[GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16),
75 		     RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates),
76 	[NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32),
77 		     RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates),
78 	[VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40),
79 		     RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates),
80 	[PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0),
81 		     RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates),
82 	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16),
83 		     RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates),
84 };
85 
86 #ifndef CONFIG_SPL_BUILD
87 #define RK3568_CLK_DUMP(_id, _name, _iscru)	\
88 {						\
89 	.id = _id,				\
90 	.name = _name,				\
91 	.is_cru = _iscru,			\
92 }
93 
94 static const struct rk3568_clk_info clks_dump[] = {
95 	RK3568_CLK_DUMP(PLL_APLL, "apll", true),
96 	RK3568_CLK_DUMP(PLL_DPLL, "dpll", true),
97 	RK3568_CLK_DUMP(PLL_GPLL, "gpll", true),
98 	RK3568_CLK_DUMP(PLL_CPLL, "cpll", true),
99 	RK3568_CLK_DUMP(PLL_NPLL, "npll", true),
100 	RK3568_CLK_DUMP(PLL_VPLL, "vpll", true),
101 	RK3568_CLK_DUMP(PLL_HPLL, "hpll", false),
102 	RK3568_CLK_DUMP(PLL_PPLL, "ppll", false),
103 	RK3568_CLK_DUMP(ARMCLK, "armclk", true),
104 	RK3568_CLK_DUMP(ACLK_BUS, "aclk_bus", true),
105 	RK3568_CLK_DUMP(PCLK_BUS, "pclk_bus", true),
106 	RK3568_CLK_DUMP(ACLK_TOP_HIGH, "aclk_top_high", true),
107 	RK3568_CLK_DUMP(ACLK_TOP_LOW, "aclk_top_low", true),
108 	RK3568_CLK_DUMP(HCLK_TOP, "hclk_top", true),
109 	RK3568_CLK_DUMP(PCLK_TOP, "pclk_top", true),
110 	RK3568_CLK_DUMP(ACLK_PERIMID, "aclk_perimid", true),
111 	RK3568_CLK_DUMP(HCLK_PERIMID, "hclk_perimid", true),
112 	RK3568_CLK_DUMP(PCLK_PMU, "pclk_pmu", false),
113 };
114 #endif
115 
116 static ulong __maybe_unused
rk3568_pmu_pll_set_rate(struct rk3568_clk_priv * priv,ulong pll_id,ulong rate)117 rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
118 			ulong pll_id, ulong rate)
119 {
120 	struct udevice *pmucru_dev;
121 	struct rk3568_pmuclk_priv *pmu_priv;
122 	int ret;
123 
124 	ret = uclass_get_device_by_driver(UCLASS_CLK,
125 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
126 					  &pmucru_dev);
127 	if (ret) {
128 		printf("%s: could not find pmucru device\n", __func__);
129 		return ret;
130 	}
131 	pmu_priv = dev_get_priv(pmucru_dev);
132 
133 	rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
134 			      pmu_priv->pmucru, pll_id, rate);
135 
136 	return 0;
137 }
138 
rk3568_pmu_pll_get_rate(struct rk3568_clk_priv * priv,ulong pll_id)139 static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
140 				     ulong pll_id)
141 {
142 	struct udevice *pmucru_dev;
143 	struct rk3568_pmuclk_priv *pmu_priv;
144 	int ret;
145 
146 	ret = uclass_get_device_by_driver(UCLASS_CLK,
147 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
148 					  &pmucru_dev);
149 	if (ret) {
150 		printf("%s: could not find pmucru device\n", __func__);
151 		return ret;
152 	}
153 	pmu_priv = dev_get_priv(pmucru_dev);
154 
155 	return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
156 				      pmu_priv->pmucru, pll_id);
157 }
158 
159 /*
160  *
161  * rational_best_approximation(31415, 10000,
162  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
163  *
164  * you may look at given_numerator as a fixed point number,
165  * with the fractional part size described in given_denominator.
166  *
167  * for theoretical background, see:
168  * http://en.wikipedia.org/wiki/Continued_fraction
169  */
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)170 static void rational_best_approximation(unsigned long given_numerator,
171 					unsigned long given_denominator,
172 					unsigned long max_numerator,
173 					unsigned long max_denominator,
174 					unsigned long *best_numerator,
175 					unsigned long *best_denominator)
176 {
177 	unsigned long n, d, n0, d0, n1, d1;
178 
179 	n = given_numerator;
180 	d = given_denominator;
181 	n0 = 0;
182 	d1 = 0;
183 	n1 = 1;
184 	d0 = 1;
185 	for (;;) {
186 		unsigned long t, a;
187 
188 		if (n1 > max_numerator || d1 > max_denominator) {
189 			n1 = n0;
190 			d1 = d0;
191 			break;
192 		}
193 		if (d == 0)
194 			break;
195 		t = d;
196 		a = n / d;
197 		d = n % d;
198 		n = t;
199 		t = n0 + a * n1;
200 		n0 = n1;
201 		n1 = t;
202 		t = d0 + a * d1;
203 		d0 = d1;
204 		d1 = t;
205 	}
206 	*best_numerator = n1;
207 	*best_denominator = d1;
208 }
209 
rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv * priv)210 static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
211 {
212 	struct rk3568_pmucru *pmucru = priv->pmucru;
213 	unsigned long m, n;
214 	u32 fracdiv;
215 
216 	fracdiv = readl(&pmucru->pmu_clksel_con[1]);
217 	m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
218 	m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
219 	n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
220 	n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
221 
222 	return OSC_HZ * m / n;
223 }
224 
rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv * priv,ulong rate)225 static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
226 				      ulong rate)
227 {
228 	struct rk3568_pmucru *pmucru = priv->pmucru;
229 	unsigned long m, n, val;
230 
231 	rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
232 		     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
233 
234 	rational_best_approximation(rate, OSC_HZ,
235 				    GENMASK(16 - 1, 0),
236 				    GENMASK(16 - 1, 0),
237 				    &m, &n);
238 	val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
239 	writel(val, &pmucru->pmu_clksel_con[1]);
240 
241 	return rk3568_rtc32k_get_pmuclk(priv);
242 }
243 
rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv * priv,ulong clk_id)244 static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
245 				   ulong clk_id)
246 {
247 	struct rk3568_pmucru *pmucru = priv->pmucru;
248 	u32 div, con;
249 
250 	switch (clk_id) {
251 	case CLK_I2C0:
252 		con = readl(&pmucru->pmu_clksel_con[3]);
253 		div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
254 		break;
255 	default:
256 		return -ENOENT;
257 	}
258 
259 	return DIV_TO_RATE(priv->ppll_hz, div);
260 }
261 
rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv * priv,ulong clk_id,ulong rate)262 static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
263 				   ulong clk_id, ulong rate)
264 {
265 	struct rk3568_pmucru *pmucru = priv->pmucru;
266 	int src_clk_div;
267 
268 	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
269 	assert(src_clk_div - 1 <= 127);
270 
271 	switch (clk_id) {
272 	case CLK_I2C0:
273 		rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
274 			     (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
275 		break;
276 	default:
277 		return -ENOENT;
278 	}
279 
280 	return rk3568_i2c_get_pmuclk(priv, clk_id);
281 }
282 
rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv * priv,ulong clk_id)283 static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
284 				   ulong clk_id)
285 {
286 	struct rk3568_pmucru *pmucru = priv->pmucru;
287 	u32 div, sel, con, parent;
288 
289 	switch (clk_id) {
290 	case CLK_PWM0:
291 		con = readl(&pmucru->pmu_clksel_con[6]);
292 		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
293 		div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
294 		if (sel == CLK_PWM0_SEL_XIN24M)
295 			parent = OSC_HZ;
296 		else
297 			parent = priv->ppll_hz;
298 		break;
299 	default:
300 		return -ENOENT;
301 	}
302 
303 	return DIV_TO_RATE(parent, div);
304 }
305 
rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv * priv,ulong clk_id,ulong rate)306 static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
307 				   ulong clk_id, ulong rate)
308 {
309 	struct rk3568_pmucru *pmucru = priv->pmucru;
310 	int src_clk_div;
311 
312 	switch (clk_id) {
313 	case CLK_PWM0:
314 		if (rate == OSC_HZ) {
315 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
316 				     CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
317 				     (CLK_PWM0_SEL_XIN24M <<
318 				      CLK_PWM0_SEL_SHIFT) |
319 				     0 << CLK_PWM0_SEL_SHIFT);
320 		} else {
321 			src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
322 			assert(src_clk_div - 1 <= 127);
323 			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
324 				     CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
325 				     (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) |
326 				     (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
327 		}
328 		break;
329 	default:
330 		return -ENOENT;
331 	}
332 
333 	return rk3568_pwm_get_pmuclk(priv, clk_id);
334 }
335 
rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv * priv)336 static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
337 {
338 	struct rk3568_pmucru *pmucru = priv->pmucru;
339 	u32 div, con, sel, parent;
340 
341 	con = readl(&pmucru->pmu_clksel_con[2]);
342 	sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
343 	div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
344 	if (sel)
345 		parent = GPLL_HZ;
346 	else
347 		parent = priv->ppll_hz;
348 
349 	return DIV_TO_RATE(parent, div);
350 }
351 
rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv * priv,ulong rate)352 static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
353 				   ulong rate)
354 {
355 	struct rk3568_pmucru *pmucru = priv->pmucru;
356 	int src_clk_div;
357 
358 	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
359 	assert(src_clk_div - 1 <= 31);
360 
361 	rk_clrsetreg(&pmucru->pmu_clksel_con[2],
362 		     PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
363 		     (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) |
364 		     ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
365 
366 	return rk3568_pmu_get_pmuclk(priv);
367 }
368 
rk3568_pmuclk_get_rate(struct clk * clk)369 static ulong rk3568_pmuclk_get_rate(struct clk *clk)
370 {
371 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
372 	ulong rate = 0;
373 
374 	if (!priv->ppll_hz) {
375 		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
376 		return -ENOENT;
377 	}
378 
379 	debug("%s %ld\n", __func__, clk->id);
380 	switch (clk->id) {
381 	case PLL_PPLL:
382 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
383 					     priv->pmucru, PPLL);
384 		break;
385 	case PLL_HPLL:
386 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
387 					     priv->pmucru, HPLL);
388 		break;
389 	case CLK_RTC_32K:
390 	case CLK_RTC32K_FRAC:
391 		rate = rk3568_rtc32k_get_pmuclk(priv);
392 		break;
393 	case CLK_I2C0:
394 		rate = rk3568_i2c_get_pmuclk(priv, clk->id);
395 		break;
396 	case CLK_PWM0:
397 		rate = rk3568_pwm_get_pmuclk(priv, clk->id);
398 		break;
399 	case PCLK_PMU:
400 		rate = rk3568_pmu_get_pmuclk(priv);
401 		break;
402 	default:
403 		return -ENOENT;
404 	}
405 
406 	return rate;
407 }
408 
rk3568_pmuclk_set_rate(struct clk * clk,ulong rate)409 static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
410 {
411 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
412 	ulong ret = 0;
413 
414 	if (!priv->ppll_hz) {
415 		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
416 		return -ENOENT;
417 	}
418 
419 	debug("%s %ld %ld\n", __func__, clk->id, rate);
420 	switch (clk->id) {
421 	case PLL_PPLL:
422 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
423 					    priv->pmucru, PPLL, rate);
424 		priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
425 						      priv->pmucru, PPLL);
426 		break;
427 	case PLL_HPLL:
428 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL],
429 					    priv->pmucru, HPLL, rate);
430 		priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
431 						      priv->pmucru, HPLL);
432 		break;
433 	case CLK_RTC_32K:
434 	case CLK_RTC32K_FRAC:
435 		ret = rk3568_rtc32k_set_pmuclk(priv, rate);
436 		break;
437 	case CLK_I2C0:
438 		ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
439 		break;
440 	case CLK_PWM0:
441 		ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
442 		break;
443 	case PCLK_PMU:
444 		ret = rk3568_pmu_set_pmuclk(priv, rate);
445 		break;
446 	default:
447 		return -ENOENT;
448 	}
449 
450 	return ret;
451 }
452 
rk3568_rtc32k_set_parent(struct clk * clk,struct clk * parent)453 static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
454 {
455 	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
456 	struct rk3568_pmucru *pmucru = priv->pmucru;
457 
458 	if (parent->id == CLK_RTC32K_FRAC)
459 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
460 			     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
461 	else
462 		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
463 			     RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
464 
465 	return 0;
466 }
467 
rk3568_pmuclk_set_parent(struct clk * clk,struct clk * parent)468 static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
469 {
470 	switch (clk->id) {
471 	case CLK_RTC_32K:
472 		return rk3568_rtc32k_set_parent(clk, parent);
473 	default:
474 		return -ENOENT;
475 	}
476 }
477 
478 static struct clk_ops rk3568_pmuclk_ops = {
479 	.get_rate = rk3568_pmuclk_get_rate,
480 	.set_rate = rk3568_pmuclk_set_rate,
481 	.set_parent = rk3568_pmuclk_set_parent,
482 };
483 
rk3568_pmuclk_probe(struct udevice * dev)484 static int rk3568_pmuclk_probe(struct udevice *dev)
485 {
486 	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
487 	int ret = 0;
488 
489 	if (priv->ppll_hz != PPLL_HZ) {
490 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
491 					    priv->pmucru,
492 					    PPLL, PPLL_HZ);
493 		if (!ret)
494 			priv->ppll_hz = PPLL_HZ;
495 	}
496 
497 	/* Ungate PCIe30phy refclk_m and refclk_n */
498 	rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
499 	return 0;
500 }
501 
rk3568_pmuclk_ofdata_to_platdata(struct udevice * dev)502 static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
503 {
504 	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
505 
506 	priv->pmucru = dev_read_addr_ptr(dev);
507 
508 	return 0;
509 }
510 
rk3568_pmuclk_bind(struct udevice * dev)511 static int rk3568_pmuclk_bind(struct udevice *dev)
512 {
513 	int ret = 0;
514 	struct udevice *sf_child;
515 	struct softreset_reg *sf_priv;
516 
517 	ret = device_bind_driver_to_node(dev, "rockchip_reset",
518 					 "reset", dev_ofnode(dev),
519 					 &sf_child);
520 	if (ret) {
521 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
522 	} else {
523 		sf_priv = malloc(sizeof(struct softreset_reg));
524 		sf_priv->sf_reset_offset = offsetof(struct rk3568_pmucru,
525 						    pmu_softrst_con[0]);
526 		sf_priv->sf_reset_num = 1;
527 		sf_child->priv = sf_priv;
528 	}
529 
530 	return 0;
531 }
532 
533 static const struct udevice_id rk3568_pmuclk_ids[] = {
534 	{ .compatible = "rockchip,rk3568-pmucru" },
535 	{ }
536 };
537 
538 U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
539 	.name		= "rockchip_rk3568_pmucru",
540 	.id		= UCLASS_CLK,
541 	.of_match	= rk3568_pmuclk_ids,
542 	.priv_auto_alloc_size = sizeof(struct rk3568_pmuclk_priv),
543 	.ofdata_to_platdata = rk3568_pmuclk_ofdata_to_platdata,
544 	.ops		= &rk3568_pmuclk_ops,
545 	.bind		= rk3568_pmuclk_bind,
546 	.probe		= rk3568_pmuclk_probe,
547 };
548 
rk3568_armclk_set_clk(struct rk3568_clk_priv * priv,ulong hz)549 static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
550 {
551 	struct rk3568_cru *cru = priv->cru;
552 	const struct rockchip_cpu_rate_table *rate;
553 	ulong old_rate;
554 
555 	rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
556 	if (!rate) {
557 		printf("%s unsupported rate\n", __func__);
558 		return -EINVAL;
559 	}
560 
561 	rk_clrsetreg(&cru->clksel_con[0],
562 		     CLK_CORE_PRE_SEL_MASK,
563 		     (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
564 	rk_clrsetreg(&cru->clksel_con[2],
565 		     SCLK_CORE_PRE_SEL_MASK |
566 		     SCLK_CORE_SRC_SEL_MASK |
567 		     SCLK_CORE_SRC_DIV_MASK,
568 		     (SCLK_CORE_PRE_SEL_SRC <<
569 		      SCLK_CORE_PRE_SEL_SHIFT) |
570 		     (SCLK_CORE_SRC_SEL_APLL <<
571 		      SCLK_CORE_SRC_SEL_SHIFT) |
572 		     (1 << SCLK_CORE_SRC_DIV_SHIFT));
573 
574 	/*
575 	 * set up dependent divisors for DBG and ACLK clocks.
576 	 */
577 	old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
578 					 priv->cru, APLL);
579 	if (old_rate > hz) {
580 		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
581 					  priv->cru, APLL, hz))
582 			return -EINVAL;
583 		rk_clrsetreg(&cru->clksel_con[3],
584 			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
585 			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
586 			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
587 		rk_clrsetreg(&cru->clksel_con[4],
588 			     PERIPHCLK_CORE_PRE_DIV_MASK |
589 			     PCLK_CORE_PRE_DIV_MASK,
590 			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
591 			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
592 		rk_clrsetreg(&cru->clksel_con[5],
593 			     ACLK_CORE_NDFT_DIV_MASK,
594 			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
595 	} else if (old_rate < hz) {
596 		rk_clrsetreg(&cru->clksel_con[3],
597 			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
598 			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
599 			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
600 		rk_clrsetreg(&cru->clksel_con[4],
601 			     PERIPHCLK_CORE_PRE_DIV_MASK |
602 			     PCLK_CORE_PRE_DIV_MASK,
603 			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
604 			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
605 		rk_clrsetreg(&cru->clksel_con[5],
606 			     ACLK_CORE_NDFT_DIV_MASK,
607 			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
608 		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
609 					  priv->cru, APLL, hz))
610 			return -EINVAL;
611 	}
612 
613 	return 0;
614 }
615 
rk3568_cpll_div_get_rate(struct rk3568_clk_priv * priv,ulong clk_id)616 static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
617 				      ulong clk_id)
618 {
619 	struct rk3568_cru *cru = priv->cru;
620 	int div, mask, shift, con;
621 
622 	switch (clk_id) {
623 	case CPLL_500M:
624 		con = 78;
625 		mask = CPLL_500M_DIV_MASK;
626 		shift = CPLL_500M_DIV_SHIFT;
627 		break;
628 	case CPLL_333M:
629 		con = 79;
630 		mask = CPLL_333M_DIV_MASK;
631 		shift = CPLL_333M_DIV_SHIFT;
632 		break;
633 	case CPLL_250M:
634 		con = 79;
635 		mask = CPLL_250M_DIV_MASK;
636 		shift = CPLL_250M_DIV_SHIFT;
637 		break;
638 	case CPLL_125M:
639 		con = 80;
640 		mask = CPLL_125M_DIV_MASK;
641 		shift = CPLL_125M_DIV_SHIFT;
642 		break;
643 	case CPLL_100M:
644 		con = 82;
645 		mask = CPLL_100M_DIV_MASK;
646 		shift = CPLL_100M_DIV_SHIFT;
647 		break;
648 	case CPLL_62P5M:
649 		con = 80;
650 		mask = CPLL_62P5M_DIV_MASK;
651 		shift = CPLL_62P5M_DIV_SHIFT;
652 		break;
653 	case CPLL_50M:
654 		con = 81;
655 		mask = CPLL_50M_DIV_MASK;
656 		shift = CPLL_50M_DIV_SHIFT;
657 		break;
658 	case CPLL_25M:
659 		con = 81;
660 		mask = CPLL_25M_DIV_MASK;
661 		shift = CPLL_25M_DIV_SHIFT;
662 		break;
663 	default:
664 		return -ENOENT;
665 	}
666 
667 	div = (readl(&cru->clksel_con[con]) & mask) >> shift;
668 	return DIV_TO_RATE(priv->cpll_hz, div);
669 }
670 
rk3568_cpll_div_set_rate(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)671 static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
672 				      ulong clk_id, ulong rate)
673 {
674 	struct rk3568_cru *cru = priv->cru;
675 	int div, mask, shift, con;
676 
677 	switch (clk_id) {
678 	case CPLL_500M:
679 		con = 78;
680 		mask = CPLL_500M_DIV_MASK;
681 		shift = CPLL_500M_DIV_SHIFT;
682 		break;
683 	case CPLL_333M:
684 		con = 79;
685 		mask = CPLL_333M_DIV_MASK;
686 		shift = CPLL_333M_DIV_SHIFT;
687 		break;
688 	case CPLL_250M:
689 		con = 79;
690 		mask = CPLL_250M_DIV_MASK;
691 		shift = CPLL_250M_DIV_SHIFT;
692 		break;
693 	case CPLL_125M:
694 		con = 80;
695 		mask = CPLL_125M_DIV_MASK;
696 		shift = CPLL_125M_DIV_SHIFT;
697 		break;
698 	case CPLL_100M:
699 		con = 82;
700 		mask = CPLL_100M_DIV_MASK;
701 		shift = CPLL_100M_DIV_SHIFT;
702 		break;
703 	case CPLL_62P5M:
704 		con = 80;
705 		mask = CPLL_62P5M_DIV_MASK;
706 		shift = CPLL_62P5M_DIV_SHIFT;
707 		break;
708 	case CPLL_50M:
709 		con = 81;
710 		mask = CPLL_50M_DIV_MASK;
711 		shift = CPLL_50M_DIV_SHIFT;
712 		break;
713 	case CPLL_25M:
714 		con = 81;
715 		mask = CPLL_25M_DIV_MASK;
716 		shift = CPLL_25M_DIV_SHIFT;
717 		break;
718 	default:
719 		return -ENOENT;
720 	}
721 
722 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
723 	assert(div - 1 <= 31);
724 	rk_clrsetreg(&cru->clksel_con[con],
725 		     mask, (div - 1) << shift);
726 	return rk3568_cpll_div_get_rate(priv, clk_id);
727 }
728 
rk3568_bus_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)729 static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
730 {
731 	struct rk3568_cru *cru = priv->cru;
732 	u32 con, sel, rate;
733 
734 	switch (clk_id) {
735 	case ACLK_BUS:
736 		con = readl(&cru->clksel_con[50]);
737 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
738 		if (sel == ACLK_BUS_SEL_200M)
739 			rate = 200 * MHz;
740 		else if (sel == ACLK_BUS_SEL_150M)
741 			rate = 150 * MHz;
742 		else if (sel == ACLK_BUS_SEL_100M)
743 			rate = 100 * MHz;
744 		else
745 			rate = OSC_HZ;
746 		break;
747 	case PCLK_BUS:
748 	case PCLK_WDT_NS:
749 		con = readl(&cru->clksel_con[50]);
750 		sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
751 		if (sel == PCLK_BUS_SEL_100M)
752 			rate = 100 * MHz;
753 		else if (sel == PCLK_BUS_SEL_75M)
754 			rate = 75 * MHz;
755 		else if (sel == PCLK_BUS_SEL_50M)
756 			rate = 50 * MHz;
757 		else
758 			rate = OSC_HZ;
759 		break;
760 	default:
761 		return -ENOENT;
762 	}
763 
764 	return rate;
765 }
766 
rk3568_bus_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)767 static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
768 				ulong clk_id, ulong rate)
769 {
770 	struct rk3568_cru *cru = priv->cru;
771 	int src_clk;
772 
773 	switch (clk_id) {
774 	case ACLK_BUS:
775 		if (rate == 200 * MHz)
776 			src_clk = ACLK_BUS_SEL_200M;
777 		else if (rate == 150 * MHz)
778 			src_clk = ACLK_BUS_SEL_150M;
779 		else if (rate == 100 * MHz)
780 			src_clk = ACLK_BUS_SEL_100M;
781 		else
782 			src_clk = ACLK_BUS_SEL_24M;
783 		rk_clrsetreg(&cru->clksel_con[50],
784 			     ACLK_BUS_SEL_MASK,
785 			     src_clk << ACLK_BUS_SEL_SHIFT);
786 		break;
787 	case PCLK_BUS:
788 	case PCLK_WDT_NS:
789 		if (rate == 100 * MHz)
790 			src_clk = PCLK_BUS_SEL_100M;
791 		else if (rate == 75 * MHz)
792 			src_clk = PCLK_BUS_SEL_75M;
793 		else if (rate == 50 * MHz)
794 			src_clk = PCLK_BUS_SEL_50M;
795 		else
796 			src_clk = PCLK_BUS_SEL_24M;
797 		rk_clrsetreg(&cru->clksel_con[50],
798 			     PCLK_BUS_SEL_MASK,
799 			     src_clk << PCLK_BUS_SEL_SHIFT);
800 		break;
801 
802 	default:
803 		printf("do not support this bus freq\n");
804 		return -EINVAL;
805 	}
806 
807 	return rk3568_bus_get_clk(priv, clk_id);
808 }
809 
rk3568_perimid_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)810 static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
811 {
812 	struct rk3568_cru *cru = priv->cru;
813 	u32 con, sel, rate;
814 
815 	switch (clk_id) {
816 	case ACLK_PERIMID:
817 		con = readl(&cru->clksel_con[10]);
818 		sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
819 		if (sel == ACLK_PERIMID_SEL_300M)
820 			rate = 300 * MHz;
821 		else if (sel == ACLK_PERIMID_SEL_200M)
822 			rate = 200 * MHz;
823 		else if (sel == ACLK_PERIMID_SEL_100M)
824 			rate = 100 * MHz;
825 		else
826 			rate = OSC_HZ;
827 		break;
828 	case HCLK_PERIMID:
829 		con = readl(&cru->clksel_con[10]);
830 		sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
831 		if (sel == HCLK_PERIMID_SEL_150M)
832 			rate = 150 * MHz;
833 		else if (sel == HCLK_PERIMID_SEL_100M)
834 			rate = 100 * MHz;
835 		else if (sel == HCLK_PERIMID_SEL_75M)
836 			rate = 75 * MHz;
837 		else
838 			rate = OSC_HZ;
839 		break;
840 	default:
841 		return -ENOENT;
842 	}
843 
844 	return rate;
845 }
846 
rk3568_perimid_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)847 static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
848 				    ulong clk_id, ulong rate)
849 {
850 	struct rk3568_cru *cru = priv->cru;
851 	int src_clk;
852 
853 	switch (clk_id) {
854 	case ACLK_PERIMID:
855 		if (rate == 300 * MHz)
856 			src_clk = ACLK_PERIMID_SEL_300M;
857 		else if (rate == 200 * MHz)
858 			src_clk = ACLK_PERIMID_SEL_200M;
859 		else if (rate == 100 * MHz)
860 			src_clk = ACLK_PERIMID_SEL_100M;
861 		else
862 			src_clk = ACLK_PERIMID_SEL_24M;
863 		rk_clrsetreg(&cru->clksel_con[10],
864 			     ACLK_PERIMID_SEL_MASK,
865 			     src_clk << ACLK_PERIMID_SEL_SHIFT);
866 		break;
867 	case HCLK_PERIMID:
868 		if (rate == 150 * MHz)
869 			src_clk = HCLK_PERIMID_SEL_150M;
870 		else if (rate == 100 * MHz)
871 			src_clk = HCLK_PERIMID_SEL_100M;
872 		else if (rate == 75 * MHz)
873 			src_clk = HCLK_PERIMID_SEL_75M;
874 		else
875 			src_clk = HCLK_PERIMID_SEL_24M;
876 		rk_clrsetreg(&cru->clksel_con[10],
877 			     HCLK_PERIMID_SEL_MASK,
878 			     src_clk << HCLK_PERIMID_SEL_SHIFT);
879 		break;
880 
881 	default:
882 		printf("do not support this permid freq\n");
883 		return -EINVAL;
884 	}
885 
886 	return rk3568_perimid_get_clk(priv, clk_id);
887 }
888 
rk3568_top_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)889 static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
890 {
891 	struct rk3568_cru *cru = priv->cru;
892 	u32 con, sel, rate;
893 
894 	switch (clk_id) {
895 	case ACLK_TOP_HIGH:
896 		con = readl(&cru->clksel_con[73]);
897 		sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
898 		if (sel == ACLK_TOP_HIGH_SEL_500M)
899 			rate = 500 * MHz;
900 		else if (sel == ACLK_TOP_HIGH_SEL_400M)
901 			rate = 400 * MHz;
902 		else if (sel == ACLK_TOP_HIGH_SEL_300M)
903 			rate = 300 * MHz;
904 		else
905 			rate = OSC_HZ;
906 		break;
907 	case ACLK_TOP_LOW:
908 		con = readl(&cru->clksel_con[73]);
909 		sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
910 		if (sel == ACLK_TOP_LOW_SEL_400M)
911 			rate = 400 * MHz;
912 		else if (sel == ACLK_TOP_LOW_SEL_300M)
913 			rate = 300 * MHz;
914 		else if (sel == ACLK_TOP_LOW_SEL_200M)
915 			rate = 200 * MHz;
916 		else
917 			rate = OSC_HZ;
918 		break;
919 	case HCLK_TOP:
920 		con = readl(&cru->clksel_con[73]);
921 		sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
922 		if (sel == HCLK_TOP_SEL_150M)
923 			rate = 150 * MHz;
924 		else if (sel == HCLK_TOP_SEL_100M)
925 			rate = 100 * MHz;
926 		else if (sel == HCLK_TOP_SEL_75M)
927 			rate = 75 * MHz;
928 		else
929 			rate = OSC_HZ;
930 		break;
931 	case PCLK_TOP:
932 		con = readl(&cru->clksel_con[73]);
933 		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
934 		if (sel == PCLK_TOP_SEL_100M)
935 			rate = 100 * MHz;
936 		else if (sel == PCLK_TOP_SEL_75M)
937 			rate = 75 * MHz;
938 		else if (sel == PCLK_TOP_SEL_50M)
939 			rate = 50 * MHz;
940 		else
941 			rate = OSC_HZ;
942 		break;
943 	default:
944 		return -ENOENT;
945 	}
946 
947 	return rate;
948 }
949 
rk3568_top_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)950 static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
951 				ulong clk_id, ulong rate)
952 {
953 	struct rk3568_cru *cru = priv->cru;
954 	int src_clk;
955 
956 	switch (clk_id) {
957 	case ACLK_TOP_HIGH:
958 		if (rate == 500 * MHz)
959 			src_clk = ACLK_TOP_HIGH_SEL_500M;
960 		else if (rate == 400 * MHz)
961 			src_clk = ACLK_TOP_HIGH_SEL_400M;
962 		else if (rate == 300 * MHz)
963 			src_clk = ACLK_TOP_HIGH_SEL_300M;
964 		else
965 			src_clk = ACLK_TOP_HIGH_SEL_24M;
966 		rk_clrsetreg(&cru->clksel_con[73],
967 			     ACLK_TOP_HIGH_SEL_MASK,
968 			     src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
969 		break;
970 	case ACLK_TOP_LOW:
971 		if (rate == 400 * MHz)
972 			src_clk = ACLK_TOP_LOW_SEL_400M;
973 		else if (rate == 300 * MHz)
974 			src_clk = ACLK_TOP_LOW_SEL_300M;
975 		else if (rate == 200 * MHz)
976 			src_clk = ACLK_TOP_LOW_SEL_200M;
977 		else
978 			src_clk = ACLK_TOP_LOW_SEL_24M;
979 		rk_clrsetreg(&cru->clksel_con[73],
980 			     ACLK_TOP_LOW_SEL_MASK,
981 			     src_clk << ACLK_TOP_LOW_SEL_SHIFT);
982 		break;
983 	case HCLK_TOP:
984 		if (rate == 150 * MHz)
985 			src_clk = HCLK_TOP_SEL_150M;
986 		else if (rate == 100 * MHz)
987 			src_clk = HCLK_TOP_SEL_100M;
988 		else if (rate == 75 * MHz)
989 			src_clk = HCLK_TOP_SEL_75M;
990 		else
991 			src_clk = HCLK_TOP_SEL_24M;
992 		rk_clrsetreg(&cru->clksel_con[73],
993 			     HCLK_TOP_SEL_MASK,
994 			     src_clk << HCLK_TOP_SEL_SHIFT);
995 		break;
996 	case PCLK_TOP:
997 		if (rate == 100 * MHz)
998 			src_clk = PCLK_TOP_SEL_100M;
999 		else if (rate == 75 * MHz)
1000 			src_clk = PCLK_TOP_SEL_75M;
1001 		else if (rate == 50 * MHz)
1002 			src_clk = PCLK_TOP_SEL_50M;
1003 		else
1004 			src_clk = PCLK_TOP_SEL_24M;
1005 		rk_clrsetreg(&cru->clksel_con[73],
1006 			     PCLK_TOP_SEL_MASK,
1007 			     src_clk << PCLK_TOP_SEL_SHIFT);
1008 		break;
1009 
1010 	default:
1011 		printf("do not support this permid freq\n");
1012 		return -EINVAL;
1013 	}
1014 
1015 	return rk3568_top_get_clk(priv, clk_id);
1016 }
1017 
rk3568_i2c_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1018 static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1019 {
1020 	struct rk3568_cru *cru = priv->cru;
1021 	u32 sel, con;
1022 	ulong rate;
1023 
1024 	switch (clk_id) {
1025 	case CLK_I2C1:
1026 	case CLK_I2C2:
1027 	case CLK_I2C3:
1028 	case CLK_I2C4:
1029 	case CLK_I2C5:
1030 		con = readl(&cru->clksel_con[71]);
1031 		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
1032 		if (sel == CLK_I2C_SEL_200M)
1033 			rate = 200 * MHz;
1034 		else if (sel == CLK_I2C_SEL_100M)
1035 			rate = 100 * MHz;
1036 		else if (sel == CLK_I2C_SEL_CPLL_100M)
1037 			rate = 100 * MHz;
1038 		else
1039 			rate = OSC_HZ;
1040 		break;
1041 	default:
1042 		return -ENOENT;
1043 	}
1044 
1045 	return rate;
1046 }
1047 
rk3568_i2c_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1048 static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1049 				ulong rate)
1050 {
1051 	struct rk3568_cru *cru = priv->cru;
1052 	int src_clk;
1053 
1054 	if (rate == 200 * MHz)
1055 		src_clk = CLK_I2C_SEL_200M;
1056 	else if (rate == 100 * MHz)
1057 		src_clk = CLK_I2C_SEL_100M;
1058 	else
1059 		src_clk = CLK_I2C_SEL_24M;
1060 
1061 	switch (clk_id) {
1062 	case CLK_I2C1:
1063 	case CLK_I2C2:
1064 	case CLK_I2C3:
1065 	case CLK_I2C4:
1066 	case CLK_I2C5:
1067 		rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1068 			     src_clk << CLK_I2C_SEL_SHIFT);
1069 		break;
1070 	default:
1071 		return -ENOENT;
1072 	}
1073 
1074 	return rk3568_i2c_get_clk(priv, clk_id);
1075 }
1076 
rk3568_spi_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1077 static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1078 {
1079 	struct rk3568_cru *cru = priv->cru;
1080 	u32 sel, con;
1081 
1082 	con = readl(&cru->clksel_con[72]);
1083 
1084 	switch (clk_id) {
1085 	case CLK_SPI0:
1086 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1087 		break;
1088 	case CLK_SPI1:
1089 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1090 		break;
1091 	case CLK_SPI2:
1092 		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1093 		break;
1094 	case CLK_SPI3:
1095 		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1096 		break;
1097 	default:
1098 		return -ENOENT;
1099 	}
1100 
1101 	switch (sel) {
1102 	case CLK_SPI_SEL_200M:
1103 		return 200 * MHz;
1104 	case CLK_SPI_SEL_24M:
1105 		return OSC_HZ;
1106 	case CLK_SPI_SEL_CPLL_100M:
1107 		return 100 * MHz;
1108 	default:
1109 		return -ENOENT;
1110 	}
1111 }
1112 
rk3568_spi_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1113 static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1114 				ulong clk_id, ulong rate)
1115 {
1116 	struct rk3568_cru *cru = priv->cru;
1117 	int src_clk;
1118 
1119 	if (rate == 200 * MHz)
1120 		src_clk = CLK_SPI_SEL_200M;
1121 	else if (rate == 100 * MHz)
1122 		src_clk = CLK_SPI_SEL_CPLL_100M;
1123 	else
1124 		src_clk = CLK_SPI_SEL_24M;
1125 
1126 	switch (clk_id) {
1127 	case CLK_SPI0:
1128 		rk_clrsetreg(&cru->clksel_con[72],
1129 			     CLK_SPI0_SEL_MASK,
1130 			     src_clk << CLK_SPI0_SEL_SHIFT);
1131 		break;
1132 	case CLK_SPI1:
1133 		rk_clrsetreg(&cru->clksel_con[72],
1134 			     CLK_SPI1_SEL_MASK,
1135 			     src_clk << CLK_SPI1_SEL_SHIFT);
1136 		break;
1137 	case CLK_SPI2:
1138 		rk_clrsetreg(&cru->clksel_con[72],
1139 			     CLK_SPI2_SEL_MASK,
1140 			     src_clk << CLK_SPI2_SEL_SHIFT);
1141 		break;
1142 	case CLK_SPI3:
1143 		rk_clrsetreg(&cru->clksel_con[72],
1144 			     CLK_SPI3_SEL_MASK,
1145 			     src_clk << CLK_SPI3_SEL_SHIFT);
1146 		break;
1147 	default:
1148 		return -ENOENT;
1149 	}
1150 
1151 	return rk3568_spi_get_clk(priv, clk_id);
1152 }
1153 
rk3568_pwm_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1154 static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1155 {
1156 	struct rk3568_cru *cru = priv->cru;
1157 	u32 sel, con;
1158 
1159 	con = readl(&cru->clksel_con[72]);
1160 
1161 	switch (clk_id) {
1162 	case CLK_PWM1:
1163 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
1164 		break;
1165 	case CLK_PWM2:
1166 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1167 		break;
1168 	case CLK_PWM3:
1169 		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1170 		break;
1171 	default:
1172 		return -ENOENT;
1173 	}
1174 
1175 	switch (sel) {
1176 	case CLK_PWM_SEL_100M:
1177 		return 100 * MHz;
1178 	case CLK_PWM_SEL_24M:
1179 		return OSC_HZ;
1180 	case CLK_PWM_SEL_CPLL_100M:
1181 		return 100 * MHz;
1182 	default:
1183 		return -ENOENT;
1184 	}
1185 }
1186 
rk3568_pwm_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1187 static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1188 				ulong clk_id, ulong rate)
1189 {
1190 	struct rk3568_cru *cru = priv->cru;
1191 	int src_clk;
1192 
1193 	if (rate == 100 * MHz)
1194 		src_clk = CLK_PWM_SEL_100M;
1195 	else
1196 		src_clk = CLK_PWM_SEL_24M;
1197 
1198 	switch (clk_id) {
1199 	case CLK_PWM1:
1200 		rk_clrsetreg(&cru->clksel_con[72],
1201 			     CLK_PWM1_SEL_MASK,
1202 			     src_clk << CLK_PWM1_SEL_SHIFT);
1203 		break;
1204 	case CLK_PWM2:
1205 		rk_clrsetreg(&cru->clksel_con[72],
1206 			     CLK_PWM2_SEL_MASK,
1207 			     src_clk << CLK_PWM2_SEL_SHIFT);
1208 		break;
1209 	case CLK_PWM3:
1210 		rk_clrsetreg(&cru->clksel_con[72],
1211 			     CLK_PWM3_SEL_MASK,
1212 			     src_clk << CLK_PWM3_SEL_SHIFT);
1213 		break;
1214 	default:
1215 		return -ENOENT;
1216 	}
1217 
1218 	return rk3568_pwm_get_clk(priv, clk_id);
1219 }
1220 
rk3568_adc_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1221 static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1222 {
1223 	struct rk3568_cru *cru = priv->cru;
1224 	u32 div, sel, con, prate;
1225 
1226 	switch (clk_id) {
1227 	case CLK_SARADC:
1228 		return OSC_HZ;
1229 	case CLK_TSADC_TSEN:
1230 		con = readl(&cru->clksel_con[51]);
1231 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
1232 		      CLK_TSADC_TSEN_DIV_SHIFT;
1233 		sel = (con & CLK_TSADC_TSEN_SEL_MASK) >>
1234 		      CLK_TSADC_TSEN_SEL_SHIFT;
1235 		if (sel == CLK_TSADC_TSEN_SEL_24M)
1236 			prate = OSC_HZ;
1237 		else
1238 			prate = 100 * MHz;
1239 		return DIV_TO_RATE(prate, div);
1240 	case CLK_TSADC:
1241 		con = readl(&cru->clksel_con[51]);
1242 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
1243 		prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1244 		return DIV_TO_RATE(prate, div);
1245 	default:
1246 		return -ENOENT;
1247 	}
1248 }
1249 
rk3568_adc_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1250 static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1251 				ulong clk_id, ulong rate)
1252 {
1253 	struct rk3568_cru *cru = priv->cru;
1254 	int src_clk_div;
1255 	ulong prate = 0;
1256 
1257 	switch (clk_id) {
1258 	case CLK_SARADC:
1259 		return OSC_HZ;
1260 	case CLK_TSADC_TSEN:
1261 		if (!(OSC_HZ % rate)) {
1262 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
1263 			assert(src_clk_div - 1 <= 7);
1264 			rk_clrsetreg(&cru->clksel_con[51],
1265 				     CLK_TSADC_TSEN_SEL_MASK |
1266 				     CLK_TSADC_TSEN_DIV_MASK,
1267 				     (CLK_TSADC_TSEN_SEL_24M <<
1268 				      CLK_TSADC_TSEN_SEL_SHIFT) |
1269 				     (src_clk_div - 1) <<
1270 				     CLK_TSADC_TSEN_DIV_SHIFT);
1271 		} else {
1272 			src_clk_div = DIV_ROUND_UP(100 * MHz, rate);
1273 			assert(src_clk_div - 1 <= 7);
1274 			rk_clrsetreg(&cru->clksel_con[51],
1275 				     CLK_TSADC_TSEN_SEL_MASK |
1276 				     CLK_TSADC_TSEN_DIV_MASK,
1277 				     (CLK_TSADC_TSEN_SEL_100M <<
1278 				      CLK_TSADC_TSEN_SEL_SHIFT) |
1279 				     (src_clk_div - 1) <<
1280 				     CLK_TSADC_TSEN_DIV_SHIFT);
1281 		}
1282 		break;
1283 	case CLK_TSADC:
1284 			prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1285 			src_clk_div = DIV_ROUND_UP(prate, rate);
1286 			assert(src_clk_div - 1 <= 128);
1287 			rk_clrsetreg(&cru->clksel_con[51],
1288 				     CLK_TSADC_DIV_MASK,
1289 				     (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1290 		break;
1291 	default:
1292 		return -ENOENT;
1293 	}
1294 	return rk3568_adc_get_clk(priv, clk_id);
1295 }
1296 
rk3568_crypto_get_rate(struct rk3568_clk_priv * priv,ulong clk_id)1297 static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1298 {
1299 	struct rk3568_cru *cru = priv->cru;
1300 	u32 sel, con;
1301 
1302 	switch (clk_id) {
1303 	case ACLK_SECURE_FLASH:
1304 	case ACLK_CRYPTO_NS:
1305 		con = readl(&cru->clksel_con[27]);
1306 		sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >>
1307 		      ACLK_SECURE_FLASH_SEL_SHIFT;
1308 		if (sel == ACLK_SECURE_FLASH_SEL_200M)
1309 			return 200 * MHz;
1310 		else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1311 			return 150 * MHz;
1312 		else if (sel == ACLK_SECURE_FLASH_SEL_100M)
1313 			return 100 * MHz;
1314 		else
1315 			return 24 * MHz;
1316 	case HCLK_SECURE_FLASH:
1317 	case HCLK_CRYPTO_NS:
1318 	case CLK_CRYPTO_NS_RNG:
1319 		con = readl(&cru->clksel_con[27]);
1320 		sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >>
1321 		      HCLK_SECURE_FLASH_SEL_SHIFT;
1322 		if (sel == HCLK_SECURE_FLASH_SEL_150M)
1323 			return 150 * MHz;
1324 		else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1325 			return 100 * MHz;
1326 		else if (sel == HCLK_SECURE_FLASH_SEL_75M)
1327 			return 75 * MHz;
1328 		else
1329 			return 24 * MHz;
1330 	case CLK_CRYPTO_NS_CORE:
1331 		con = readl(&cru->clksel_con[27]);
1332 		sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >>
1333 		      CLK_CRYPTO_CORE_SEL_SHIFT;
1334 		if (sel == CLK_CRYPTO_CORE_SEL_200M)
1335 			return 200 * MHz;
1336 		else if (sel == CLK_CRYPTO_CORE_SEL_150M)
1337 			return 150 * MHz;
1338 		else
1339 			return 100 * MHz;
1340 	case CLK_CRYPTO_NS_PKA:
1341 		con = readl(&cru->clksel_con[27]);
1342 		sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >>
1343 		      CLK_CRYPTO_PKA_SEL_SHIFT;
1344 		if (sel == CLK_CRYPTO_PKA_SEL_300M)
1345 			return 300 * MHz;
1346 		else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1347 			return 200 * MHz;
1348 		else
1349 			return 100 * MHz;
1350 	default:
1351 		return -ENOENT;
1352 	}
1353 }
1354 
rk3568_crypto_set_rate(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1355 static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1356 				    ulong clk_id, ulong rate)
1357 {
1358 	struct rk3568_cru *cru = priv->cru;
1359 	u32 src_clk, mask, shift;
1360 
1361 	switch (clk_id) {
1362 	case ACLK_SECURE_FLASH:
1363 	case ACLK_CRYPTO_NS:
1364 		mask = ACLK_SECURE_FLASH_SEL_MASK;
1365 		shift = ACLK_SECURE_FLASH_SEL_SHIFT;
1366 		if (rate == 200 * MHz)
1367 			src_clk = ACLK_SECURE_FLASH_SEL_200M;
1368 		else if (rate == 150 * MHz)
1369 			src_clk = ACLK_SECURE_FLASH_SEL_150M;
1370 		else if (rate == 100 * MHz)
1371 			src_clk = ACLK_SECURE_FLASH_SEL_100M;
1372 		else
1373 			src_clk = ACLK_SECURE_FLASH_SEL_24M;
1374 		break;
1375 	case HCLK_SECURE_FLASH:
1376 	case HCLK_CRYPTO_NS:
1377 	case CLK_CRYPTO_NS_RNG:
1378 		mask = HCLK_SECURE_FLASH_SEL_MASK;
1379 		shift = HCLK_SECURE_FLASH_SEL_SHIFT;
1380 		if (rate == 150 * MHz)
1381 			src_clk = HCLK_SECURE_FLASH_SEL_150M;
1382 		else if (rate == 100 * MHz)
1383 			src_clk = HCLK_SECURE_FLASH_SEL_100M;
1384 		else if (rate == 75 * MHz)
1385 			src_clk = HCLK_SECURE_FLASH_SEL_75M;
1386 		else
1387 			src_clk = HCLK_SECURE_FLASH_SEL_24M;
1388 		break;
1389 	case CLK_CRYPTO_NS_CORE:
1390 		mask = CLK_CRYPTO_CORE_SEL_MASK;
1391 		shift = CLK_CRYPTO_CORE_SEL_SHIFT;
1392 		if (rate == 200 * MHz)
1393 			src_clk = CLK_CRYPTO_CORE_SEL_200M;
1394 		else if (rate == 150 * MHz)
1395 			src_clk = CLK_CRYPTO_CORE_SEL_150M;
1396 		else
1397 			src_clk = CLK_CRYPTO_CORE_SEL_100M;
1398 		break;
1399 	case CLK_CRYPTO_NS_PKA:
1400 		mask = CLK_CRYPTO_PKA_SEL_MASK;
1401 		shift = CLK_CRYPTO_PKA_SEL_SHIFT;
1402 		if (rate == 300 * MHz)
1403 			src_clk = CLK_CRYPTO_PKA_SEL_300M;
1404 		else if (rate == 200 * MHz)
1405 			src_clk = CLK_CRYPTO_PKA_SEL_200M;
1406 		else
1407 			src_clk = CLK_CRYPTO_PKA_SEL_100M;
1408 		break;
1409 	default:
1410 		return -ENOENT;
1411 	}
1412 
1413 	rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1414 
1415 	return rk3568_crypto_get_rate(priv, clk_id);
1416 }
1417 
rk3568_sdmmc_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1418 static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1419 {
1420 	struct rk3568_cru *cru = priv->cru;
1421 	u32 sel, con;
1422 
1423 	switch (clk_id) {
1424 	case HCLK_SDMMC0:
1425 	case CLK_SDMMC0:
1426 		con = readl(&cru->clksel_con[30]);
1427 		sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1428 		break;
1429 	case CLK_SDMMC1:
1430 		con = readl(&cru->clksel_con[30]);
1431 		sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1432 		break;
1433 	case CLK_SDMMC2:
1434 		con = readl(&cru->clksel_con[32]);
1435 		sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1436 		break;
1437 	default:
1438 		return -ENOENT;
1439 	}
1440 
1441 	switch (sel) {
1442 	case CLK_SDMMC_SEL_24M:
1443 		return OSC_HZ;
1444 	case CLK_SDMMC_SEL_400M:
1445 		return 400 * MHz;
1446 	case CLK_SDMMC_SEL_300M:
1447 		return 300 * MHz;
1448 	case CLK_SDMMC_SEL_100M:
1449 		return 100 * MHz;
1450 	case CLK_SDMMC_SEL_50M:
1451 		return 50 * MHz;
1452 	case CLK_SDMMC_SEL_750K:
1453 		return 750 * KHz;
1454 	default:
1455 		return -ENOENT;
1456 	}
1457 }
1458 
rk3568_sdmmc_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1459 static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1460 				  ulong clk_id, ulong rate)
1461 {
1462 	struct rk3568_cru *cru = priv->cru;
1463 	int src_clk;
1464 
1465 	switch (rate) {
1466 	case OSC_HZ:
1467 	case 26 * MHz:
1468 		src_clk = CLK_SDMMC_SEL_24M;
1469 		break;
1470 	case 400 * MHz:
1471 		src_clk = CLK_SDMMC_SEL_400M;
1472 		break;
1473 	case 300 * MHz:
1474 		src_clk = CLK_SDMMC_SEL_300M;
1475 		break;
1476 	case 100 * MHz:
1477 		src_clk = CLK_SDMMC_SEL_100M;
1478 		break;
1479 	case 52 * MHz:
1480 	case 50 * MHz:
1481 		src_clk = CLK_SDMMC_SEL_50M;
1482 		break;
1483 	case 750 * KHz:
1484 	case 400 * KHz:
1485 		src_clk = CLK_SDMMC_SEL_750K;
1486 		break;
1487 	default:
1488 		return -ENOENT;
1489 	}
1490 
1491 	switch (clk_id) {
1492 	case HCLK_SDMMC0:
1493 	case CLK_SDMMC0:
1494 		rk_clrsetreg(&cru->clksel_con[30],
1495 			     CLK_SDMMC0_SEL_MASK,
1496 			     src_clk << CLK_SDMMC0_SEL_SHIFT);
1497 		break;
1498 	case CLK_SDMMC1:
1499 		rk_clrsetreg(&cru->clksel_con[30],
1500 			     CLK_SDMMC1_SEL_MASK,
1501 			     src_clk << CLK_SDMMC1_SEL_SHIFT);
1502 		break;
1503 	case CLK_SDMMC2:
1504 		rk_clrsetreg(&cru->clksel_con[32],
1505 			     CLK_SDMMC2_SEL_MASK,
1506 			     src_clk << CLK_SDMMC2_SEL_SHIFT);
1507 		break;
1508 	default:
1509 		return -ENOENT;
1510 	}
1511 
1512 	return rk3568_sdmmc_get_clk(priv, clk_id);
1513 }
1514 
rk3568_sfc_get_clk(struct rk3568_clk_priv * priv)1515 static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1516 {
1517 	struct rk3568_cru *cru = priv->cru;
1518 	u32 sel, con;
1519 
1520 	con = readl(&cru->clksel_con[28]);
1521 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1522 	switch (sel) {
1523 	case SCLK_SFC_SEL_24M:
1524 		return OSC_HZ;
1525 	case SCLK_SFC_SEL_50M:
1526 		return 50 * MHz;
1527 	case SCLK_SFC_SEL_75M:
1528 		return 75 * MHz;
1529 	case SCLK_SFC_SEL_100M:
1530 		return 100 * MHz;
1531 	case SCLK_SFC_SEL_125M:
1532 		return 125 * MHz;
1533 	case SCLK_SFC_SEL_150M:
1534 		return 150 * MHz;
1535 	default:
1536 		return -ENOENT;
1537 	}
1538 }
1539 
rk3568_sfc_set_clk(struct rk3568_clk_priv * priv,ulong rate)1540 static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1541 {
1542 	struct rk3568_cru *cru = priv->cru;
1543 	int src_clk;
1544 
1545 	switch (rate) {
1546 	case OSC_HZ:
1547 		src_clk = SCLK_SFC_SEL_24M;
1548 		break;
1549 	case 50 * MHz:
1550 		src_clk = SCLK_SFC_SEL_50M;
1551 		break;
1552 	case 75 * MHz:
1553 		src_clk = SCLK_SFC_SEL_75M;
1554 		break;
1555 	case 100 * MHz:
1556 		src_clk = SCLK_SFC_SEL_100M;
1557 		break;
1558 	case 125 * MHz:
1559 		src_clk = SCLK_SFC_SEL_125M;
1560 		break;
1561 	case 150 * MHz:
1562 		src_clk = SCLK_SFC_SEL_150M;
1563 		break;
1564 	default:
1565 		return -ENOENT;
1566 	}
1567 
1568 	rk_clrsetreg(&cru->clksel_con[28],
1569 		     SCLK_SFC_SEL_MASK,
1570 		     src_clk << SCLK_SFC_SEL_SHIFT);
1571 
1572 	return rk3568_sfc_get_clk(priv);
1573 }
1574 
rk3568_nand_get_clk(struct rk3568_clk_priv * priv)1575 static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1576 {
1577 	struct rk3568_cru *cru = priv->cru;
1578 	u32 sel, con;
1579 
1580 	con = readl(&cru->clksel_con[28]);
1581 	sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1582 	switch (sel) {
1583 	case NCLK_NANDC_SEL_200M:
1584 		return 200 * MHz;
1585 	case NCLK_NANDC_SEL_150M:
1586 		return 150 * MHz;
1587 	case NCLK_NANDC_SEL_100M:
1588 		return 100 * MHz;
1589 	case NCLK_NANDC_SEL_24M:
1590 		return OSC_HZ;
1591 	default:
1592 		return -ENOENT;
1593 	}
1594 }
1595 
rk3568_nand_set_clk(struct rk3568_clk_priv * priv,ulong rate)1596 static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1597 {
1598 	struct rk3568_cru *cru = priv->cru;
1599 	int src_clk;
1600 
1601 	switch (rate) {
1602 	case OSC_HZ:
1603 		src_clk = NCLK_NANDC_SEL_24M;
1604 		break;
1605 	case 100 * MHz:
1606 		src_clk = NCLK_NANDC_SEL_100M;
1607 		break;
1608 	case 150 * MHz:
1609 		src_clk = NCLK_NANDC_SEL_150M;
1610 		break;
1611 	case 200 * MHz:
1612 		src_clk = NCLK_NANDC_SEL_200M;
1613 		break;
1614 	default:
1615 		return -ENOENT;
1616 	}
1617 
1618 	rk_clrsetreg(&cru->clksel_con[28],
1619 		     NCLK_NANDC_SEL_MASK,
1620 		     src_clk << NCLK_NANDC_SEL_SHIFT);
1621 
1622 	return rk3568_nand_get_clk(priv);
1623 }
1624 
rk3568_emmc_get_clk(struct rk3568_clk_priv * priv)1625 static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1626 {
1627 	struct rk3568_cru *cru = priv->cru;
1628 	u32 sel, con;
1629 
1630 	con = readl(&cru->clksel_con[28]);
1631 	sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1632 	switch (sel) {
1633 	case CCLK_EMMC_SEL_200M:
1634 		return 200 * MHz;
1635 	case CCLK_EMMC_SEL_150M:
1636 		return 150 * MHz;
1637 	case CCLK_EMMC_SEL_100M:
1638 		return 100 * MHz;
1639 	case CCLK_EMMC_SEL_50M:
1640 		return 50 * MHz;
1641 	case CCLK_EMMC_SEL_375K:
1642 		return 375 * KHz;
1643 	case CCLK_EMMC_SEL_24M:
1644 		return OSC_HZ;
1645 	default:
1646 		return -ENOENT;
1647 	}
1648 }
1649 
rk3568_emmc_set_clk(struct rk3568_clk_priv * priv,ulong rate)1650 static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1651 {
1652 	struct rk3568_cru *cru = priv->cru;
1653 	int src_clk;
1654 
1655 	switch (rate) {
1656 	case OSC_HZ:
1657 		src_clk = CCLK_EMMC_SEL_24M;
1658 		break;
1659 	case 52 * MHz:
1660 	case 50 * MHz:
1661 		src_clk = CCLK_EMMC_SEL_50M;
1662 		break;
1663 	case 100 * MHz:
1664 		src_clk = CCLK_EMMC_SEL_100M;
1665 		break;
1666 	case 150 * MHz:
1667 		src_clk = CCLK_EMMC_SEL_150M;
1668 		break;
1669 	case 200 * MHz:
1670 		src_clk = CCLK_EMMC_SEL_200M;
1671 		break;
1672 	case 400 * KHz:
1673 	case 375 * KHz:
1674 		src_clk = CCLK_EMMC_SEL_375K;
1675 		break;
1676 	default:
1677 		return -ENOENT;
1678 	}
1679 
1680 	rk_clrsetreg(&cru->clksel_con[28],
1681 		     CCLK_EMMC_SEL_MASK,
1682 		     src_clk << CCLK_EMMC_SEL_SHIFT);
1683 
1684 	return rk3568_emmc_get_clk(priv);
1685 }
1686 
rk3568_emmc_get_bclk(struct rk3568_clk_priv * priv)1687 static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1688 {
1689 	struct rk3568_cru *cru = priv->cru;
1690 	u32 sel, con;
1691 
1692 	con = readl(&cru->clksel_con[28]);
1693 	sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1694 	switch (sel) {
1695 	case BCLK_EMMC_SEL_200M:
1696 		return 200 * MHz;
1697 	case BCLK_EMMC_SEL_150M:
1698 		return 150 * MHz;
1699 	case BCLK_EMMC_SEL_125M:
1700 		return 125 * MHz;
1701 	default:
1702 		return -ENOENT;
1703 	}
1704 }
1705 
rk3568_emmc_set_bclk(struct rk3568_clk_priv * priv,ulong rate)1706 static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1707 {
1708 	struct rk3568_cru *cru = priv->cru;
1709 	int src_clk;
1710 
1711 	switch (rate) {
1712 	case 200 * MHz:
1713 		src_clk = BCLK_EMMC_SEL_200M;
1714 		break;
1715 	case 150 * MHz:
1716 		src_clk = BCLK_EMMC_SEL_150M;
1717 		break;
1718 	case 125 * MHz:
1719 		src_clk = BCLK_EMMC_SEL_125M;
1720 		break;
1721 	default:
1722 		return -ENOENT;
1723 	}
1724 
1725 	rk_clrsetreg(&cru->clksel_con[28],
1726 		     BCLK_EMMC_SEL_MASK,
1727 		     src_clk << BCLK_EMMC_SEL_SHIFT);
1728 
1729 	return rk3568_emmc_get_bclk(priv);
1730 }
1731 
1732 #ifndef CONFIG_SPL_BUILD
rk3568_aclk_vop_get_clk(struct rk3568_clk_priv * priv)1733 static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1734 {
1735 	struct rk3568_cru *cru = priv->cru;
1736 	u32 div, sel, con, parent;
1737 
1738 	con = readl(&cru->clksel_con[38]);
1739 	div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1740 	sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1741 	if (sel == ACLK_VOP_PRE_SEL_GPLL)
1742 		parent = priv->gpll_hz;
1743 	else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1744 		parent = priv->cpll_hz;
1745 	else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1746 		parent = priv->vpll_hz;
1747 	else
1748 		parent = priv->hpll_hz;
1749 
1750 	return DIV_TO_RATE(parent, div);
1751 }
1752 
rk3568_aclk_vop_set_clk(struct rk3568_clk_priv * priv,ulong rate)1753 static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1754 {
1755 	struct rk3568_cru *cru = priv->cru;
1756 	int src_clk_div, src_clk_mux;
1757 
1758 	if ((priv->cpll_hz % rate) == 0) {
1759 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1760 		src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1761 	} else {
1762 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1763 		src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1764 	}
1765 	assert(src_clk_div - 1 <= 31);
1766 	rk_clrsetreg(&cru->clksel_con[38],
1767 		     ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1768 		     src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1769 		     (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1770 
1771 	return rk3568_aclk_vop_get_clk(priv);
1772 }
1773 
rk3568_dclk_vop_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)1774 static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1775 {
1776 	struct rk3568_cru *cru = priv->cru;
1777 	u32 conid, div, sel, con, parent;
1778 
1779 	switch (clk_id) {
1780 	case DCLK_VOP0:
1781 		conid = 39;
1782 		break;
1783 	case DCLK_VOP1:
1784 		conid = 40;
1785 		break;
1786 	case DCLK_VOP2:
1787 		conid = 41;
1788 		break;
1789 	default:
1790 		return -ENOENT;
1791 	}
1792 
1793 	con = readl(&cru->clksel_con[conid]);
1794 	div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1795 	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1796 	if (sel == DCLK_VOP_SEL_HPLL)
1797 		parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1798 	else if (sel == DCLK_VOP_SEL_VPLL)
1799 		parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1800 					       priv->cru, VPLL);
1801 	else if (sel == DCLK_VOP_SEL_GPLL)
1802 		parent = priv->gpll_hz;
1803 	else if (sel == DCLK_VOP_SEL_CPLL)
1804 		parent = priv->cpll_hz;
1805 	else
1806 		return -ENOENT;
1807 
1808 	return DIV_TO_RATE(parent, div);
1809 }
1810 
1811 #define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1812 
rk3568_dclk_vop_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)1813 static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1814 				     ulong clk_id, ulong rate)
1815 {
1816 	struct rk3568_cru *cru = priv->cru;
1817 	ulong pll_rate, now, best_rate = 0;
1818 	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1819 
1820 	switch (clk_id) {
1821 	case DCLK_VOP0:
1822 		conid = 39;
1823 		break;
1824 	case DCLK_VOP1:
1825 		conid = 40;
1826 		break;
1827 	case DCLK_VOP2:
1828 		conid = 41;
1829 		break;
1830 	default:
1831 		return -ENOENT;
1832 	}
1833 
1834 	con = readl(&cru->clksel_con[conid]);
1835 	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1836 
1837 	if (sel == DCLK_VOP_SEL_HPLL) {
1838 		div = 1;
1839 		rk_clrsetreg(&cru->clksel_con[conid],
1840 			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1841 			     (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1842 			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1843 		rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1844 	} else if (sel == DCLK_VOP_SEL_VPLL) {
1845 		div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1846 		rk_clrsetreg(&cru->clksel_con[conid],
1847 			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1848 			     (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1849 			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1850 		rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1851 				      priv->cru, VPLL, div * rate);
1852 	} else {
1853 		for (i = sel; i <= DCLK_VOP_SEL_CPLL; i++) {
1854 			switch (i) {
1855 			case DCLK_VOP_SEL_GPLL:
1856 				pll_rate = priv->gpll_hz;
1857 				break;
1858 			case DCLK_VOP_SEL_CPLL:
1859 				pll_rate = priv->cpll_hz;
1860 				break;
1861 			default:
1862 				printf("do not support this vop pll sel\n");
1863 				return -EINVAL;
1864 			}
1865 
1866 			div = DIV_ROUND_UP(pll_rate, rate);
1867 			if (div > 255)
1868 				continue;
1869 			now = pll_rate / div;
1870 			if (abs(rate - now) < abs(rate - best_rate)) {
1871 				best_rate = now;
1872 				best_div = div;
1873 				best_sel = i;
1874 			}
1875 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1876 			      pll_rate, best_rate, best_div, best_sel);
1877 		}
1878 
1879 		if (best_rate) {
1880 			rk_clrsetreg(&cru->clksel_con[conid],
1881 				     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1882 				     best_sel << DCLK0_VOP_SEL_SHIFT |
1883 				     (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1884 		} else {
1885 			printf("do not support this vop freq %lu\n", rate);
1886 			return -EINVAL;
1887 		}
1888 	}
1889 	return rk3568_dclk_vop_get_clk(priv, clk_id);
1890 }
1891 
rk3568_gmac_src_get_clk(struct rk3568_clk_priv * priv,ulong mac_id)1892 static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1893 				     ulong mac_id)
1894 {
1895 	struct rk3568_cru *cru = priv->cru;
1896 	u32 sel, con;
1897 
1898 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1899 	sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1900 
1901 	switch (sel) {
1902 	case CLK_MAC0_2TOP_SEL_125M:
1903 		return 125 * MHz;
1904 	case CLK_MAC0_2TOP_SEL_50M:
1905 		return 50 * MHz;
1906 	case CLK_MAC0_2TOP_SEL_25M:
1907 		return 25 * MHz;
1908 	case CLK_MAC0_2TOP_SEL_PPLL:
1909 		return rk3568_pmu_pll_get_rate(priv, HPLL);
1910 	default:
1911 		return -ENOENT;
1912 	}
1913 }
1914 
rk3568_gmac_src_set_clk(struct rk3568_clk_priv * priv,ulong mac_id,ulong rate)1915 static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1916 				     ulong mac_id, ulong rate)
1917 {
1918 	struct rk3568_cru *cru = priv->cru;
1919 	int src_clk;
1920 
1921 	switch (rate) {
1922 	case 125 * MHz:
1923 		src_clk = CLK_MAC0_2TOP_SEL_125M;
1924 		break;
1925 	case 50 * MHz:
1926 		src_clk = CLK_MAC0_2TOP_SEL_50M;
1927 		break;
1928 	case 25 * MHz:
1929 		src_clk = CLK_MAC0_2TOP_SEL_25M;
1930 		break;
1931 	default:
1932 		return -ENOENT;
1933 	}
1934 
1935 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1936 		     CLK_MAC0_2TOP_SEL_MASK,
1937 		     src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1938 
1939 	return rk3568_gmac_src_get_clk(priv, mac_id);
1940 }
1941 
rk3568_gmac_out_get_clk(struct rk3568_clk_priv * priv,ulong mac_id)1942 static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1943 				     ulong mac_id)
1944 {
1945 	struct rk3568_cru *cru = priv->cru;
1946 	u32 sel, con;
1947 
1948 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1949 	sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1950 
1951 	switch (sel) {
1952 	case CLK_MAC0_OUT_SEL_125M:
1953 		return 125 * MHz;
1954 	case CLK_MAC0_OUT_SEL_50M:
1955 		return 50 * MHz;
1956 	case CLK_MAC0_OUT_SEL_25M:
1957 		return 25 * MHz;
1958 	case CLK_MAC0_OUT_SEL_24M:
1959 		return OSC_HZ;
1960 	default:
1961 		return -ENOENT;
1962 	}
1963 }
1964 
rk3568_gmac_out_set_clk(struct rk3568_clk_priv * priv,ulong mac_id,ulong rate)1965 static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1966 				     ulong mac_id, ulong rate)
1967 {
1968 	struct rk3568_cru *cru = priv->cru;
1969 	int src_clk;
1970 
1971 	switch (rate) {
1972 	case 125 * MHz:
1973 		src_clk = CLK_MAC0_OUT_SEL_125M;
1974 		break;
1975 	case 50 * MHz:
1976 		src_clk = CLK_MAC0_OUT_SEL_50M;
1977 		break;
1978 	case 25 * MHz:
1979 		src_clk = CLK_MAC0_OUT_SEL_25M;
1980 		break;
1981 	case 24 * MHz:
1982 		src_clk = CLK_MAC0_OUT_SEL_24M;
1983 		break;
1984 	default:
1985 		return -ENOENT;
1986 	}
1987 
1988 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1989 		     CLK_MAC0_OUT_SEL_MASK,
1990 		     src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1991 
1992 	return rk3568_gmac_out_get_clk(priv, mac_id);
1993 }
1994 
rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv * priv,ulong mac_id)1995 static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1996 					 ulong mac_id)
1997 {
1998 	struct rk3568_cru *cru = priv->cru;
1999 	u32 sel, con;
2000 
2001 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
2002 	sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
2003 
2004 	switch (sel) {
2005 	case CLK_GMAC0_PTP_REF_SEL_62_5M:
2006 		return 62500 * KHz;
2007 	case CLK_GMAC0_PTP_REF_SEL_100M:
2008 		return 100 * MHz;
2009 	case CLK_GMAC0_PTP_REF_SEL_50M:
2010 		return 50 * MHz;
2011 	case CLK_GMAC0_PTP_REF_SEL_24M:
2012 		return OSC_HZ;
2013 	default:
2014 		return -ENOENT;
2015 	}
2016 }
2017 
rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv * priv,ulong mac_id,ulong rate)2018 static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
2019 					 ulong mac_id, ulong rate)
2020 {
2021 	struct rk3568_cru *cru = priv->cru;
2022 	int src_clk;
2023 
2024 	switch (rate) {
2025 	case 62500 * KHz:
2026 		src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2027 		break;
2028 	case 100 * MHz:
2029 		src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2030 		break;
2031 	case 50 * MHz:
2032 		src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2033 		break;
2034 	case 24 * MHz:
2035 		src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2036 		break;
2037 	default:
2038 		return -ENOENT;
2039 	}
2040 
2041 	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2042 		     CLK_GMAC0_PTP_REF_SEL_MASK,
2043 		     src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2044 
2045 	return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2046 }
2047 
rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv * priv,ulong mac_id,ulong rate)2048 static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2049 				       ulong mac_id, ulong rate)
2050 {
2051 	struct rk3568_cru *cru = priv->cru;
2052 	u32 con, sel, div_sel;
2053 
2054 	con = readl(&cru->clksel_con[31 + mac_id * 2]);
2055 	sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2056 
2057 	if (sel == RMII0_MODE_SEL_RGMII) {
2058 		if (rate == 2500000)
2059 			div_sel = RGMII0_CLK_SEL_2_5M;
2060 		else if (rate == 25000000)
2061 			div_sel = RGMII0_CLK_SEL_25M;
2062 		else
2063 			div_sel = RGMII0_CLK_SEL_125M;
2064 		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2065 			     RGMII0_CLK_SEL_MASK,
2066 			     div_sel << RGMII0_CLK_SEL_SHIFT);
2067 	} else if (sel == RMII0_MODE_SEL_RMII) {
2068 		if (rate == 2500000)
2069 			div_sel = RMII0_CLK_SEL_2_5M;
2070 		else
2071 			div_sel = RMII0_CLK_SEL_25M;
2072 		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2073 			     RMII0_CLK_SEL_MASK,
2074 			     div_sel << RMII0_CLK_SEL_SHIFT);
2075 	}
2076 
2077 	return 0;
2078 }
2079 
rk3568_ebc_get_clk(struct rk3568_clk_priv * priv)2080 static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2081 {
2082 	struct rk3568_cru *cru = priv->cru;
2083 	u32 con, div, p_rate;
2084 
2085 	con = readl(&cru->clksel_con[79]);
2086 	div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2087 	p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2088 
2089 	con = readl(&cru->clksel_con[43]);
2090 	div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2091 	switch (div) {
2092 	case DCLK_EBC_SEL_GPLL_400M:
2093 		return 400 * MHz;
2094 	case DCLK_EBC_SEL_CPLL_333M:
2095 		return p_rate;
2096 	case DCLK_EBC_SEL_GPLL_200M:
2097 		return 200 * MHz;
2098 	default:
2099 		return -ENOENT;
2100 	}
2101 }
2102 
rk3568_ebc_set_clk(struct rk3568_clk_priv * priv,ulong rate)2103 static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2104 {
2105 	struct rk3568_cru *cru = priv->cru;
2106 	int src_clk_div;
2107 
2108 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2109 	assert(src_clk_div - 1 <= 31);
2110 	rk_clrsetreg(&cru->clksel_con[79],
2111 		     CPLL_333M_DIV_MASK,
2112 		     (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2113 	rk_clrsetreg(&cru->clksel_con[43],
2114 		     DCLK_EBC_SEL_MASK,
2115 		     DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2116 
2117 	return rk3568_ebc_get_clk(priv);
2118 }
2119 
rk3568_rkvdec_get_clk(struct rk3568_clk_priv * priv,ulong clk_id)2120 static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2121 {
2122 	struct rk3568_cru *cru = priv->cru;
2123 	u32 con, div, src, p_rate;
2124 
2125 	switch (clk_id) {
2126 	case ACLK_RKVDEC_PRE:
2127 	case ACLK_RKVDEC:
2128 		con = readl(&cru->clksel_con[47]);
2129 		src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2130 		div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2131 		if (src == ACLK_RKVDEC_SEL_CPLL)
2132 			p_rate = priv->cpll_hz;
2133 		else
2134 			p_rate = priv->gpll_hz;
2135 		return DIV_TO_RATE(p_rate, div);
2136 	case CLK_RKVDEC_CORE:
2137 		con = readl(&cru->clksel_con[49]);
2138 		src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2139 		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2140 		div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2141 		      >> CLK_RKVDEC_CORE_DIV_SHIFT;
2142 		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2143 			p_rate = priv->cpll_hz;
2144 		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2145 			p_rate = priv->npll_hz;
2146 		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2147 			p_rate = priv->vpll_hz;
2148 		else
2149 			p_rate = priv->gpll_hz;
2150 		return DIV_TO_RATE(p_rate, div);
2151 	default:
2152 		return -ENOENT;
2153 	}
2154 }
2155 
rk3568_rkvdec_set_clk(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)2156 static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2157 				   ulong clk_id, ulong rate)
2158 {
2159 	struct rk3568_cru *cru = priv->cru;
2160 	int src_clk_div, src, p_rate;
2161 
2162 	switch (clk_id) {
2163 	case ACLK_RKVDEC_PRE:
2164 	case ACLK_RKVDEC:
2165 		src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2166 		      >> ACLK_RKVDEC_SEL_SHIFT;
2167 		if (src == ACLK_RKVDEC_SEL_CPLL)
2168 			p_rate = priv->cpll_hz;
2169 		else
2170 			p_rate = priv->gpll_hz;
2171 		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2172 		assert(src_clk_div - 1 <= 31);
2173 		rk_clrsetreg(&cru->clksel_con[47],
2174 			     ACLK_RKVDEC_SEL_MASK |
2175 			     ACLK_RKVDEC_DIV_MASK,
2176 			     (src << ACLK_RKVDEC_SEL_SHIFT) |
2177 			     (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2178 		break;
2179 	case CLK_RKVDEC_CORE:
2180 		src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2181 		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2182 		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2183 			p_rate = priv->cpll_hz;
2184 		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2185 			p_rate = priv->npll_hz;
2186 		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2187 			p_rate = priv->vpll_hz;
2188 		else
2189 			p_rate = priv->gpll_hz;
2190 		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2191 		assert(src_clk_div - 1 <= 31);
2192 		rk_clrsetreg(&cru->clksel_con[49],
2193 			     CLK_RKVDEC_CORE_SEL_MASK |
2194 			     CLK_RKVDEC_CORE_DIV_MASK,
2195 			     (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2196 			     (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2197 		break;
2198 	default:
2199 		return -ENOENT;
2200 	}
2201 
2202 	return rk3568_rkvdec_get_clk(priv, clk_id);
2203 }
2204 
rk3568_uart_get_rate(struct rk3568_clk_priv * priv,ulong clk_id)2205 static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2206 {
2207 	struct rk3568_cru *cru = priv->cru;
2208 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
2209 	unsigned long m, n;
2210 
2211 	switch (clk_id) {
2212 	case SCLK_UART1:
2213 		reg = 52;
2214 		break;
2215 	case SCLK_UART2:
2216 		reg = 54;
2217 		break;
2218 	case SCLK_UART3:
2219 		reg = 56;
2220 		break;
2221 	case SCLK_UART4:
2222 		reg = 58;
2223 		break;
2224 	case SCLK_UART5:
2225 		reg = 60;
2226 		break;
2227 	case SCLK_UART6:
2228 		reg = 62;
2229 		break;
2230 	case SCLK_UART7:
2231 		reg = 64;
2232 		break;
2233 	case SCLK_UART8:
2234 		reg = 66;
2235 		break;
2236 	case SCLK_UART9:
2237 		reg = 68;
2238 		break;
2239 	default:
2240 		return -ENOENT;
2241 	}
2242 	con = readl(&cru->clksel_con[reg]);
2243 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2244 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2245 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2246 	if (p_src == CLK_UART_SRC_SEL_GPLL)
2247 		p_rate = priv->gpll_hz;
2248 	else if (p_src == CLK_UART_SRC_SEL_CPLL)
2249 		p_rate = priv->cpll_hz;
2250 	else
2251 		p_rate = 480000000;
2252 	if (src == CLK_UART_SEL_SRC) {
2253 		return DIV_TO_RATE(p_rate, div);
2254 	} else if (src == CLK_UART_SEL_FRAC) {
2255 		fracdiv = readl(&cru->clksel_con[reg + 1]);
2256 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2257 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2258 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2259 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2260 		return DIV_TO_RATE(p_rate, div) * n / m;
2261 	} else {
2262 		return OSC_HZ;
2263 	}
2264 }
2265 
rk3568_uart_set_rate(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)2266 static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2267 				  ulong clk_id, ulong rate)
2268 {
2269 	struct rk3568_cru *cru = priv->cru;
2270 	u32 reg, clk_src, uart_src, div;
2271 	unsigned long m = 0, n = 0, val;
2272 
2273 	if (priv->gpll_hz % rate == 0) {
2274 		clk_src = CLK_UART_SRC_SEL_GPLL;
2275 		uart_src = CLK_UART_SEL_SRC;
2276 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2277 	} else if (priv->cpll_hz % rate == 0) {
2278 		clk_src = CLK_UART_SRC_SEL_CPLL;
2279 		uart_src = CLK_UART_SEL_SRC;
2280 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2281 	} else if (rate == OSC_HZ) {
2282 		clk_src = CLK_UART_SRC_SEL_GPLL;
2283 		uart_src = CLK_UART_SEL_XIN24M;
2284 		div = 2;
2285 	} else {
2286 		clk_src = CLK_UART_SRC_SEL_GPLL;
2287 		uart_src = CLK_UART_SEL_FRAC;
2288 		div = 2;
2289 		rational_best_approximation(rate, priv->gpll_hz / div,
2290 					    GENMASK(16 - 1, 0),
2291 					    GENMASK(16 - 1, 0),
2292 					    &m, &n);
2293 	}
2294 
2295 	switch (clk_id) {
2296 	case SCLK_UART1:
2297 		reg = 52;
2298 		break;
2299 	case SCLK_UART2:
2300 		reg = 54;
2301 		break;
2302 	case SCLK_UART3:
2303 		reg = 56;
2304 		break;
2305 	case SCLK_UART4:
2306 		reg = 58;
2307 		break;
2308 	case SCLK_UART5:
2309 		reg = 60;
2310 		break;
2311 	case SCLK_UART6:
2312 		reg = 62;
2313 		break;
2314 	case SCLK_UART7:
2315 		reg = 64;
2316 		break;
2317 	case SCLK_UART8:
2318 		reg = 66;
2319 		break;
2320 	case SCLK_UART9:
2321 		reg = 68;
2322 		break;
2323 	default:
2324 		return -ENOENT;
2325 	}
2326 	rk_clrsetreg(&cru->clksel_con[reg],
2327 		     CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2328 		     CLK_UART_SRC_DIV_MASK,
2329 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2330 		     (uart_src << CLK_UART_SEL_SHIFT) |
2331 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2332 	if (m && n) {
2333 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2334 		writel(val, &cru->clksel_con[reg + 1]);
2335 	}
2336 
2337 	return rk3568_uart_get_rate(priv, clk_id);
2338 }
2339 
rk3568_i2s3_get_rate(struct rk3568_clk_priv * priv,ulong clk_id)2340 static ulong rk3568_i2s3_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2341 {
2342 	struct rk3568_cru *cru = priv->cru;
2343 	struct rk3568_grf *grf = priv->grf;
2344 	u32 con, div, src, p_rate;
2345 	u32 reg, fracdiv, p_src;
2346 	unsigned long m, n;
2347 
2348 	switch (clk_id) {
2349 	case I2S3_MCLKOUT_TX:
2350 		con = readl(&cru->clksel_con[21]);
2351 		src = (con & I2S3_MCLKOUT_TX_SEL_MASK) >>
2352 		      I2S3_MCLKOUT_TX_SEL_SHIFT;
2353 		if (src == I2S3_MCLKOUT_TX_SEL_12M)
2354 			p_rate = 12000000;
2355 		else
2356 			p_rate = rk3568_i2s3_get_rate(priv, MCLK_I2S3_2CH_TX);
2357 		return p_rate;
2358 	case I2S3_MCLKOUT_RX:
2359 		con = readl(&cru->clksel_con[83]);
2360 		src = (con & I2S3_MCLKOUT_TX_SEL_MASK) >>
2361 		      I2S3_MCLKOUT_TX_SEL_SHIFT;
2362 		if (src == I2S3_MCLKOUT_TX_SEL_12M)
2363 			p_rate = 12000000;
2364 		else
2365 			p_rate = rk3568_i2s3_get_rate(priv, MCLK_I2S3_2CH_RX);
2366 		return p_rate;
2367 	case I2S3_MCLKOUT:
2368 		con = readl(&grf->soc_con2);
2369 		src = (con & I2S3_MCLKOUT_SEL_MASK)
2370 		      >> I2S3_MCLKOUT_SEL_SHIFT;
2371 		if (src == I2S3_MCLKOUT_SEL_RX)
2372 			p_rate = rk3568_i2s3_get_rate(priv, I2S3_MCLKOUT_RX);
2373 		else
2374 			p_rate = rk3568_i2s3_get_rate(priv, I2S3_MCLKOUT_TX);
2375 		return p_rate;
2376 	case MCLK_I2S3_2CH_RX:
2377 		reg = 83;
2378 		break;
2379 	case MCLK_I2S3_2CH_TX:
2380 		reg = 21;
2381 		break;
2382 	default:
2383 		return -ENOENT;
2384 	}
2385 
2386 	con = readl(&cru->clksel_con[reg]);
2387 	src = (con & CLK_I2S3_SEL_MASK) >> CLK_I2S3_SEL_SHIFT;
2388 	div = (con & CLK_I2S3_SRC_DIV_MASK) >> CLK_I2S3_SRC_DIV_SHIFT;
2389 	p_src = (con & CLK_I2S3_SRC_SEL_MASK) >> CLK_I2S3_SRC_SEL_SHIFT;
2390 	if (p_src == CLK_I2S3_SRC_SEL_GPLL)
2391 		p_rate = priv->gpll_hz;
2392 	else if (p_src == CLK_I2S3_SRC_SEL_CPLL)
2393 		p_rate = priv->cpll_hz;
2394 	else
2395 		p_rate = priv->npll_hz;
2396 	if (src == CLK_I2S3_SEL_SRC) {
2397 		return DIV_TO_RATE(p_rate, div);
2398 	} else if (src == CLK_I2S3_SEL_FRAC) {
2399 		fracdiv = readl(&cru->clksel_con[reg + 1]);
2400 		n = fracdiv & CLK_I2S3_FRAC_NUMERATOR_MASK;
2401 		n >>= CLK_I2S3_FRAC_NUMERATOR_SHIFT;
2402 		m = fracdiv & CLK_I2S3_FRAC_DENOMINATOR_MASK;
2403 		m >>= CLK_I2S3_FRAC_DENOMINATOR_SHIFT;
2404 		return DIV_TO_RATE(p_rate, div) * n / m;
2405 	} else {
2406 		return OSC_HZ / 2;
2407 	}
2408 }
2409 
rk3568_i2s3_set_rate(struct rk3568_clk_priv * priv,ulong clk_id,ulong rate)2410 static ulong rk3568_i2s3_set_rate(struct rk3568_clk_priv *priv,
2411 				  ulong clk_id, ulong rate)
2412 {
2413 	struct rk3568_cru *cru = priv->cru;
2414 	struct rk3568_grf *grf = priv->grf;
2415 	u32 reg, con, clk_src, i2s_src, div;
2416 	unsigned long m = 0, n = 0, val;
2417 
2418 	if (priv->gpll_hz % rate == 0) {
2419 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2420 		i2s_src = CLK_I2S3_SEL_SRC;
2421 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2422 	} else if (priv->cpll_hz % rate == 0) {
2423 		clk_src = CLK_I2S3_SRC_SEL_CPLL;
2424 		i2s_src = CLK_I2S3_SEL_SRC;
2425 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2426 	} else if (rate == OSC_HZ / 2) {
2427 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2428 		i2s_src = CLK_I2S3_SEL_XIN12M;
2429 		div = 1;
2430 	} else {
2431 		clk_src = CLK_I2S3_SRC_SEL_GPLL;
2432 		i2s_src = CLK_I2S3_SEL_FRAC;
2433 		div = 1;
2434 		rational_best_approximation(rate, priv->gpll_hz / div,
2435 					    GENMASK(16 - 1, 0),
2436 					    GENMASK(16 - 1, 0),
2437 					    &m, &n);
2438 	}
2439 
2440 	switch (clk_id) {
2441 	case I2S3_MCLKOUT_TX:
2442 		if (rate == 12000000) {
2443 			rk_clrsetreg(&cru->clksel_con[21],
2444 				     I2S3_MCLKOUT_TX_SEL_MASK,
2445 				     I2S3_MCLKOUT_TX_SEL_12M <<
2446 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2447 		} else {
2448 			rk3568_i2s3_set_rate(priv, MCLK_I2S3_2CH_TX, rate),
2449 			rk_clrsetreg(&cru->clksel_con[21],
2450 				     I2S3_MCLKOUT_TX_SEL_MASK,
2451 				     I2S3_MCLKOUT_TX_SEL_MCLK <<
2452 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2453 		}
2454 		return rk3568_i2s3_get_rate(priv, clk_id);
2455 	case I2S3_MCLKOUT_RX:
2456 		if (rate == 12000000) {
2457 			rk_clrsetreg(&cru->clksel_con[83],
2458 				     I2S3_MCLKOUT_TX_SEL_MASK,
2459 				     I2S3_MCLKOUT_TX_SEL_12M <<
2460 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2461 		} else {
2462 			rk3568_i2s3_set_rate(priv, MCLK_I2S3_2CH_RX, rate),
2463 			rk_clrsetreg(&cru->clksel_con[21],
2464 				     I2S3_MCLKOUT_TX_SEL_MASK,
2465 				     I2S3_MCLKOUT_TX_SEL_MCLK <<
2466 				     I2S3_MCLKOUT_TX_SEL_SHIFT);
2467 		}
2468 		return rk3568_i2s3_get_rate(priv, clk_id);
2469 	case I2S3_MCLKOUT:
2470 		con = readl(&grf->soc_con2);
2471 		clk_src = (con & I2S3_MCLKOUT_SEL_MASK)
2472 		      >> I2S3_MCLKOUT_SEL_SHIFT;
2473 		if (clk_src == I2S3_MCLKOUT_SEL_RX)
2474 			rk3568_i2s3_set_rate(priv, I2S3_MCLKOUT_RX, rate);
2475 		else
2476 			rk3568_i2s3_set_rate(priv, I2S3_MCLKOUT_TX, rate);
2477 		return rk3568_i2s3_get_rate(priv, clk_id);
2478 	case MCLK_I2S3_2CH_RX:
2479 		reg = 83;
2480 		break;
2481 	case MCLK_I2S3_2CH_TX:
2482 		reg = 21;
2483 		break;
2484 	default:
2485 		return -ENOENT;
2486 	}
2487 
2488 	rk_clrsetreg(&cru->clksel_con[reg],
2489 		     CLK_I2S3_SEL_MASK | CLK_I2S3_SRC_SEL_MASK |
2490 		     CLK_I2S3_SRC_DIV_MASK,
2491 		     (clk_src << CLK_I2S3_SRC_SEL_SHIFT) |
2492 		     (i2s_src << CLK_I2S3_SEL_SHIFT) |
2493 		     ((div - 1) << CLK_I2S3_SRC_DIV_SHIFT));
2494 	if (m && n) {
2495 		val = m << CLK_I2S3_FRAC_NUMERATOR_SHIFT | n;
2496 		writel(val, &cru->clksel_con[reg + 1]);
2497 	}
2498 	return rk3568_i2s3_get_rate(priv, clk_id);
2499 }
2500 
2501 #endif
2502 
rk3568_clk_get_rate(struct clk * clk)2503 static ulong rk3568_clk_get_rate(struct clk *clk)
2504 {
2505 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2506 	ulong rate = 0;
2507 
2508 	if (!priv->gpll_hz) {
2509 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2510 		return -ENOENT;
2511 	}
2512 
2513 	switch (clk->id) {
2514 	case PLL_APLL:
2515 	case ARMCLK:
2516 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2517 					     APLL);
2518 		break;
2519 	case PLL_CPLL:
2520 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2521 					     CPLL);
2522 		break;
2523 	case PLL_GPLL:
2524 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2525 					     GPLL);
2526 		break;
2527 	case PLL_NPLL:
2528 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2529 					     NPLL);
2530 		break;
2531 	case PLL_VPLL:
2532 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2533 					     VPLL);
2534 		break;
2535 	case PLL_DPLL:
2536 		rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2537 					     DPLL);
2538 		break;
2539 	case ACLK_BUS:
2540 	case PCLK_BUS:
2541 	case PCLK_WDT_NS:
2542 		rate = rk3568_bus_get_clk(priv, clk->id);
2543 		break;
2544 	case ACLK_PERIMID:
2545 	case HCLK_PERIMID:
2546 		rate = rk3568_perimid_get_clk(priv, clk->id);
2547 		break;
2548 	case ACLK_TOP_HIGH:
2549 	case ACLK_TOP_LOW:
2550 	case HCLK_TOP:
2551 	case PCLK_TOP:
2552 		rate = rk3568_top_get_clk(priv, clk->id);
2553 		break;
2554 	case CLK_I2C1:
2555 	case CLK_I2C2:
2556 	case CLK_I2C3:
2557 	case CLK_I2C4:
2558 	case CLK_I2C5:
2559 		rate = rk3568_i2c_get_clk(priv, clk->id);
2560 		break;
2561 	case CLK_SPI0:
2562 	case CLK_SPI1:
2563 	case CLK_SPI2:
2564 	case CLK_SPI3:
2565 		rate = rk3568_spi_get_clk(priv, clk->id);
2566 		break;
2567 	case CLK_PWM1:
2568 	case CLK_PWM2:
2569 	case CLK_PWM3:
2570 		rate = rk3568_pwm_get_clk(priv, clk->id);
2571 		break;
2572 	case CLK_SARADC:
2573 	case CLK_TSADC_TSEN:
2574 	case CLK_TSADC:
2575 		rate = rk3568_adc_get_clk(priv, clk->id);
2576 		break;
2577 	case HCLK_SDMMC0:
2578 	case CLK_SDMMC0:
2579 	case CLK_SDMMC1:
2580 	case CLK_SDMMC2:
2581 		rate = rk3568_sdmmc_get_clk(priv, clk->id);
2582 		break;
2583 	case SCLK_SFC:
2584 		rate = rk3568_sfc_get_clk(priv);
2585 		break;
2586 	case NCLK_NANDC:
2587 		rate = rk3568_nand_get_clk(priv);
2588 		break;
2589 	case CCLK_EMMC:
2590 		rate = rk3568_emmc_get_clk(priv);
2591 		break;
2592 	case BCLK_EMMC:
2593 		rate = rk3568_emmc_get_bclk(priv);
2594 		break;
2595 	case TCLK_EMMC:
2596 		rate = OSC_HZ;
2597 		break;
2598 #ifndef CONFIG_SPL_BUILD
2599 	case ACLK_VOP:
2600 		rate = rk3568_aclk_vop_get_clk(priv);
2601 		break;
2602 	case DCLK_VOP0:
2603 	case DCLK_VOP1:
2604 	case DCLK_VOP2:
2605 		rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2606 		break;
2607 	case SCLK_GMAC0:
2608 	case CLK_MAC0_2TOP:
2609 	case CLK_MAC0_REFOUT:
2610 		rate = rk3568_gmac_src_get_clk(priv, 0);
2611 		break;
2612 	case CLK_MAC0_OUT:
2613 		rate = rk3568_gmac_out_get_clk(priv, 0);
2614 		break;
2615 	case CLK_GMAC0_PTP_REF:
2616 		rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2617 		break;
2618 	case SCLK_GMAC1:
2619 	case CLK_MAC1_2TOP:
2620 	case CLK_MAC1_REFOUT:
2621 		rate = rk3568_gmac_src_get_clk(priv, 1);
2622 		break;
2623 	case CLK_MAC1_OUT:
2624 		rate = rk3568_gmac_out_get_clk(priv, 1);
2625 		break;
2626 	case CLK_GMAC1_PTP_REF:
2627 		rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2628 		break;
2629 	case DCLK_EBC:
2630 		rate = rk3568_ebc_get_clk(priv);
2631 		break;
2632 	case ACLK_RKVDEC_PRE:
2633 	case ACLK_RKVDEC:
2634 	case CLK_RKVDEC_CORE:
2635 		rate = rk3568_rkvdec_get_clk(priv, clk->id);
2636 		break;
2637 	case TCLK_WDT_NS:
2638 		rate = OSC_HZ;
2639 		break;
2640 	case SCLK_UART1:
2641 	case SCLK_UART2:
2642 	case SCLK_UART3:
2643 	case SCLK_UART4:
2644 	case SCLK_UART5:
2645 	case SCLK_UART6:
2646 	case SCLK_UART7:
2647 	case SCLK_UART8:
2648 	case SCLK_UART9:
2649 		rate = rk3568_uart_get_rate(priv, clk->id);
2650 		break;
2651 	case I2S3_MCLKOUT_RX:
2652 	case I2S3_MCLKOUT_TX:
2653 	case MCLK_I2S3_2CH_RX:
2654 	case MCLK_I2S3_2CH_TX:
2655 	case I2S3_MCLKOUT:
2656 		rate = rk3568_i2s3_get_rate(priv, clk->id);
2657 		break;
2658 #endif
2659 	case ACLK_SECURE_FLASH:
2660 	case ACLK_CRYPTO_NS:
2661 	case HCLK_SECURE_FLASH:
2662 	case HCLK_CRYPTO_NS:
2663 	case CLK_CRYPTO_NS_RNG:
2664 	case CLK_CRYPTO_NS_CORE:
2665 	case CLK_CRYPTO_NS_PKA:
2666 		rate = rk3568_crypto_get_rate(priv, clk->id);
2667 		break;
2668 	case CPLL_500M:
2669 	case CPLL_333M:
2670 	case CPLL_250M:
2671 	case CPLL_125M:
2672 	case CPLL_100M:
2673 	case CPLL_62P5M:
2674 	case CPLL_50M:
2675 	case CPLL_25M:
2676 		rate = rk3568_cpll_div_get_rate(priv, clk->id);
2677 		break;
2678 	default:
2679 		return -ENOENT;
2680 	}
2681 
2682 	return rate;
2683 };
2684 
rk3568_clk_set_rate(struct clk * clk,ulong rate)2685 static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2686 {
2687 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2688 	ulong ret = 0;
2689 
2690 	if (!priv->gpll_hz) {
2691 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2692 		return -ENOENT;
2693 	}
2694 
2695 	switch (clk->id) {
2696 	case PLL_APLL:
2697 	case ARMCLK:
2698 		if (priv->armclk_hz)
2699 			rk3568_armclk_set_clk(priv, rate);
2700 		priv->armclk_hz = rate;
2701 		break;
2702 	case PLL_CPLL:
2703 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2704 					    CPLL, rate);
2705 		priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2706 						      priv->cru, CPLL);
2707 		break;
2708 	case PLL_GPLL:
2709 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2710 					    GPLL, rate);
2711 		priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2712 						      priv->cru, GPLL);
2713 		break;
2714 	case PLL_NPLL:
2715 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2716 					    NPLL, rate);
2717 		break;
2718 	case PLL_VPLL:
2719 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2720 					    VPLL, rate);
2721 		priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2722 						      priv->cru,
2723 						      VPLL);
2724 		break;
2725 	case ACLK_BUS:
2726 	case PCLK_BUS:
2727 	case PCLK_WDT_NS:
2728 		ret = rk3568_bus_set_clk(priv, clk->id, rate);
2729 		break;
2730 	case ACLK_PERIMID:
2731 	case HCLK_PERIMID:
2732 		ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2733 		break;
2734 	case ACLK_TOP_HIGH:
2735 	case ACLK_TOP_LOW:
2736 	case HCLK_TOP:
2737 	case PCLK_TOP:
2738 		ret = rk3568_top_set_clk(priv, clk->id, rate);
2739 		break;
2740 	case CLK_I2C1:
2741 	case CLK_I2C2:
2742 	case CLK_I2C3:
2743 	case CLK_I2C4:
2744 	case CLK_I2C5:
2745 		ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2746 		break;
2747 	case CLK_SPI0:
2748 	case CLK_SPI1:
2749 	case CLK_SPI2:
2750 	case CLK_SPI3:
2751 		ret = rk3568_spi_set_clk(priv, clk->id, rate);
2752 		break;
2753 	case CLK_PWM1:
2754 	case CLK_PWM2:
2755 	case CLK_PWM3:
2756 		ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2757 		break;
2758 	case CLK_SARADC:
2759 	case CLK_TSADC_TSEN:
2760 	case CLK_TSADC:
2761 		ret = rk3568_adc_set_clk(priv, clk->id, rate);
2762 		break;
2763 	case HCLK_SDMMC0:
2764 	case CLK_SDMMC0:
2765 	case CLK_SDMMC1:
2766 	case CLK_SDMMC2:
2767 		ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2768 		break;
2769 	case SCLK_SFC:
2770 		ret = rk3568_sfc_set_clk(priv, rate);
2771 		break;
2772 	case NCLK_NANDC:
2773 		ret = rk3568_nand_set_clk(priv, rate);
2774 		break;
2775 	case CCLK_EMMC:
2776 		ret = rk3568_emmc_set_clk(priv, rate);
2777 		break;
2778 	case BCLK_EMMC:
2779 		ret = rk3568_emmc_set_bclk(priv, rate);
2780 		break;
2781 	case TCLK_EMMC:
2782 		ret = OSC_HZ;
2783 		break;
2784 #ifndef CONFIG_SPL_BUILD
2785 	case ACLK_VOP:
2786 		ret = rk3568_aclk_vop_set_clk(priv, rate);
2787 		break;
2788 	case DCLK_VOP0:
2789 	case DCLK_VOP1:
2790 	case DCLK_VOP2:
2791 		ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2792 		break;
2793 	case SCLK_GMAC0:
2794 	case CLK_MAC0_2TOP:
2795 	case CLK_MAC0_REFOUT:
2796 		ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2797 		break;
2798 	case CLK_MAC0_OUT:
2799 		ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2800 		break;
2801 	case SCLK_GMAC0_RX_TX:
2802 		ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2803 		break;
2804 	case CLK_GMAC0_PTP_REF:
2805 		ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2806 		break;
2807 	case SCLK_GMAC1:
2808 	case CLK_MAC1_2TOP:
2809 	case CLK_MAC1_REFOUT:
2810 		ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2811 		break;
2812 	case CLK_MAC1_OUT:
2813 		ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2814 		break;
2815 	case SCLK_GMAC1_RX_TX:
2816 		ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2817 		break;
2818 	case CLK_GMAC1_PTP_REF:
2819 		ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2820 		break;
2821 	case DCLK_EBC:
2822 		ret = rk3568_ebc_set_clk(priv, rate);
2823 		break;
2824 	case ACLK_RKVDEC_PRE:
2825 	case ACLK_RKVDEC:
2826 	case CLK_RKVDEC_CORE:
2827 		ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2828 		break;
2829 	case TCLK_WDT_NS:
2830 		ret = OSC_HZ;
2831 		break;
2832 	case SCLK_UART1:
2833 	case SCLK_UART2:
2834 	case SCLK_UART3:
2835 	case SCLK_UART4:
2836 	case SCLK_UART5:
2837 	case SCLK_UART6:
2838 	case SCLK_UART7:
2839 	case SCLK_UART8:
2840 	case SCLK_UART9:
2841 		ret = rk3568_uart_set_rate(priv, clk->id, rate);
2842 		break;
2843 	case I2S3_MCLKOUT_RX:
2844 	case I2S3_MCLKOUT_TX:
2845 	case MCLK_I2S3_2CH_RX:
2846 	case MCLK_I2S3_2CH_TX:
2847 	case I2S3_MCLKOUT:
2848 		ret = rk3568_i2s3_set_rate(priv, clk->id, rate);
2849 		break;
2850 #endif
2851 	case ACLK_SECURE_FLASH:
2852 	case ACLK_CRYPTO_NS:
2853 	case HCLK_SECURE_FLASH:
2854 	case HCLK_CRYPTO_NS:
2855 	case CLK_CRYPTO_NS_RNG:
2856 	case CLK_CRYPTO_NS_CORE:
2857 	case CLK_CRYPTO_NS_PKA:
2858 		ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2859 		break;
2860 	case CPLL_500M:
2861 	case CPLL_333M:
2862 	case CPLL_250M:
2863 	case CPLL_125M:
2864 	case CPLL_100M:
2865 	case CPLL_62P5M:
2866 	case CPLL_50M:
2867 	case CPLL_25M:
2868 		ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2869 		break;
2870 	default:
2871 		return -ENOENT;
2872 	}
2873 
2874 	return ret;
2875 };
2876 
2877 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
2878 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
2879 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
2880 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
2881 
2882 #define PSECS_PER_SEC 1000000000000LL
2883 /*
2884  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
2885  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
2886  */
2887 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
2888 
rk3568_mmc_get_phase(struct clk * clk)2889 int rk3568_mmc_get_phase(struct clk *clk)
2890 {
2891 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2892 	struct rk3568_cru *cru = priv->cru;
2893 	u32 raw_value, delay_num;
2894 	u16 degrees = 0;
2895 	ulong rate;
2896 
2897 	rate = rk3568_clk_get_rate(clk);
2898 	if (rate < 0)
2899 		return rate;
2900 
2901 	if (clk->id == SCLK_EMMC_SAMPLE)
2902 		raw_value = readl(&cru->emmc_con[1]);
2903 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
2904 		raw_value = readl(&cru->sdmmc0_con[1]);
2905 	else if (clk->id == SCLK_SDMMC1_SAMPLE)
2906 		raw_value = readl(&cru->sdmmc1_con[1]);
2907 	else
2908 		raw_value = readl(&cru->sdmmc2_con[1]);
2909 
2910 	raw_value >>= 1;
2911 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
2912 
2913 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
2914 		/* degrees/delaynum * 10000 */
2915 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
2916 					36 * (rate / 1000000);
2917 
2918 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
2919 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
2920 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
2921 	}
2922 
2923 	return degrees % 360;
2924 }
2925 
rk3568_mmc_set_phase(struct clk * clk,u32 degrees)2926 int rk3568_mmc_set_phase(struct clk *clk, u32 degrees)
2927 {
2928 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2929 	struct rk3568_cru *cru = priv->cru;
2930 	u8 nineties, remainder, delay_num;
2931 	u32 raw_value, delay;
2932 	ulong rate;
2933 
2934 	rate = rk3568_clk_get_rate(clk);
2935 	if (rate < 0)
2936 		return rate;
2937 
2938 	nineties = degrees / 90;
2939 	remainder = (degrees % 90);
2940 
2941 	/*
2942 	 * Convert to delay; do a little extra work to make sure we
2943 	 * don't overflow 32-bit / 64-bit numbers.
2944 	 */
2945 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
2946 	delay *= remainder;
2947 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
2948 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
2949 
2950 	delay_num = (u8)min_t(u32, delay, 255);
2951 
2952 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
2953 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
2954 	raw_value |= nineties;
2955 
2956 	raw_value <<= 1;
2957 	if (clk->id == SCLK_EMMC_SAMPLE)
2958 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
2959 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
2960 		writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]);
2961 	else if (clk->id == SCLK_SDMMC1_SAMPLE)
2962 		writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]);
2963 	else
2964 		writel(raw_value | 0xffff0000, &cru->sdmmc2_con[1]);
2965 
2966 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
2967 	      degrees, delay_num, raw_value, rk3568_mmc_get_phase(clk));
2968 
2969 	return 0;
2970 }
2971 
rk3568_clk_get_phase(struct clk * clk)2972 static int rk3568_clk_get_phase(struct clk *clk)
2973 {
2974 	int ret;
2975 
2976 	debug("%s %ld\n", __func__, clk->id);
2977 	switch (clk->id) {
2978 	case SCLK_EMMC_SAMPLE:
2979 	case SCLK_SDMMC0_SAMPLE:
2980 	case SCLK_SDMMC1_SAMPLE:
2981 	case SCLK_SDMMC2_SAMPLE:
2982 		ret = rk3568_mmc_get_phase(clk);
2983 		break;
2984 	default:
2985 		return -ENOENT;
2986 	}
2987 
2988 	return ret;
2989 }
2990 
rk3568_clk_set_phase(struct clk * clk,int degrees)2991 static int rk3568_clk_set_phase(struct clk *clk, int degrees)
2992 {
2993 	int ret;
2994 
2995 	debug("%s %ld\n", __func__, clk->id);
2996 	switch (clk->id) {
2997 	case SCLK_EMMC_SAMPLE:
2998 	case SCLK_SDMMC0_SAMPLE:
2999 	case SCLK_SDMMC1_SAMPLE:
3000 	case SCLK_SDMMC2_SAMPLE:
3001 		ret = rk3568_mmc_set_phase(clk, degrees);
3002 		break;
3003 	default:
3004 		return -ENOENT;
3005 	}
3006 
3007 	return ret;
3008 }
3009 
3010 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
rk3568_gmac0_src_set_parent(struct clk * clk,struct clk * parent)3011 static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
3012 {
3013 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3014 	struct rk3568_cru *cru = priv->cru;
3015 
3016 	if (parent->id == CLK_MAC0_2TOP)
3017 		rk_clrsetreg(&cru->clksel_con[31],
3018 			     RMII0_EXTCLK_SEL_MASK,
3019 			     RMII0_EXTCLK_SEL_MAC0_TOP <<
3020 			     RMII0_EXTCLK_SEL_SHIFT);
3021 	else
3022 		rk_clrsetreg(&cru->clksel_con[31],
3023 			     RMII0_EXTCLK_SEL_MASK,
3024 			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
3025 	return 0;
3026 }
3027 
rk3568_gmac1_src_set_parent(struct clk * clk,struct clk * parent)3028 static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
3029 {
3030 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3031 	struct rk3568_cru *cru = priv->cru;
3032 
3033 	if (parent->id == CLK_MAC1_2TOP)
3034 		rk_clrsetreg(&cru->clksel_con[33],
3035 			     RMII0_EXTCLK_SEL_MASK,
3036 			     RMII0_EXTCLK_SEL_MAC0_TOP <<
3037 			     RMII0_EXTCLK_SEL_SHIFT);
3038 	else
3039 		rk_clrsetreg(&cru->clksel_con[33],
3040 			     RMII0_EXTCLK_SEL_MASK,
3041 			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
3042 	return 0;
3043 }
3044 
rk3568_gmac0_tx_rx_set_parent(struct clk * clk,struct clk * parent)3045 static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
3046 {
3047 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3048 	struct rk3568_cru *cru = priv->cru;
3049 
3050 	if (parent->id == SCLK_GMAC0_RGMII_SPEED)
3051 		rk_clrsetreg(&cru->clksel_con[31],
3052 			     RMII0_MODE_MASK,
3053 			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
3054 	else if (parent->id == SCLK_GMAC0_RMII_SPEED)
3055 		rk_clrsetreg(&cru->clksel_con[31],
3056 			     RMII0_MODE_MASK,
3057 			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
3058 	else
3059 		rk_clrsetreg(&cru->clksel_con[31],
3060 			     RMII0_MODE_MASK,
3061 			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
3062 
3063 	return 0;
3064 }
3065 
rk3568_gmac1_tx_rx_set_parent(struct clk * clk,struct clk * parent)3066 static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
3067 {
3068 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3069 	struct rk3568_cru *cru = priv->cru;
3070 
3071 	if (parent->id == SCLK_GMAC1_RGMII_SPEED)
3072 		rk_clrsetreg(&cru->clksel_con[33],
3073 			     RMII0_MODE_MASK,
3074 			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
3075 	else if (parent->id == SCLK_GMAC1_RMII_SPEED)
3076 		rk_clrsetreg(&cru->clksel_con[33],
3077 			     RMII0_MODE_MASK,
3078 			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
3079 	else
3080 		rk_clrsetreg(&cru->clksel_con[33],
3081 			     RMII0_MODE_MASK,
3082 			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
3083 
3084 	return 0;
3085 }
3086 
rk3568_dclk_vop_set_parent(struct clk * clk,struct clk * parent)3087 static int __maybe_unused rk3568_dclk_vop_set_parent(struct clk *clk,
3088 						     struct clk *parent)
3089 {
3090 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3091 	struct rk3568_cru *cru = priv->cru;
3092 	u32 con_id;
3093 
3094 	switch (clk->id) {
3095 	case DCLK_VOP0:
3096 		con_id = 39;
3097 		break;
3098 	case DCLK_VOP1:
3099 		con_id = 40;
3100 		break;
3101 	case DCLK_VOP2:
3102 		con_id = 41;
3103 		break;
3104 	default:
3105 		return -EINVAL;
3106 	}
3107 	if (parent->id == PLL_VPLL) {
3108 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3109 			     DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
3110 	} else if (parent->id == PLL_HPLL) {
3111 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3112 			     DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
3113 	} else if (parent->id == PLL_CPLL) {
3114 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3115 			     DCLK_VOP_SEL_CPLL << DCLK0_VOP_SEL_SHIFT);
3116 	} else {
3117 		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
3118 			     DCLK_VOP_SEL_GPLL << DCLK0_VOP_SEL_SHIFT);
3119 	}
3120 
3121 	return 0;
3122 }
3123 
rk3568_rkvdec_set_parent(struct clk * clk,struct clk * parent)3124 static int __maybe_unused rk3568_rkvdec_set_parent(struct clk *clk,
3125 						   struct clk *parent)
3126 {
3127 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3128 	struct rk3568_cru *cru = priv->cru;
3129 	u32 con_id, mask, shift;
3130 
3131 	switch (clk->id) {
3132 	case ACLK_RKVDEC_PRE:
3133 		con_id = 47;
3134 		mask = ACLK_RKVDEC_SEL_MASK;
3135 		shift = ACLK_RKVDEC_SEL_SHIFT;
3136 		break;
3137 	case CLK_RKVDEC_CORE:
3138 		con_id = 49;
3139 		mask = CLK_RKVDEC_CORE_SEL_MASK;
3140 		shift = CLK_RKVDEC_CORE_SEL_SHIFT;
3141 		break;
3142 	default:
3143 		return -EINVAL;
3144 	}
3145 	if (parent->id == PLL_CPLL) {
3146 		rk_clrsetreg(&cru->clksel_con[con_id], mask,
3147 			     ACLK_RKVDEC_SEL_CPLL << shift);
3148 	} else {
3149 		rk_clrsetreg(&cru->clksel_con[con_id], mask,
3150 			     ACLK_RKVDEC_SEL_GPLL << shift);
3151 	}
3152 
3153 	return 0;
3154 }
3155 
rk3568_i2s3_set_parent(struct clk * clk,struct clk * parent)3156 static int __maybe_unused rk3568_i2s3_set_parent(struct clk *clk,
3157 						 struct clk *parent)
3158 {
3159 	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
3160 	struct rk3568_grf *grf = priv->grf;
3161 
3162 	switch (clk->id) {
3163 	case I2S3_MCLK_IOE:
3164 		if (parent->id == I2S3_MCLKOUT) {
3165 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLK_IOE_SEL_MASK,
3166 				     I2S3_MCLK_IOE_SEL_CLKOUT <<
3167 				     I2S3_MCLK_IOE_SEL_SHIFT);
3168 		} else {
3169 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLK_IOE_SEL_MASK,
3170 				     I2S3_MCLK_IOE_SEL_CLKIN <<
3171 				     I2S3_MCLK_IOE_SEL_SHIFT);
3172 		}
3173 		break;
3174 	case I2S3_MCLKOUT:
3175 		if (parent->id == I2S3_MCLKOUT_RX) {
3176 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLKOUT_SEL_MASK,
3177 				     I2S3_MCLKOUT_SEL_RX <<
3178 				     I2S3_MCLKOUT_SEL_SHIFT);
3179 		} else {
3180 			rk_clrsetreg(&grf->soc_con2, I2S3_MCLKOUT_SEL_MASK,
3181 				     I2S3_MCLKOUT_SEL_TX <<
3182 				     I2S3_MCLKOUT_SEL_SHIFT);
3183 		}
3184 		break;
3185 	default:
3186 		return -EINVAL;
3187 	}
3188 
3189 	return 0;
3190 }
3191 
rk3568_clk_set_parent(struct clk * clk,struct clk * parent)3192 static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
3193 {
3194 	switch (clk->id) {
3195 	case SCLK_GMAC0:
3196 		return rk3568_gmac0_src_set_parent(clk, parent);
3197 	case SCLK_GMAC1:
3198 		return rk3568_gmac1_src_set_parent(clk, parent);
3199 	case SCLK_GMAC0_RX_TX:
3200 		return rk3568_gmac0_tx_rx_set_parent(clk, parent);
3201 	case SCLK_GMAC1_RX_TX:
3202 		return rk3568_gmac1_tx_rx_set_parent(clk, parent);
3203 	case DCLK_VOP0:
3204 	case DCLK_VOP1:
3205 	case DCLK_VOP2:
3206 		return rk3568_dclk_vop_set_parent(clk, parent);
3207 	case ACLK_RKVDEC_PRE:
3208 	case CLK_RKVDEC_CORE:
3209 		return rk3568_rkvdec_set_parent(clk, parent);
3210 	case I2S3_MCLK_IOE:
3211 	case I2S3_MCLKOUT:
3212 		return rk3568_i2s3_set_parent(clk, parent);
3213 	default:
3214 		return -ENOENT;
3215 	}
3216 
3217 	return 0;
3218 }
3219 #endif
3220 
3221 static struct clk_ops rk3568_clk_ops = {
3222 	.get_rate = rk3568_clk_get_rate,
3223 	.set_rate = rk3568_clk_set_rate,
3224 	.get_phase = rk3568_clk_get_phase,
3225 	.set_phase = rk3568_clk_set_phase,
3226 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
3227 	.set_parent = rk3568_clk_set_parent,
3228 #endif
3229 };
3230 
rk3568_clk_init(struct rk3568_clk_priv * priv)3231 static void rk3568_clk_init(struct rk3568_clk_priv *priv)
3232 {
3233 	int ret;
3234 
3235 	priv->sync_kernel = false;
3236 	if (!priv->armclk_enter_hz) {
3237 		priv->armclk_enter_hz =
3238 			rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
3239 					      priv->cru, APLL);
3240 		priv->armclk_init_hz = priv->armclk_enter_hz;
3241 	}
3242 
3243 	if (priv->armclk_init_hz != APLL_HZ) {
3244 		ret = rk3568_armclk_set_clk(priv, APLL_HZ);
3245 		if (!ret)
3246 			priv->armclk_init_hz = APLL_HZ;
3247 	}
3248 	if (priv->cpll_hz != CPLL_HZ) {
3249 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
3250 					    CPLL, CPLL_HZ);
3251 		if (!ret)
3252 			priv->cpll_hz = CPLL_HZ;
3253 	}
3254 	if (priv->gpll_hz != GPLL_HZ) {
3255 		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
3256 					    GPLL, GPLL_HZ);
3257 		if (!ret)
3258 			priv->gpll_hz = GPLL_HZ;
3259 	}
3260 
3261 #ifdef CONFIG_SPL_BUILD
3262 	ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
3263 	if (ret < 0)
3264 		printf("Fail to set the ACLK_BUS clock.\n");
3265 #endif
3266 
3267 	priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
3268 	priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
3269 }
3270 
rk3568_clk_probe(struct udevice * dev)3271 static int rk3568_clk_probe(struct udevice *dev)
3272 {
3273 	struct rk3568_clk_priv *priv = dev_get_priv(dev);
3274 	int ret;
3275 
3276 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
3277 	if (IS_ERR(priv->grf))
3278 		return PTR_ERR(priv->grf);
3279 
3280 	rk3568_clk_init(priv);
3281 
3282 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
3283 	ret = clk_set_defaults(dev);
3284 	if (ret)
3285 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
3286 	else
3287 		priv->sync_kernel = true;
3288 
3289 	return 0;
3290 }
3291 
rk3568_clk_ofdata_to_platdata(struct udevice * dev)3292 static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
3293 {
3294 	struct rk3568_clk_priv *priv = dev_get_priv(dev);
3295 
3296 	priv->cru = dev_read_addr_ptr(dev);
3297 
3298 	return 0;
3299 }
3300 
rk3568_clk_bind(struct udevice * dev)3301 static int rk3568_clk_bind(struct udevice *dev)
3302 {
3303 	int ret;
3304 	struct udevice *sys_child, *sf_child;
3305 	struct sysreset_reg *priv;
3306 	struct softreset_reg *sf_priv;
3307 
3308 	/* The reset driver does not have a device node, so bind it here */
3309 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
3310 				 &sys_child);
3311 	if (ret) {
3312 		debug("Warning: No sysreset driver: ret=%d\n", ret);
3313 	} else {
3314 		priv = malloc(sizeof(struct sysreset_reg));
3315 		priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
3316 						    glb_srst_fst);
3317 		priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
3318 						    glb_srsr_snd);
3319 		sys_child->priv = priv;
3320 	}
3321 
3322 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
3323 					 dev_ofnode(dev), &sf_child);
3324 	if (ret) {
3325 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
3326 	} else {
3327 		sf_priv = malloc(sizeof(struct softreset_reg));
3328 		sf_priv->sf_reset_offset = offsetof(struct rk3568_cru,
3329 						    softrst_con[0]);
3330 		sf_priv->sf_reset_num = 30;
3331 		sf_child->priv = sf_priv;
3332 	}
3333 
3334 	return 0;
3335 }
3336 
3337 static const struct udevice_id rk3568_clk_ids[] = {
3338 	{ .compatible = "rockchip,rk3568-cru" },
3339 	{ }
3340 };
3341 
3342 U_BOOT_DRIVER(rockchip_rk3568_cru) = {
3343 	.name		= "rockchip_rk3568_cru",
3344 	.id		= UCLASS_CLK,
3345 	.of_match	= rk3568_clk_ids,
3346 	.priv_auto_alloc_size = sizeof(struct rk3568_clk_priv),
3347 	.ofdata_to_platdata = rk3568_clk_ofdata_to_platdata,
3348 	.ops		= &rk3568_clk_ops,
3349 	.bind		= rk3568_clk_bind,
3350 	.probe		= rk3568_clk_probe,
3351 };
3352 
3353 #ifndef CONFIG_SPL_BUILD
3354 /**
3355  * soc_clk_dump() - Print clock frequencies
3356  * Returns zero on success
3357  *
3358  * Implementation for the clk dump command.
3359  */
soc_clk_dump(void)3360 int soc_clk_dump(void)
3361 {
3362 	struct udevice *cru_dev, *pmucru_dev;
3363 	struct rk3568_clk_priv *priv;
3364 	const struct rk3568_clk_info *clk_dump;
3365 	struct clk clk;
3366 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
3367 	unsigned long rate;
3368 	int i, ret;
3369 
3370 	ret = uclass_get_device_by_driver(UCLASS_CLK,
3371 					  DM_GET_DRIVER(rockchip_rk3568_cru),
3372 					  &cru_dev);
3373 	if (ret) {
3374 		printf("%s failed to get cru device\n", __func__);
3375 		return ret;
3376 	}
3377 
3378 	ret = uclass_get_device_by_driver(UCLASS_CLK,
3379 					  DM_GET_DRIVER(rockchip_rk3568_pmucru),
3380 					  &pmucru_dev);
3381 	if (ret) {
3382 		printf("%s failed to get pmucru device\n", __func__);
3383 		return ret;
3384 	}
3385 
3386 	priv = dev_get_priv(cru_dev);
3387 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
3388 	       priv->sync_kernel ? "sync kernel" : "uboot",
3389 	       priv->armclk_enter_hz / 1000,
3390 	       priv->armclk_init_hz / 1000,
3391 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
3392 	       priv->set_armclk_rate ? " KHz" : "N/A");
3393 	for (i = 0; i < clk_count; i++) {
3394 		clk_dump = &clks_dump[i];
3395 		if (clk_dump->name) {
3396 			clk.id = clk_dump->id;
3397 			if (clk_dump->is_cru)
3398 				ret = clk_request(cru_dev, &clk);
3399 			else
3400 				ret = clk_request(pmucru_dev, &clk);
3401 			if (ret < 0)
3402 				return ret;
3403 
3404 			rate = clk_get_rate(&clk);
3405 			clk_free(&clk);
3406 			if (i == 0) {
3407 				if (rate < 0)
3408 					printf("  %s %s\n", clk_dump->name,
3409 					       "unknown");
3410 				else
3411 					printf("  %s %lu KHz\n", clk_dump->name,
3412 					       rate / 1000);
3413 			} else {
3414 				if (rate < 0)
3415 					printf("  %s %s\n", clk_dump->name,
3416 					       "unknown");
3417 				else
3418 					printf("  %s %lu KHz\n", clk_dump->name,
3419 					       rate / 1000);
3420 			}
3421 		}
3422 	}
3423 
3424 	return 0;
3425 }
3426 #endif
3427