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