xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk3562.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022 Rockchip Electronics Co., Ltd
4  * Author: Finley Xiao <finley.xiao@rock-chips.com>
5  */
6 
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <syscon.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/cru_rk3562.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/io.h>
15 #include <dm/lists.h>
16 #include <dt-bindings/clock/rk3562-cru.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
21 
22 static struct rockchip_pll_rate_table rk3562_pll_rates[] = {
23 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
24 	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
25 	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
26 	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
27 	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
28 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
29 	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
30 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
31 	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
32 	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
33 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
34 	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
35 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
36 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
37 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
38 	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
39 	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
40 	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
41 	{ /* sentinel */ },
42 };
43 
44 static struct rockchip_pll_clock rk3562_pll_clks[] = {
45 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3562_PLL_CON(0),
46 		     RK3562_MODE_CON, 0, 10, 0, rk3562_pll_rates),
47 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3562_PLL_CON(24),
48 		     RK3562_MODE_CON, 2, 10, 0, rk3562_pll_rates),
49 	[VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3562_PLL_CON(32),
50 		     RK3562_MODE_CON, 6, 10, 0, rk3562_pll_rates),
51 	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3562_PLL_CON(40),
52 		     RK3562_MODE_CON, 8, 10, 0, rk3562_pll_rates),
53 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3562_PMU1_PLL_CON(0),
54 		     RK3562_PMU1_MODE_CON, 0, 10, 0, rk3562_pll_rates),
55 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3562_SUBDDR_PLL_CON(0),
56 		     RK3562_SUBDDR_MODE_CON, 0, 10, 0, NULL),
57 };
58 
59 #define RK3562_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg)	\
60 {								\
61 	.rate = _rate##U,					\
62 	.aclk_div = _aclk_m_core,				\
63 	.pclk_div = _pclk_dbg,					\
64 }
65 
66 static struct rockchip_cpu_rate_table rk3562_cpu_rates[] = {
67 	RK3562_CPUCLK_RATE(1416000000, 1, 8),
68 	RK3562_CPUCLK_RATE(1296000000, 1, 8),
69 	RK3562_CPUCLK_RATE(1200000000, 1, 8),
70 	RK3562_CPUCLK_RATE(1104000000, 1, 8),
71 	RK3562_CPUCLK_RATE(1008000000, 1, 8),
72 	RK3562_CPUCLK_RATE(912000000, 1, 6),
73 	RK3562_CPUCLK_RATE(816000000, 1, 6),
74 	RK3562_CPUCLK_RATE(600000000, 1, 6),
75 	RK3562_CPUCLK_RATE(408000000, 1, 4),
76 	{ /* sentinel */ },
77 };
78 
79 #ifndef CONFIG_SPL_BUILD
80 #define RK3562_CLK_DUMP(_id, _name)		\
81 {						\
82 	.id = _id,				\
83 	.name = _name,				\
84 }
85 
86 static const struct rk3562_clk_info clks_dump[] = {
87 	RK3562_CLK_DUMP(PLL_APLL, "apll"),
88 	RK3562_CLK_DUMP(PLL_GPLL, "gpll"),
89 	RK3562_CLK_DUMP(PLL_VPLL, "vpll"),
90 	RK3562_CLK_DUMP(PLL_HPLL, "hpll"),
91 	RK3562_CLK_DUMP(PLL_CPLL, "cpll"),
92 	RK3562_CLK_DUMP(PLL_DPLL, "dpll"),
93 	RK3562_CLK_DUMP(ACLK_BUS, "aclk_bus"),
94 	RK3562_CLK_DUMP(HCLK_BUS, "hclk_bus"),
95 	RK3562_CLK_DUMP(PCLK_BUS, "pclk_bus"),
96 	RK3562_CLK_DUMP(ACLK_PERI, "aclk_peri"),
97 	RK3562_CLK_DUMP(HCLK_PERI, "hclk_peri"),
98 	RK3562_CLK_DUMP(PCLK_PERI, "pclk_peri"),
99 };
100 #endif
101 
102 /*
103  *
104  * rational_best_approximation(31415, 10000,
105  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
106  *
107  * you may look at given_numerator as a fixed point number,
108  * with the fractional part size described in given_denominator.
109  *
110  * for theoretical background, see:
111  * http://en.wikipedia.org/wiki/Continued_fraction
112  */
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)113 static void rational_best_approximation(unsigned long given_numerator,
114 					unsigned long given_denominator,
115 					unsigned long max_numerator,
116 					unsigned long max_denominator,
117 					unsigned long *best_numerator,
118 					unsigned long *best_denominator)
119 {
120 	unsigned long n, d, n0, d0, n1, d1;
121 
122 	n = given_numerator;
123 	d = given_denominator;
124 	n0 = 0;
125 	d1 = 0;
126 	n1 = 1;
127 	d0 = 1;
128 	for (;;) {
129 		unsigned long t, a;
130 
131 		if (n1 > max_numerator || d1 > max_denominator) {
132 			n1 = n0;
133 			d1 = d0;
134 			break;
135 		}
136 		if (d == 0)
137 			break;
138 		t = d;
139 		a = n / d;
140 		d = n % d;
141 		n = t;
142 		t = n0 + a * n1;
143 		n0 = n1;
144 		n1 = t;
145 		t = d0 + a * d1;
146 		d0 = d1;
147 		d1 = t;
148 	}
149 	*best_numerator = n1;
150 	*best_denominator = d1;
151 }
152 
rk3562_armclk_set_rate(struct rk3562_clk_priv * priv,ulong new_rate)153 static int rk3562_armclk_set_rate(struct rk3562_clk_priv *priv, ulong new_rate)
154 {
155 	const struct rockchip_cpu_rate_table *rate;
156 	struct rk3562_cru *cru = priv->cru;
157 	ulong old_rate;
158 
159 	rate = rockchip_get_cpu_settings(rk3562_cpu_rates, new_rate);
160 	if (!rate) {
161 		printf("%s unsupported rate\n", __func__);
162 		return -EINVAL;
163 	}
164 
165 	/*
166 	 * set up dependent divisors for DBG and ACLK clocks.
167 	 */
168 	old_rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru,
169 					 APLL);
170 	if (old_rate == new_rate) {
171 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
172 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
173 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
174 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
175 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
176 	} else if (old_rate > new_rate) {
177 		if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL],
178 					  priv->cru, APLL, new_rate))
179 			return -EINVAL;
180 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
181 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
182 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
183 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
184 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
185 	} else if (old_rate < new_rate) {
186 		rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK,
187 			     rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT);
188 		rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK,
189 			     rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT);
190 		rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0);
191 
192 		if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL],
193 					  priv->cru, APLL, new_rate))
194 			return -EINVAL;
195 	}
196 
197 	return 0;
198 }
199 
rk3562_bus_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)200 static ulong rk3562_bus_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
201 {
202 	struct rk3562_cru *cru = priv->cru;
203 	u32 sel, con, div;
204 	ulong rate;
205 
206 	switch (clk_id) {
207 	case ACLK_BUS:
208 		con = readl(&cru->clksel_con[40]);
209 		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
210 		div = (con & ACLK_BUS_DIV_MASK) >> ACLK_BUS_DIV_SHIFT;
211 		break;
212 	case HCLK_BUS:
213 		con = readl(&cru->clksel_con[40]);
214 		sel = (con & HCLK_BUS_SEL_MASK) >> HCLK_BUS_SEL_SHIFT;
215 		div = (con & HCLK_BUS_DIV_MASK) >> HCLK_BUS_DIV_SHIFT;
216 		break;
217 	case PCLK_BUS:
218 		con = readl(&cru->clksel_con[41]);
219 		sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
220 		div = (con & PCLK_BUS_DIV_MASK) >> PCLK_BUS_DIV_SHIFT;
221 		break;
222 	default:
223 		return -ENOENT;
224 	}
225 
226 	if (sel == ACLK_BUS_SEL_CPLL)
227 		rate = priv->cpll_hz;
228 	else
229 		rate = priv->gpll_hz;
230 
231 	return DIV_TO_RATE(rate, div);
232 }
233 
rk3562_bus_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)234 static ulong rk3562_bus_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
235 				 ulong rate)
236 {
237 	struct rk3562_cru *cru = priv->cru;
238 	u32 sel, div;
239 
240 	if (priv->cpll_hz % rate == 0) {
241 		sel = ACLK_BUS_SEL_CPLL;
242 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
243 	} else {
244 		sel= ACLK_BUS_SEL_GPLL;
245 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
246 	}
247 
248 	switch (clk_id) {
249 	case ACLK_BUS:
250 		rk_clrsetreg(&cru->clksel_con[40],
251 			     ACLK_BUS_SEL_MASK | ACLK_BUS_DIV_MASK,
252 			     (sel << ACLK_BUS_SEL_SHIFT) |
253 			     ((div - 1) << ACLK_BUS_DIV_SHIFT));
254 		break;
255 	case HCLK_BUS:
256 		rk_clrsetreg(&cru->clksel_con[40],
257 			     HCLK_BUS_SEL_MASK | HCLK_BUS_DIV_MASK,
258 			     (sel << HCLK_BUS_SEL_SHIFT) |
259 			     ((div - 1) << HCLK_BUS_DIV_SHIFT));
260 		break;
261 	case PCLK_BUS:
262 		rk_clrsetreg(&cru->clksel_con[41],
263 			     PCLK_BUS_SEL_MASK | PCLK_BUS_DIV_MASK,
264 			     (sel << PCLK_BUS_SEL_SHIFT) |
265 			     ((div - 1) << PCLK_BUS_DIV_SHIFT));
266 		break;
267 	default:
268 		return -ENOENT;
269 	}
270 
271 	return rk3562_bus_get_rate(priv, clk_id);
272 }
273 
rk3562_peri_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)274 static ulong rk3562_peri_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
275 {
276 	struct rk3562_cru *cru = priv->cru;
277 	u32 sel, con, div;
278 	ulong rate;
279 
280 	switch (clk_id) {
281 	case ACLK_PERI:
282 		con = readl(&cru->periclksel_con[0]);
283 		sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
284 		div = (con & ACLK_PERI_DIV_MASK) >> ACLK_PERI_DIV_SHIFT;
285 		break;
286 	case HCLK_PERI:
287 		con = readl(&cru->periclksel_con[0]);
288 		sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT;
289 		div = (con & HCLK_PERI_DIV_MASK) >> HCLK_PERI_DIV_SHIFT;
290 		break;
291 	case PCLK_PERI:
292 		con = readl(&cru->periclksel_con[1]);
293 		sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
294 		div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
295 		break;
296 	default:
297 		return -ENOENT;
298 	}
299 
300 	if (sel == ACLK_PERI_SEL_CPLL)
301 		rate = priv->cpll_hz;
302 	else
303 		rate = priv->gpll_hz;
304 
305 	return DIV_TO_RATE(rate, div);
306 }
307 
rk3562_peri_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)308 static ulong rk3562_peri_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
309 				  ulong rate)
310 {
311 	struct rk3562_cru *cru = priv->cru;
312 	u32 sel, div;
313 
314 	if (priv->cpll_hz % rate == 0) {
315 		sel = ACLK_PERI_SEL_CPLL;
316 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
317 	} else {
318 		sel= ACLK_PERI_SEL_GPLL;
319 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
320 	}
321 
322 	switch (clk_id) {
323 	case ACLK_PERI:
324 		rk_clrsetreg(&cru->periclksel_con[0],
325 			     ACLK_PERI_SEL_MASK | ACLK_PERI_DIV_MASK,
326 			     (sel << ACLK_PERI_SEL_SHIFT) |
327 			     ((div - 1) << ACLK_PERI_DIV_SHIFT));
328 		break;
329 	case HCLK_PERI:
330 		rk_clrsetreg(&cru->periclksel_con[0],
331 			     HCLK_PERI_SEL_MASK | HCLK_PERI_DIV_MASK,
332 			     (sel << HCLK_PERI_SEL_SHIFT) |
333 			     ((div - 1) << HCLK_PERI_DIV_SHIFT));
334 		break;
335 	case PCLK_PERI:
336 		rk_clrsetreg(&cru->periclksel_con[1],
337 			     PCLK_PERI_SEL_MASK | PCLK_PERI_DIV_MASK,
338 			     (sel << PCLK_PERI_SEL_SHIFT) |
339 			     ((div - 1) << PCLK_PERI_DIV_SHIFT));
340 		break;
341 	default:
342 		return -ENOENT;
343 	}
344 
345 	return rk3562_peri_get_rate(priv, clk_id);
346 }
347 
rk3562_i2c_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)348 static ulong rk3562_i2c_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
349 {
350 	struct rk3562_cru *cru = priv->cru;
351 	u32 sel, con, div;
352 	ulong rate;
353 
354 	switch (clk_id) {
355 	case CLK_PMU0_I2C0:
356 		con = readl(&cru->pmu0clksel_con[3]);
357 		sel = (con & CLK_PMU0_I2C0_SEL_MASK) >> CLK_PMU0_I2C0_SEL_SHIFT;
358 		if (sel == CLK_PMU0_I2C0_SEL_200M)
359 			rate = 200 * MHz;
360 		else if (sel == CLK_PMU0_I2C0_SEL_24M)
361 			rate = OSC_HZ;
362 		else
363 			rate = 32768;
364 		div = (con & CLK_PMU0_I2C0_DIV_MASK) >> CLK_PMU0_I2C0_DIV_SHIFT;
365 
366 		return DIV_TO_RATE(rate, div);
367 	case CLK_I2C:
368 	case CLK_I2C1:
369 	case CLK_I2C2:
370 	case CLK_I2C3:
371 	case CLK_I2C4:
372 	case CLK_I2C5:
373 		con = readl(&cru->clksel_con[41]);
374 		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
375 		if (sel == CLK_I2C_SEL_200M)
376 			rate = 200 * MHz;
377 		else if (sel == CLK_I2C_SEL_100M)
378 			rate = 100 * MHz;
379 		else if (sel == CLK_I2C_SEL_50M)
380 			rate = 50 * MHz;
381 		else
382 			rate = OSC_HZ;
383 		break;
384 	default:
385 		return -ENOENT;
386 	}
387 
388 	return rate;
389 }
390 
rk3562_i2c_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)391 static ulong rk3562_i2c_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
392 				 ulong rate)
393 {
394 	struct rk3562_cru *cru = priv->cru;
395 	u32 sel, div;
396 
397 	switch (clk_id) {
398 	case CLK_PMU0_I2C0:
399 		if (rate == 200 * MHz) {
400 			sel = CLK_PMU0_I2C0_SEL_200M;
401 			div = 1;
402 		} else if (rate == OSC_HZ) {
403 			sel = CLK_PMU0_I2C0_SEL_24M;
404 			div = 1;
405 		} else if (rate == 32768) {
406 			sel = CLK_PMU0_I2C0_SEL_32K;
407 			div = 1;
408 		} else {
409 			sel = CLK_PMU0_I2C0_SEL_200M;
410 			div = DIV_ROUND_UP(200 * MHz, rate);
411 			assert(div - 1 <= 31);
412 		}
413 		rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_DIV_MASK,
414 			     (div - 1) << CLK_PMU0_I2C0_DIV_SHIFT);
415 		rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_SEL_MASK,
416 			     sel << CLK_PMU0_I2C0_SEL_SHIFT);
417 		break;
418 	case CLK_I2C:
419 	case CLK_I2C2:
420 	case CLK_I2C3:
421 	case CLK_I2C4:
422 	case CLK_I2C5:
423 		if (rate == 200 * MHz)
424 			sel = CLK_I2C_SEL_200M;
425 		else if (rate == 100 * MHz)
426 			sel = CLK_I2C_SEL_100M;
427 		else if (rate == 50 * MHz)
428 			sel = CLK_I2C_SEL_50M;
429 		else
430 			sel = CLK_I2C_SEL_24M;
431 		rk_clrsetreg(&cru->clksel_con[41], CLK_I2C_SEL_MASK,
432 			     sel << CLK_I2C_SEL_SHIFT);
433 		break;
434 	default:
435 		return -ENOENT;
436 	}
437 
438 
439 	return rk3562_i2c_get_rate(priv, clk_id);
440 }
441 
rk3562_uart_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)442 static ulong rk3562_uart_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
443 {
444 	struct rk3562_cru *cru = priv->cru;
445 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
446 	unsigned long m, n;
447 
448 	switch (clk_id) {
449 	case SCLK_PMU1_UART0:
450 		con = readl(&cru->pmu1clksel_con[2]);
451 		src = (con & CLK_PMU1_UART0_SEL_MASK) >>
452 		       CLK_PMU1_UART0_SEL_SHIFT;
453 		div = (con & CLK_PMU1_UART0_SRC_DIV_MASK) >>
454 		       CLK_PMU1_UART0_SRC_DIV_SHIFT;
455 		if (src == CLK_UART_SEL_SRC) {
456 			return DIV_TO_RATE(priv->cpll_hz, div);
457 		} else if (src == CLK_UART_SEL_FRAC) {
458 			fracdiv = readl(&cru->pmu1clksel_con[3]);
459 			n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
460 			n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
461 			m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
462 			m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
463 			return DIV_TO_RATE(priv->cpll_hz, div) * n / m;
464 		} else {
465 			return OSC_HZ;
466 		}
467 	case SCLK_UART1:
468 		reg = 21;
469 		break;
470 	case SCLK_UART2:
471 		reg = 23;
472 		break;
473 	case SCLK_UART3:
474 		reg = 25;
475 		break;
476 	case SCLK_UART4:
477 		reg = 27;
478 		break;
479 	case SCLK_UART5:
480 		reg = 29;
481 		break;
482 	case SCLK_UART6:
483 		reg = 31;
484 		break;
485 	case SCLK_UART7:
486 		reg = 33;
487 		break;
488 	case SCLK_UART8:
489 		reg = 35;
490 		break;
491 	case SCLK_UART9:
492 		reg = 37;
493 		break;
494 	default:
495 		return -ENOENT;
496 	}
497 	con = readl(&cru->periclksel_con[reg]);
498 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
499 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
500 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
501 	if (p_src == CLK_UART_SRC_SEL_GPLL)
502 		p_rate = priv->gpll_hz;
503 	else
504 		p_rate = priv->cpll_hz;
505 	if (src == CLK_UART_SEL_SRC) {
506 		return DIV_TO_RATE(p_rate, div);
507 	} else if (src == CLK_UART_SEL_FRAC) {
508 		fracdiv = readl(&cru->periclksel_con[reg + 1]);
509 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
510 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
511 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
512 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
513 		return DIV_TO_RATE(p_rate, div) * n / m;
514 	} else {
515 		return OSC_HZ;
516 	}
517 }
518 
rk3562_uart_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)519 static ulong rk3562_uart_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
520 				  ulong rate)
521 {
522 	struct rk3562_cru *cru = priv->cru;
523 	u32 reg, clk_src, uart_src, div;
524 	unsigned long m = 0, n = 0, val;
525 
526 	switch (clk_id) {
527 	case SCLK_PMU1_UART0:
528 		if (priv->cpll_hz % rate == 0) {
529 			uart_src = CLK_UART_SEL_SRC;
530 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
531 		} else if (rate == OSC_HZ) {
532 			uart_src = CLK_UART_SEL_XIN24M;
533 			div = 2;
534 		} else {
535 			uart_src = CLK_UART_SEL_FRAC;
536 			div = 2;
537 			rational_best_approximation(rate, priv->cpll_hz / div,
538 						    GENMASK(16 - 1, 0),
539 						    GENMASK(16 - 1, 0),
540 						    &n, &m);
541 		}
542 
543 		rk_clrsetreg(&cru->pmu1clksel_con[2],
544 			     CLK_PMU1_UART0_SEL_MASK |
545 			     CLK_PMU1_UART0_SRC_DIV_MASK,
546 			     (uart_src << CLK_PMU1_UART0_SEL_SHIFT) |
547 			     ((div - 1) << CLK_PMU1_UART0_SRC_DIV_SHIFT));
548 		if (m && n) {
549 			val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m;
550 			writel(val, &cru->pmu1clksel_con[3]);
551 		}
552 
553 		return rk3562_uart_get_rate(priv, clk_id);
554 	case SCLK_UART1:
555 		reg = 21;
556 		break;
557 	case SCLK_UART2:
558 		reg = 23;
559 		break;
560 	case SCLK_UART3:
561 		reg = 25;
562 		break;
563 	case SCLK_UART4:
564 		reg = 27;
565 		break;
566 	case SCLK_UART5:
567 		reg = 29;
568 		break;
569 	case SCLK_UART6:
570 		reg = 31;
571 		break;
572 	case SCLK_UART7:
573 		reg = 33;
574 		break;
575 	case SCLK_UART8:
576 		reg = 35;
577 		break;
578 	case SCLK_UART9:
579 		reg = 37;
580 		break;
581 	default:
582 		return -ENOENT;
583 	}
584 
585 	if (priv->gpll_hz % rate == 0) {
586 		clk_src = CLK_UART_SRC_SEL_GPLL;
587 		uart_src = CLK_UART_SEL_SRC;
588 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
589 	} else if (priv->cpll_hz % rate == 0) {
590 		clk_src = CLK_UART_SRC_SEL_CPLL;
591 		uart_src = CLK_UART_SEL_SRC;
592 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
593 	} else if (rate == OSC_HZ) {
594 		clk_src = CLK_UART_SRC_SEL_GPLL;
595 		uart_src = CLK_UART_SEL_XIN24M;
596 		div = 2;
597 	} else {
598 		clk_src = CLK_UART_SRC_SEL_GPLL;
599 		uart_src = CLK_UART_SEL_FRAC;
600 		div = 2;
601 		rational_best_approximation(rate, priv->gpll_hz / div,
602 					    GENMASK(16 - 1, 0),
603 					    GENMASK(16 - 1, 0),
604 					    &n, &m);
605 	}
606 
607 	rk_clrsetreg(&cru->periclksel_con[reg],
608 		     CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
609 		     CLK_UART_SRC_DIV_MASK,
610 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
611 		     (uart_src << CLK_UART_SEL_SHIFT) |
612 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
613 	if (m && n) {
614 		val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m;
615 		writel(val, &cru->periclksel_con[reg + 1]);
616 	}
617 
618 	return rk3562_uart_get_rate(priv, clk_id);
619 }
620 
rk3562_pwm_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)621 static ulong rk3562_pwm_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
622 {
623 	struct rk3562_cru *cru = priv->cru;
624 	u32 sel, con, div, mask, shift;
625 	ulong rate;
626 
627 	switch (clk_id) {
628 	case CLK_PMU1_PWM0:
629 		con = readl(&cru->pmu1clksel_con[4]);
630 		sel = (con & CLK_PMU1_PWM0_SEL_MASK) >> CLK_PMU1_PWM0_SEL_SHIFT;
631 		if (sel == CLK_PMU1_PWM0_SEL_200M)
632 			rate = 200 * MHz;
633 		else if (sel == CLK_PMU1_PWM0_SEL_24M)
634 			rate = OSC_HZ;
635 		else
636 			rate = 32768;
637 		div = (con & CLK_PMU1_PWM0_DIV_MASK) >> CLK_PMU1_PWM0_DIV_SHIFT;
638 
639 		return DIV_TO_RATE(rate, div);
640 	case CLK_PWM1_PERI:
641 		mask = CLK_PWM1_PERI_SEL_MASK;
642 		shift = CLK_PWM1_PERI_SEL_SHIFT;
643 		break;
644 	case CLK_PWM2_PERI:
645 		mask = CLK_PWM2_PERI_SEL_MASK;
646 		shift = CLK_PWM2_PERI_SEL_SHIFT;
647 		break;
648 	case CLK_PWM3_PERI:
649 		mask = CLK_PWM3_PERI_SEL_MASK;
650 		shift = CLK_PWM3_PERI_SEL_SHIFT;
651 		break;
652 	default:
653 		return -ENOENT;
654 	}
655 
656 	con = readl(&cru->periclksel_con[40]);
657 	sel = (con & mask) >> shift;
658 	if (sel == CLK_PWM_SEL_100M)
659 		rate = 100 * MHz;
660 	else if (sel == CLK_PWM_SEL_50M)
661 		rate = 50 * MHz;
662 	else
663 		rate = OSC_HZ;
664 
665 	return rate;
666 }
667 
rk3562_pwm_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)668 static ulong rk3562_pwm_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
669 				 ulong rate)
670 {
671 	struct rk3562_cru *cru = priv->cru;
672 	u32 sel, div, mask, shift;
673 
674 	switch (clk_id) {
675 	case CLK_PMU1_PWM0:
676 		if (rate == 200 * MHz) {
677 			sel = CLK_PMU1_PWM0_SEL_200M;
678 			div = 1;
679 		} else if (rate == OSC_HZ) {
680 			sel = CLK_PMU1_PWM0_SEL_24M;
681 			div = 1;
682 		} else if (rate == 32768) {
683 			sel = CLK_PMU1_PWM0_SEL_32K;
684 			div = 1;
685 		} else {
686 			sel = CLK_PMU1_PWM0_SEL_200M;
687 			div = DIV_ROUND_UP(200 * MHz, rate);
688 			assert(div - 1 <= 3);
689 		}
690 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_DIV_MASK,
691 			     (div - 1) << CLK_PMU1_PWM0_DIV_SHIFT);
692 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_SEL_MASK,
693 			     sel << CLK_PMU1_PWM0_SEL_SHIFT);
694 
695 		return rk3562_pwm_get_rate(priv, clk_id);
696 	case CLK_PWM1_PERI:
697 		mask = CLK_PWM1_PERI_SEL_MASK;
698 		shift = CLK_PWM1_PERI_SEL_SHIFT;
699 		break;
700 	case CLK_PWM2_PERI:
701 		mask = CLK_PWM2_PERI_SEL_MASK;
702 		shift = CLK_PWM2_PERI_SEL_SHIFT;
703 		break;
704 	case CLK_PWM3_PERI:
705 		mask = CLK_PWM3_PERI_SEL_MASK;
706 		shift = CLK_PWM3_PERI_SEL_SHIFT;
707 		break;
708 	default:
709 		return -ENOENT;
710 	}
711 
712 	if (rate == 100 * MHz)
713 		sel = CLK_PWM_SEL_100M;
714 	else if (rate == 50 * MHz)
715 		sel = CLK_PWM_SEL_50M;
716 	else
717 		sel = CLK_PWM_SEL_24M;
718 	rk_clrsetreg(&cru->periclksel_con[40], mask, sel << shift);
719 
720 	return rk3562_pwm_get_rate(priv, clk_id);
721 }
722 
rk3562_spi_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)723 static ulong rk3562_spi_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
724 {
725 	struct rk3562_cru *cru = priv->cru;
726 	u32 sel, con, div, mask, shift;
727 	ulong rate;
728 
729 	switch (clk_id) {
730 	case CLK_PMU1_SPI0:
731 		con = readl(&cru->pmu1clksel_con[4]);
732 		sel = (con & CLK_PMU1_SPI0_SEL_MASK) >> CLK_PMU1_SPI0_SEL_SHIFT;
733 		if (sel == CLK_PMU1_SPI0_SEL_200M)
734 			rate = 200 * MHz;
735 		else if (sel == CLK_PMU1_SPI0_SEL_24M)
736 			rate = OSC_HZ;
737 		else
738 			rate = 32768;
739 		div = (con & CLK_PMU1_SPI0_DIV_MASK) >> CLK_PMU1_SPI0_DIV_SHIFT;
740 
741 		return DIV_TO_RATE(rate, div);
742 	case CLK_SPI1:
743 		mask = CLK_SPI1_SEL_MASK;
744 		shift = CLK_SPI1_SEL_SHIFT;
745 		break;
746 	case CLK_SPI2:
747 		mask = CLK_SPI2_SEL_MASK;
748 		shift = CLK_SPI2_SEL_SHIFT;
749 		break;
750 	default:
751 		return -ENOENT;
752 	}
753 
754 	con = readl(&cru->periclksel_con[20]);
755 	sel = (con & mask) >> shift;
756 	if (sel == CLK_SPI_SEL_200M)
757 		rate = 200 * MHz;
758 	else if (sel == CLK_SPI_SEL_100M)
759 		rate = 100 * MHz;
760 	else if (sel == CLK_SPI_SEL_50M)
761 		rate = 50 * MHz;
762 	else
763 		rate = OSC_HZ;
764 
765 	return rate;
766 }
767 
rk3562_spi_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)768 static ulong rk3562_spi_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
769 				 ulong rate)
770 {
771 	struct rk3562_cru *cru = priv->cru;
772 	u32 sel, div, mask, shift;
773 
774 	switch (clk_id) {
775 	case CLK_PMU1_SPI0:
776 		if (rate == 200 * MHz) {
777 			sel = CLK_PMU1_SPI0_SEL_200M;
778 			div = 1;
779 		} else if (rate == OSC_HZ) {
780 			sel = CLK_PMU1_SPI0_SEL_24M;
781 			div = 1;
782 		} else if (rate == 32768) {
783 			sel = CLK_PMU1_SPI0_SEL_32K;
784 			div = 1;
785 		} else {
786 			sel = CLK_PMU1_SPI0_SEL_200M;
787 			div = DIV_ROUND_UP(200 * MHz, rate);
788 			assert(div - 1 <= 3);
789 		}
790 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_DIV_MASK,
791 			     (div - 1) << CLK_PMU1_SPI0_DIV_SHIFT);
792 		rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_SEL_MASK,
793 			     sel << CLK_PMU1_SPI0_SEL_SHIFT);
794 
795 		return rk3562_spi_get_rate(priv, clk_id);
796 	case CLK_SPI1:
797 		mask = CLK_SPI1_SEL_MASK;
798 		shift = CLK_SPI1_SEL_SHIFT;
799 		break;
800 	case CLK_SPI2:
801 		mask = CLK_SPI2_SEL_MASK;
802 		shift = CLK_SPI2_SEL_SHIFT;
803 		break;
804 	default:
805 		return -ENOENT;
806 	}
807 
808 	if (rate == 200 * MHz)
809 		sel = CLK_SPI_SEL_200M;
810 	else if (rate == 100 * MHz)
811 		sel = CLK_SPI_SEL_100M;
812 	else if (rate == 50 * MHz)
813 		sel = CLK_SPI_SEL_50M;
814 	else
815 		sel = CLK_SPI_SEL_24M;
816 	rk_clrsetreg(&cru->periclksel_con[20], mask, sel << shift);
817 
818 	return rk3562_spi_get_rate(priv, clk_id);
819 }
820 
rk3562_tsadc_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)821 static ulong rk3562_tsadc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
822 {
823 	struct rk3562_cru *cru = priv->cru;
824 	u32 div, con;
825 
826 	con = readl(&cru->clksel_con[43]);
827 	switch (clk_id) {
828 	case CLK_TSADC_TSEN:
829 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
830 		       CLK_TSADC_TSEN_DIV_SHIFT;
831 		break;
832 	case CLK_TSADC:
833 		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
834 		break;
835 	default:
836 		return -ENOENT;
837 	}
838 
839 	return DIV_TO_RATE(OSC_HZ, div);
840 }
841 
rk3562_tsadc_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)842 static ulong rk3562_tsadc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
843 				   ulong rate)
844 {
845 	struct rk3562_cru *cru = priv->cru;
846 	u32 div, mask, shift;
847 
848 	switch (clk_id) {
849 	case CLK_TSADC_TSEN:
850 		mask = CLK_TSADC_TSEN_DIV_MASK;
851 		shift =	CLK_TSADC_TSEN_DIV_SHIFT;
852 		break;
853 	case CLK_TSADC:
854 		mask = CLK_TSADC_DIV_MASK;
855 		shift =	CLK_TSADC_DIV_SHIFT;
856 		break;
857 	default:
858 		return -ENOENT;
859 	}
860 
861 	div = DIV_ROUND_UP(OSC_HZ, rate);
862 	rk_clrsetreg(&cru->clksel_con[43], mask, (div - 1) << shift);
863 
864 	return rk3562_tsadc_get_rate(priv, clk_id);
865 }
866 
rk3562_saradc_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)867 static ulong rk3562_saradc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
868 {
869 	struct rk3562_cru *cru = priv->cru;
870 	u32 div, con;
871 
872 	switch (clk_id) {
873 	case CLK_SARADC_VCCIO156:
874 		con = readl(&cru->clksel_con[44]);
875 		div = (con & CLK_SARADC_VCCIO156_DIV_MASK) >>
876 		       CLK_SARADC_VCCIO156_DIV_SHIFT;
877 		break;
878 	case CLK_SARADC:
879 		con = readl(&cru->periclksel_con[46]);
880 		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
881 		break;
882 	default:
883 		return -ENOENT;
884 	}
885 
886 	return DIV_TO_RATE(OSC_HZ, div);
887 }
888 
rk3562_saradc_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)889 static ulong rk3562_saradc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
890 				    ulong rate)
891 {
892 	struct rk3562_cru *cru = priv->cru;
893 	u32 div;
894 
895 	switch (clk_id) {
896 	case CLK_SARADC_VCCIO156:
897 		div = DIV_ROUND_UP(OSC_HZ, rate);
898 		rk_clrsetreg(&cru->clksel_con[44], CLK_SARADC_VCCIO156_DIV_MASK,
899 			     (div - 1) << CLK_SARADC_VCCIO156_DIV_SHIFT);
900 		break;
901 	case CLK_SARADC:
902 		div = DIV_ROUND_UP(OSC_HZ, rate);
903 		rk_clrsetreg(&cru->periclksel_con[46], CLK_SARADC_DIV_MASK,
904 			     (div - 1) << CLK_SARADC_DIV_SHIFT);
905 		break;
906 	default:
907 		return -ENOENT;
908 	}
909 
910 	return rk3562_saradc_get_rate(priv, clk_id);
911 }
912 
rk3562_sfc_get_rate(struct rk3562_clk_priv * priv)913 static ulong rk3562_sfc_get_rate(struct rk3562_clk_priv *priv)
914 {
915 	struct rk3562_cru *cru = priv->cru;
916 	u32 div, sel, con, parent;
917 
918 	con = readl(&cru->periclksel_con[20]);
919 	div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
920 	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
921 	if (sel == SCLK_SFC_SRC_SEL_GPLL)
922 		parent = priv->gpll_hz;
923 	else if (sel == SCLK_SFC_SRC_SEL_CPLL)
924 		parent = priv->cpll_hz;
925 	else
926 		parent = OSC_HZ;
927 
928 	return DIV_TO_RATE(parent, div);
929 }
930 
rk3562_sfc_set_rate(struct rk3562_clk_priv * priv,ulong rate)931 static ulong rk3562_sfc_set_rate(struct rk3562_clk_priv *priv, ulong rate)
932 {
933 	struct rk3562_cru *cru = priv->cru;
934 	int div, sel;
935 
936 	if (OSC_HZ % rate == 0) {
937 		div = DIV_ROUND_UP(OSC_HZ, rate);
938 		sel = SCLK_SFC_SRC_SEL_24M;
939 	} else if ((priv->cpll_hz % rate) == 0) {
940 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
941 		sel = SCLK_SFC_SRC_SEL_CPLL;
942 	} else {
943 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
944 		sel = SCLK_SFC_SRC_SEL_GPLL;
945 	}
946 
947 	assert(div - 1 <= 255);
948 	rk_clrsetreg(&cru->periclksel_con[20],
949 		     SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
950 		     sel << SCLK_SFC_SEL_SHIFT |
951 		     (div - 1) << SCLK_SFC_DIV_SHIFT);
952 
953 	return rk3562_sfc_get_rate(priv);
954 }
955 
rk3562_emmc_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)956 static ulong rk3562_emmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
957 {
958 	struct rk3562_cru *cru = priv->cru;
959 	u32 div, sel, con, parent;
960 
961 	switch (clk_id) {
962 	case CCLK_EMMC:
963 		con = readl(&cru->periclksel_con[18]);
964 		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
965 		sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
966 		if (sel == CCLK_EMMC_SEL_GPLL)
967 			parent = priv->gpll_hz;
968 		else if (sel == CCLK_EMMC_SEL_CPLL)
969 			parent = priv->cpll_hz;
970 		else if (sel == CCLK_EMMC_SEL_HPLL)
971 			parent = priv->hpll_hz;
972 		else
973 			parent = OSC_HZ;
974 		break;
975 	case BCLK_EMMC:
976 		con = readl(&cru->periclksel_con[19]);
977 		div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
978 		sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
979 		if (sel == BCLK_EMMC_SEL_GPLL)
980 			parent = priv->gpll_hz;
981 		else
982 			parent = priv->cpll_hz;
983 		break;
984 	default:
985 		return -ENOENT;
986 	}
987 
988 	return DIV_TO_RATE(parent, div);
989 }
990 
rk3562_emmc_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)991 static ulong rk3562_emmc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
992 				  ulong rate)
993 {
994 	struct rk3562_cru *cru = priv->cru;
995 	int div, sel;
996 
997 	switch (clk_id) {
998 	case CCLK_EMMC:
999 		if (OSC_HZ % rate == 0) {
1000 			div = DIV_ROUND_UP(OSC_HZ, rate);
1001 			sel = CCLK_EMMC_SEL_24M;
1002 		} else if ((priv->cpll_hz % rate) == 0) {
1003 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1004 			sel = CCLK_EMMC_SEL_CPLL;
1005 		} else if ((priv->hpll_hz % rate) == 0) {
1006 			div = DIV_ROUND_UP(priv->hpll_hz, rate);
1007 			sel = CCLK_EMMC_SEL_HPLL;
1008 		} else {
1009 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1010 			sel = CCLK_EMMC_SEL_GPLL;
1011 		}
1012 		rk_clrsetreg(&cru->periclksel_con[18],
1013 			     CCLK_EMMC_SEL_MASK | CCLK_EMMC_DIV_MASK,
1014 			     sel << CCLK_EMMC_SEL_SHIFT |
1015 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
1016 		break;
1017 	case BCLK_EMMC:
1018 		if ((priv->cpll_hz % rate) == 0) {
1019 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1020 			sel = BCLK_EMMC_SEL_CPLL;
1021 		} else {
1022 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1023 			sel = BCLK_EMMC_SEL_GPLL;
1024 		}
1025 		rk_clrsetreg(&cru->periclksel_con[19],
1026 			     BCLK_EMMC_SEL_MASK | BCLK_EMMC_DIV_MASK,
1027 			     sel << BCLK_EMMC_SEL_SHIFT |
1028 			     (div - 1) << BCLK_EMMC_DIV_SHIFT);
1029 		break;
1030 	default:
1031 		return -ENOENT;
1032 	}
1033 
1034 	return rk3562_emmc_get_rate(priv, clk_id);
1035 }
1036 
rk3562_sdmmc_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)1037 static ulong rk3562_sdmmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1038 {
1039 	struct rk3562_cru *cru = priv->cru;
1040 	u32 div, sel, con;
1041 	ulong prate;
1042 
1043 	switch (clk_id) {
1044 	case HCLK_SDMMC0:
1045 	case CCLK_SDMMC0:
1046 	case SCLK_SDMMC0_SAMPLE:
1047 		con = readl(&cru->periclksel_con[16]);
1048 		div = (con & CCLK_SDMMC0_DIV_MASK) >> CCLK_SDMMC0_DIV_SHIFT;
1049 		sel = (con & CCLK_SDMMC0_SEL_MASK) >> CCLK_SDMMC0_SEL_SHIFT;
1050 		break;
1051 	case HCLK_SDMMC1:
1052 	case CCLK_SDMMC1:
1053 	case SCLK_SDMMC1_SAMPLE:
1054 		con = readl(&cru->periclksel_con[17]);
1055 		div = (con & CCLK_SDMMC1_DIV_MASK) >> CCLK_SDMMC1_DIV_SHIFT;
1056 		sel = (con & CCLK_SDMMC1_SEL_MASK) >> CCLK_SDMMC1_SEL_SHIFT;
1057 		break;
1058 	default:
1059 		return -ENOENT;
1060 	}
1061 
1062 	if (sel == CCLK_SDMMC_SEL_GPLL)
1063 		prate = priv->gpll_hz;
1064 	else if (sel == CCLK_SDMMC_SEL_CPLL)
1065 		prate = priv->cpll_hz;
1066 	else if (sel == CCLK_SDMMC_SEL_HPLL)
1067 		prate = priv->hpll_hz;
1068 	else
1069 		prate = OSC_HZ;
1070 
1071 	return DIV_TO_RATE(prate, div);
1072 }
1073 
rk3562_sdmmc_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)1074 static ulong rk3562_sdmmc_set_rate(struct rk3562_clk_priv *priv,
1075 				   ulong clk_id, ulong rate)
1076 {
1077 	struct rk3562_cru *cru = priv->cru;
1078 	u32 div, sel;
1079 
1080 	if (OSC_HZ % rate == 0) {
1081 		div = DIV_ROUND_UP(OSC_HZ, rate);
1082 		sel = CCLK_SDMMC_SEL_24M;
1083 	} else if ((priv->cpll_hz % rate) == 0) {
1084 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
1085 		sel = CCLK_SDMMC_SEL_CPLL;
1086 	} else if ((priv->hpll_hz % rate) == 0) {
1087 		div = DIV_ROUND_UP(priv->hpll_hz, rate);
1088 		sel = CCLK_SDMMC_SEL_HPLL;
1089 	} else {
1090 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1091 		sel = CCLK_SDMMC_SEL_CPLL;
1092 	}
1093 
1094 	switch (clk_id) {
1095 	case HCLK_SDMMC0:
1096 	case CCLK_SDMMC0:
1097 		rk_clrsetreg(&cru->periclksel_con[16],
1098 			     CCLK_SDMMC0_SEL_MASK | CCLK_SDMMC0_DIV_MASK,
1099 			     sel << CCLK_SDMMC0_SEL_SHIFT |
1100 			     (div - 1) << CCLK_SDMMC0_DIV_SHIFT);
1101 		break;
1102 	case HCLK_SDMMC1:
1103 	case CCLK_SDMMC1:
1104 		rk_clrsetreg(&cru->periclksel_con[17],
1105 			     CCLK_SDMMC1_SEL_MASK | CCLK_SDMMC1_DIV_MASK,
1106 			     sel << CCLK_SDMMC1_SEL_SHIFT |
1107 			     (div - 1) << CCLK_SDMMC1_DIV_SHIFT);
1108 		break;
1109 	default:
1110 		return -ENOENT;
1111 	}
1112 
1113 	return rk3562_sdmmc_get_rate(priv, clk_id);
1114 }
1115 
rk3562_vop_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)1116 static ulong rk3562_vop_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1117 {
1118 	struct rk3562_cru *cru = priv->cru;
1119 	u32 con, sel, div;
1120 	ulong prate;
1121 
1122 	switch (clk_id) {
1123 	case ACLK_VOP:
1124 		con = readl(&cru->clksel_con[28]);
1125 		div = (con & ACLK_VOP_DIV_MASK) >> ACLK_VOP_DIV_SHIFT;
1126 		sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT;
1127 		if (sel == ACLK_VOP_SEL_GPLL)
1128 			prate = priv->gpll_hz;
1129 		else if (sel == ACLK_VOP_SEL_CPLL)
1130 			prate = priv->cpll_hz;
1131 		else if (sel == ACLK_VOP_SEL_HPLL)
1132 			prate = priv->hpll_hz;
1133 		else if (sel == ACLK_VOP_SEL_VPLL)
1134 			prate = priv->vpll_hz;
1135 		else
1136 			return -ENOENT;
1137 
1138 		return DIV_TO_RATE(prate, div);
1139 	case DCLK_VOP:
1140 		con = readl(&cru->clksel_con[30]);
1141 		div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1142 		sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1143 		if (sel == DCLK_VOP_SEL_VPLL)
1144 			priv->vpll_hz =
1145 				rockchip_pll_get_rate(&rk3562_pll_clks[VPLL],
1146 						      priv->cru, VPLL);
1147 		break;
1148 	case DCLK_VOP1:
1149 		con = readl(&cru->clksel_con[31]);
1150 		div = (con & DCLK_VOP1_DIV_MASK) >> DCLK_VOP1_DIV_SHIFT;
1151 		sel = (con & DCLK_VOP1_SEL_MASK) >> DCLK_VOP1_SEL_SHIFT;
1152 		break;
1153 	default:
1154 		return -ENOENT;
1155 	}
1156 
1157 	if (sel == DCLK_VOP_SEL_GPLL)
1158 		prate = priv->gpll_hz;
1159 	else if (sel == DCLK_VOP_SEL_HPLL)
1160 		prate = priv->hpll_hz;
1161 	else if (sel == DCLK_VOP_SEL_VPLL)
1162 		prate = priv->vpll_hz;
1163 	else
1164 		return -ENOENT;
1165 
1166 	return DIV_TO_RATE(prate, div);
1167 }
1168 
1169 #define RK3562_VOP_PLL_LIMIT_FREQ 600000000
1170 
rk3562_vop_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)1171 static ulong rk3562_vop_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1172 				 ulong rate)
1173 {
1174 	struct rk3562_cru *cru = priv->cru;
1175 	u32 i, div, sel, best_div = 0, best_sel = 0;
1176 	ulong pll_rate, now, best_rate = 0;
1177 
1178 	switch (clk_id) {
1179 	case ACLK_VOP:
1180 		if ((priv->cpll_hz % rate) == 0) {
1181 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1182 			sel = ACLK_VOP_SEL_CPLL;
1183 		} else if ((priv->hpll_hz % rate) == 0) {
1184 			div = DIV_ROUND_UP(priv->hpll_hz, rate);
1185 			sel = ACLK_VOP_SEL_HPLL;
1186 		} else if ((priv->vpll_hz % rate) == 0) {
1187 			div = DIV_ROUND_UP(priv->vpll_hz, rate);
1188 			sel = ACLK_VOP_SEL_VPLL;
1189 		} else {
1190 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1191 			sel = ACLK_VOP_SEL_GPLL;
1192 		}
1193 		rk_clrsetreg(&cru->clksel_con[28],
1194 			     ACLK_VOP_SEL_MASK | ACLK_VOP_DIV_MASK,
1195 			     sel << ACLK_VOP_SEL_SHIFT |
1196 			     ((div - 1) << ACLK_VOP_DIV_SHIFT));
1197 
1198 		return rk3562_vop_get_rate(priv, clk_id);
1199 	case DCLK_VOP:
1200 		div = DIV_ROUND_UP(RK3562_VOP_PLL_LIMIT_FREQ, rate);
1201 		rk_clrsetreg(&cru->clksel_con[30],
1202 			     DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1203 			     DCLK_VOP_SEL_VPLL << DCLK_VOP_SEL_SHIFT |
1204 			     ((div - 1) << DCLK_VOP_DIV_SHIFT));
1205 		rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru,
1206 				      VPLL, div * rate);
1207 		break;
1208 	case DCLK_VOP1:
1209 		for (i = 0; i <= DCLK_VOP_SEL_APLL; i++) {
1210 			switch (i) {
1211 			case DCLK_VOP_SEL_GPLL:
1212 				pll_rate = priv->gpll_hz;
1213 				break;
1214 			case DCLK_VOP_SEL_HPLL:
1215 				pll_rate = priv->hpll_hz;
1216 				break;
1217 			case DCLK_VOP_SEL_VPLL:
1218 			case DCLK_VOP_SEL_APLL:
1219 				continue;
1220 			default:
1221 				printf("do not support this vop pll sel\n");
1222 				return -EINVAL;
1223 			}
1224 
1225 			div = DIV_ROUND_UP(pll_rate, rate);
1226 			if (div > 255)
1227 				continue;
1228 			now = pll_rate / div;
1229 			if (abs(rate - now) < abs(rate - best_rate)) {
1230 				best_rate = now;
1231 				best_div = div;
1232 				best_sel = i;
1233 			}
1234 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1235 			      pll_rate, best_rate, best_div, best_sel);
1236 		}
1237 		if (best_rate) {
1238 			rk_clrsetreg(&cru->clksel_con[31],
1239 				     DCLK_VOP1_SEL_MASK | DCLK_VOP1_DIV_MASK,
1240 				     best_sel << DCLK_VOP1_SEL_SHIFT |
1241 				     (best_div - 1) << DCLK_VOP1_DIV_SHIFT);
1242 		} else {
1243 			printf("do not support this vop freq %lu\n", rate);
1244 			return -EINVAL;
1245 		}
1246 		break;
1247 	default:
1248 		return -ENOENT;
1249 	}
1250 
1251 	return rk3562_vop_get_rate(priv, clk_id);
1252 }
1253 
rk3562_gmac_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)1254 static ulong rk3562_gmac_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1255 {
1256 	struct rk3562_cru *cru = priv->cru;
1257 	u32 con, sel, div;
1258 	ulong prate;
1259 
1260 	switch (clk_id) {
1261 	case CLK_GMAC_125M_CRU_I:
1262 		con = readl(&cru->clksel_con[45]);
1263 		sel = (con & CLK_GMAC_125M_SEL_MASK) >> CLK_GMAC_125M_SEL_SHIFT;
1264 		if (sel == CLK_GMAC_125M)
1265 			return 125000000;
1266 		else
1267 			return OSC_HZ;
1268 	case CLK_GMAC_50M_CRU_I:
1269 		con = readl(&cru->clksel_con[45]);
1270 		sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT;
1271 		if (sel == CLK_GMAC_50M)
1272 			return 50000000;
1273 		else
1274 			return OSC_HZ;
1275 	case CLK_MAC100_50M_MATRIX:
1276 		con = readl(&cru->clksel_con[47]);
1277 		sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT;
1278 		if (sel == CLK_GMAC_50M)
1279 			return 50000000;
1280 		else
1281 			return OSC_HZ;
1282 	case CLK_GMAC_ETH_OUT2IO:
1283 		con = readl(&cru->clksel_con[46]);
1284 		sel = (con & CLK_GMAC_ETH_OUT2IO_SEL_MASK) >> CLK_GMAC_ETH_OUT2IO_SEL_SHIFT;
1285 		div = (con & CLK_GMAC_ETH_OUT2IO_DIV_MASK) >> CLK_GMAC_ETH_OUT2IO_DIV_SHIFT;
1286 		if (sel == CLK_GMAC_ETH_OUT2IO_GPLL)
1287 			prate = priv->gpll_hz;
1288 		else
1289 			prate = priv->cpll_hz;
1290 		break;
1291 	default:
1292 		return -ENOENT;
1293 	}
1294 
1295 	return DIV_TO_RATE(prate, div);
1296 }
1297 
rk3562_gmac_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)1298 static ulong rk3562_gmac_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1299 				  ulong rate)
1300 {
1301 	struct rk3562_cru *cru = priv->cru;
1302 	u32 sel, div;
1303 
1304 	switch (clk_id) {
1305 	case CLK_GMAC_125M_CRU_I:
1306 		if (rate == 125000000)
1307 			sel = CLK_GMAC_125M;
1308 		else
1309 			sel = CLK_GMAC_24M;
1310 		rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_125M_SEL_MASK,
1311 			     sel << CLK_GMAC_125M_SEL_SHIFT);
1312 		break;
1313 	case CLK_GMAC_50M_CRU_I:
1314 		if (rate == 50000000)
1315 			sel = CLK_GMAC_50M;
1316 		else
1317 			sel = CLK_GMAC_24M;
1318 		rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_50M_SEL_MASK,
1319 			     sel << CLK_GMAC_50M_SEL_SHIFT);
1320 		break;
1321 	case CLK_MAC100_50M_MATRIX:
1322 		if (rate == 50000000)
1323 			sel = CLK_GMAC_50M;
1324 		else
1325 			sel = CLK_GMAC_24M;
1326 		rk_clrsetreg(&cru->clksel_con[47], CLK_GMAC_50M_SEL_MASK,
1327 			     sel << CLK_GMAC_50M_SEL_SHIFT);
1328 		break;
1329 	case CLK_GMAC_ETH_OUT2IO:
1330 		if ((priv->cpll_hz % rate) == 0) {
1331 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1332 			sel = CLK_GMAC_ETH_OUT2IO_CPLL;
1333 		} else {
1334 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1335 			sel = CLK_GMAC_ETH_OUT2IO_GPLL;
1336 		}
1337 		rk_clrsetreg(&cru->clksel_con[46],
1338 			     CLK_GMAC_ETH_OUT2IO_SEL_MASK | CLK_GMAC_ETH_OUT2IO_DIV_MASK,
1339 			     sel << CLK_GMAC_ETH_OUT2IO_SEL_SHIFT |
1340 			     (div - 1) << CLK_GMAC_ETH_OUT2IO_DIV_SHIFT);
1341 		break;
1342 	default:
1343 		return -ENOENT;
1344 	}
1345 
1346 	return rk3562_gmac_get_rate(priv, clk_id);
1347 }
1348 
rk3562_clk_get_rate(struct clk * clk)1349 static ulong rk3562_clk_get_rate(struct clk *clk)
1350 {
1351 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1352 	ulong rate = 0;
1353 
1354 	if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) {
1355 		printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n",
1356 		       __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz);
1357 		return -ENOENT;
1358 	}
1359 
1360 	switch (clk->id) {
1361 	case PLL_APLL:
1362 	case ARMCLK:
1363 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru,
1364 					     APLL);
1365 		break;
1366 	case PLL_GPLL:
1367 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL], priv->cru,
1368 					     GPLL);
1369 		break;
1370 
1371 	case PLL_VPLL:
1372 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL], priv->cru,
1373 					     VPLL);
1374 		break;
1375 	case PLL_HPLL:
1376 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL], priv->cru,
1377 					     HPLL);
1378 		break;
1379 	case PLL_CPLL:
1380 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[CPLL], priv->cru,
1381 					     CPLL);
1382 		break;
1383 	case PLL_DPLL:
1384 		rate = rockchip_pll_get_rate(&rk3562_pll_clks[DPLL], priv->cru,
1385 					     DPLL);
1386 		break;
1387 	case ACLK_BUS:
1388 	case HCLK_BUS:
1389 	case PCLK_BUS:
1390 		rate = rk3562_bus_get_rate(priv, clk->id);
1391 		break;
1392 	case ACLK_PERI:
1393 	case HCLK_PERI:
1394 	case PCLK_PERI:
1395 		rate = rk3562_peri_get_rate(priv, clk->id);
1396 		break;
1397 	case CLK_PMU0_I2C0:
1398 	case CLK_I2C:
1399 	case CLK_I2C1:
1400 	case CLK_I2C2:
1401 	case CLK_I2C3:
1402 	case CLK_I2C4:
1403 	case CLK_I2C5:
1404 		rate = rk3562_i2c_get_rate(priv, clk->id);
1405 		break;
1406 	case SCLK_PMU1_UART0:
1407 	case SCLK_UART1:
1408 	case SCLK_UART2:
1409 	case SCLK_UART3:
1410 	case SCLK_UART4:
1411 	case SCLK_UART5:
1412 	case SCLK_UART6:
1413 	case SCLK_UART7:
1414 	case SCLK_UART8:
1415 	case SCLK_UART9:
1416 		rate = rk3562_uart_get_rate(priv, clk->id);
1417 		break;
1418 	case CLK_PMU1_PWM0:
1419 	case CLK_PWM1_PERI:
1420 	case CLK_PWM2_PERI:
1421 	case CLK_PWM3_PERI:
1422 		rate = rk3562_pwm_get_rate(priv, clk->id);
1423 		break;
1424 	case CLK_PMU1_SPI0:
1425 	case CLK_SPI1:
1426 	case CLK_SPI2:
1427 		rate = rk3562_spi_get_rate(priv, clk->id);
1428 		break;
1429 	case CLK_TSADC:
1430 	case CLK_TSADC_TSEN:
1431 		rate = rk3562_tsadc_get_rate(priv, clk->id);
1432 		break;
1433 	case CLK_SARADC:
1434 	case CLK_SARADC_VCCIO156:
1435 		rate = rk3562_saradc_get_rate(priv, clk->id);
1436 		break;
1437 	case SCLK_SFC:
1438 		rate = rk3562_sfc_get_rate(priv);
1439 		break;
1440 	case CCLK_EMMC:
1441 	case BCLK_EMMC:
1442 		rate = rk3562_emmc_get_rate(priv, clk->id);
1443 		break;
1444 	case HCLK_SDMMC0:
1445 	case HCLK_SDMMC1:
1446 	case CCLK_SDMMC0:
1447 	case CCLK_SDMMC1:
1448 	case SCLK_SDMMC0_SAMPLE:
1449 	case SCLK_SDMMC1_SAMPLE:
1450 		rate = rk3562_sdmmc_get_rate(priv, clk->id);
1451 		break;
1452 	case ACLK_VOP:
1453 	case DCLK_VOP:
1454 	case DCLK_VOP1:
1455 		rate = rk3562_vop_get_rate(priv, clk->id);
1456 		break;
1457 	case CLK_GMAC_125M_CRU_I:
1458 	case CLK_GMAC_50M_CRU_I:
1459 	case CLK_GMAC_ETH_OUT2IO:
1460 	case CLK_MAC100_50M_MATRIX:
1461 		rate = rk3562_gmac_get_rate(priv, clk->id);
1462 		break;
1463 	case CLK_WDTNS:
1464 		rate = OSC_HZ;
1465 		break;
1466 	default:
1467 		return -ENOENT;
1468 	}
1469 
1470 	return rate;
1471 };
1472 
rk3562_clk_set_rate(struct clk * clk,ulong rate)1473 static ulong rk3562_clk_set_rate(struct clk *clk, ulong rate)
1474 {
1475 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1476 	ulong ret = 0;
1477 
1478 	if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) {
1479 		printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n",
1480 		       __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz);
1481 		return -ENOENT;
1482 	}
1483 
1484 	debug("%s: id=%ld, rate=%ld\n", __func__, clk->id, rate);
1485 
1486 	switch (clk->id) {
1487 	case PLL_APLL:
1488 	case ARMCLK:
1489 		if (priv->armclk_hz)
1490 			rk3562_armclk_set_rate(priv, rate);
1491 		priv->armclk_hz = rate;
1492 		break;
1493 	case PLL_GPLL:
1494 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru,
1495 					    GPLL, rate);
1496 		priv->gpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL],
1497 						      priv->cru, GPLL);
1498 		break;
1499 	case PLL_VPLL:
1500 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru,
1501 					    VPLL, rate);
1502 		priv->vpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL],
1503 						      priv->cru, VPLL);
1504 		break;
1505 	case PLL_HPLL:
1506 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru,
1507 					    HPLL, rate);
1508 		priv->hpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL],
1509 						      priv->cru, HPLL);
1510 		break;
1511 	case ACLK_BUS:
1512 	case HCLK_BUS:
1513 	case PCLK_BUS:
1514 		ret = rk3562_bus_set_rate(priv, clk->id, rate);
1515 		break;
1516 	case ACLK_PERI:
1517 	case HCLK_PERI:
1518 	case PCLK_PERI:
1519 		ret = rk3562_peri_set_rate(priv, clk->id, rate);
1520 		break;
1521 	case CLK_PMU0_I2C0:
1522 	case CLK_I2C:
1523 	case CLK_I2C1:
1524 	case CLK_I2C2:
1525 	case CLK_I2C3:
1526 	case CLK_I2C4:
1527 	case CLK_I2C5:
1528 		ret = rk3562_i2c_set_rate(priv, clk->id, rate);
1529 		break;
1530 	case SCLK_PMU1_UART0:
1531 	case SCLK_UART1:
1532 	case SCLK_UART2:
1533 	case SCLK_UART3:
1534 	case SCLK_UART4:
1535 	case SCLK_UART5:
1536 	case SCLK_UART6:
1537 	case SCLK_UART7:
1538 	case SCLK_UART8:
1539 	case SCLK_UART9:
1540 		ret = rk3562_uart_set_rate(priv, clk->id, rate);
1541 		break;
1542 	case CLK_PMU1_PWM0:
1543 	case CLK_PWM1_PERI:
1544 	case CLK_PWM2_PERI:
1545 	case CLK_PWM3_PERI:
1546 		ret = rk3562_pwm_set_rate(priv, clk->id, rate);
1547 		break;
1548 	case CLK_PMU1_SPI0:
1549 	case CLK_SPI1:
1550 	case CLK_SPI2:
1551 		ret = rk3562_spi_set_rate(priv, clk->id, rate);
1552 		break;
1553 	case CLK_TSADC:
1554 	case CLK_TSADC_TSEN:
1555 		ret = rk3562_tsadc_set_rate(priv, clk->id, rate);
1556 		break;
1557 	case CLK_SARADC:
1558 	case CLK_SARADC_VCCIO156:
1559 		ret = rk3562_saradc_set_rate(priv, clk->id, rate);
1560 		break;
1561 	case SCLK_SFC:
1562 		ret = rk3562_sfc_set_rate(priv, rate);
1563 		break;
1564 	case CCLK_EMMC:
1565 	case BCLK_EMMC:
1566 		ret = rk3562_emmc_set_rate(priv, clk->id, rate);
1567 		break;
1568 	case HCLK_SDMMC0:
1569 	case HCLK_SDMMC1:
1570 	case CCLK_SDMMC0:
1571 	case CCLK_SDMMC1:
1572 		ret = rk3562_sdmmc_set_rate(priv, clk->id, rate);
1573 		break;
1574 	case ACLK_VOP:
1575 	case DCLK_VOP:
1576 	case DCLK_VOP1:
1577 		ret = rk3562_vop_set_rate(priv, clk->id, rate);
1578 		break;
1579 	case CLK_GMAC_125M_CRU_I:
1580 	case CLK_GMAC_50M_CRU_I:
1581 	case CLK_GMAC_ETH_OUT2IO:
1582 	case CLK_MAC100_50M_MATRIX:
1583 		ret = rk3562_gmac_set_rate(priv, clk->id, rate);
1584 		break;
1585 	default:
1586 		return -ENOENT;
1587 	}
1588 
1589 	return ret;
1590 };
1591 
1592 #define ROCKCHIP_MMC_DELAY_SEL		BIT(11)
1593 #define ROCKCHIP_MMC_DEGREE_SHIFT	1
1594 #define ROCKCHIP_MMC_DEGREE_MASK	(0x3 << ROCKCHIP_MMC_DEGREE_SHIFT)
1595 #define ROCKCHIP_MMC_DELAYNUM_SHIFT	3
1596 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_SHIFT)
1597 #define PSECS_PER_SEC 1000000000000LL
1598 
1599 /*
1600  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1601  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1602  */
1603 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1604 
rk3562_mmc_get_phase(struct clk * clk)1605 int rk3562_mmc_get_phase(struct clk *clk)
1606 {
1607 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1608 	struct rk3562_cru *cru = priv->cru;
1609 	u32 raw_value, delay_num;
1610 	u16 degrees = 0;
1611 	ulong rate;
1612 
1613 	rate = rk3562_clk_get_rate(clk);
1614 	if (rate < 0)
1615 		return rate;
1616 
1617 	if (clk->id == SCLK_SDMMC0_SAMPLE)
1618 		raw_value = readl(&cru->sdmmc0_con[1]);
1619 	else if (clk->id == SCLK_SDMMC0_SAMPLE)
1620 		raw_value = readl(&cru->sdmmc1_con[1]);
1621 	else
1622 		return -ENONET;
1623 
1624 	raw_value &= ROCKCHIP_MMC_DEGREE_MASK;
1625 	degrees = (raw_value >>  ROCKCHIP_MMC_DEGREE_SHIFT) * 90;
1626 
1627 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1628 		/* degrees/delaynum * 10000 */
1629 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1630 					36 * (rate / 1000000);
1631 
1632 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1633 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_SHIFT;
1634 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1635 	}
1636 
1637 	return degrees % 360;
1638 }
1639 
rk3562_mmc_set_phase(struct clk * clk,u32 degrees)1640 int rk3562_mmc_set_phase(struct clk *clk, u32 degrees)
1641 {
1642 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
1643 	struct rk3562_cru *cru = priv->cru;
1644 	u8 nineties, remainder, delay_num;
1645 	u32 raw_value, delay;
1646 	ulong rate;
1647 
1648 	rate = rk3562_clk_get_rate(clk);
1649 	if (rate < 0)
1650 		return rate;
1651 
1652 	nineties = degrees / 90;
1653 	remainder = (degrees % 90);
1654 
1655 	/*
1656 	 * Convert to delay; do a little extra work to make sure we
1657 	 * don't overflow 32-bit / 64-bit numbers.
1658 	 */
1659 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1660 	delay *= remainder;
1661 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1662 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1663 
1664 	delay_num = (u8)min_t(u32, delay, 255);
1665 
1666 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1667 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_SHIFT;
1668 	raw_value |= nineties << ROCKCHIP_MMC_DEGREE_SHIFT;
1669 
1670 	if (clk->id == SCLK_SDMMC0_SAMPLE)
1671 		writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]);
1672 	else
1673 		writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]);
1674 
1675 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1676 	      degrees, delay_num, raw_value, rk3562_mmc_get_phase(clk));
1677 
1678 	return 0;
1679 }
1680 
rk3562_clk_get_phase(struct clk * clk)1681 static int rk3562_clk_get_phase(struct clk *clk)
1682 {
1683 	int ret;
1684 
1685 	switch (clk->id) {
1686 	case SCLK_SDMMC0_SAMPLE:
1687 	case SCLK_SDMMC1_SAMPLE:
1688 		ret = rk3562_mmc_get_phase(clk);
1689 		break;
1690 	default:
1691 		return -ENOENT;
1692 	}
1693 
1694 	return ret;
1695 }
1696 
rk3562_clk_set_phase(struct clk * clk,int degrees)1697 static int rk3562_clk_set_phase(struct clk *clk, int degrees)
1698 {
1699 	int ret;
1700 
1701 	switch (clk->id) {
1702 	case SCLK_SDMMC0_SAMPLE:
1703 	case SCLK_SDMMC1_SAMPLE:
1704 		ret = rk3562_mmc_set_phase(clk, degrees);
1705 		break;
1706 	default:
1707 		return -ENOENT;
1708 	}
1709 
1710 	return ret;
1711 }
1712 
1713 static struct clk_ops rk3562_clk_ops = {
1714 	.get_rate = rk3562_clk_get_rate,
1715 	.set_rate = rk3562_clk_set_rate,
1716 	.get_phase = rk3562_clk_get_phase,
1717 	.set_phase = rk3562_clk_set_phase,
1718 };
1719 
1720 #ifndef CONFIG_SPL_BUILD
1721 /**
1722  * soc_clk_dump() - Print clock frequencies
1723  * Returns zero on success
1724  *
1725  * Implementation for the clk dump command.
1726  */
soc_clk_dump(void)1727 int soc_clk_dump(void)
1728 {
1729 	const struct rk3562_clk_info *clk_dump;
1730 	struct rk3562_clk_priv *priv;
1731 	struct udevice *cru_dev;
1732 	struct clk clk;
1733 	ulong clk_count = ARRAY_SIZE(clks_dump);
1734 	ulong rate;
1735 	int i, ret;
1736 
1737 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1738 					  DM_GET_DRIVER(rockchip_rk3562_cru),
1739 					  &cru_dev);
1740 	if (ret) {
1741 		printf("%s failed to get cru device\n", __func__);
1742 		return ret;
1743 	}
1744 
1745 	priv = dev_get_priv(cru_dev);
1746 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1747 	       priv->sync_kernel ? "sync kernel" : "uboot",
1748 	       priv->armclk_enter_hz / 1000,
1749 	       priv->armclk_init_hz / 1000,
1750 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1751 	       priv->set_armclk_rate ? " KHz" : "N/A");
1752 	for (i = 0; i < clk_count; i++) {
1753 		clk_dump = &clks_dump[i];
1754 		if (clk_dump->name) {
1755 			clk.id = clk_dump->id;
1756 			ret = clk_request(cru_dev, &clk);
1757 			if (ret < 0)
1758 				return ret;
1759 
1760 			rate = clk_get_rate(&clk);
1761 			clk_free(&clk);
1762 			if (i == 0) {
1763 				if (rate < 0)
1764 					printf("  %s %s\n", clk_dump->name,
1765 					       "unknown");
1766 				else
1767 					printf("  %s %lu KHz\n", clk_dump->name,
1768 					       rate / 1000);
1769 			} else {
1770 				if (rate < 0)
1771 					printf("  %s %s\n", clk_dump->name,
1772 					       "unknown");
1773 				else
1774 					printf("  %s %lu KHz\n", clk_dump->name,
1775 					       rate / 1000);
1776 			}
1777 		}
1778 	}
1779 
1780 	return 0;
1781 }
1782 #endif
1783 
rk3562_clk_init(struct rk3562_clk_priv * priv)1784 static void rk3562_clk_init(struct rk3562_clk_priv *priv)
1785 {
1786 	int ret;
1787 
1788 	priv->sync_kernel = false;
1789 	if (!priv->armclk_enter_hz)
1790 		priv->armclk_enter_hz =
1791 			rockchip_pll_get_rate(&rk3562_pll_clks[APLL],
1792 					      priv->cru, APLL);
1793 
1794 	if (!priv->armclk_init_hz) {
1795 #ifdef CONFIG_SPL_BUILD
1796 		ret = rk3562_armclk_set_rate(priv, APLL_HZ);
1797 		if (!ret)
1798 			priv->armclk_init_hz = APLL_HZ;
1799 
1800 #else
1801 		struct clk clk;
1802 
1803 		ret = rockchip_get_scmi_clk(&clk.dev);
1804 		if (ret) {
1805 			printf("Failed to get scmi clk dev\n");
1806 			return;
1807 		}
1808 
1809 		clk.id = ARMCLK;
1810 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
1811 		if (ret < 0) {
1812 			printf("Failed to set scmi cpu %dhz\n", CPU_PVTPLL_HZ);
1813 			return;
1814 		} else {
1815 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
1816 		}
1817 #endif
1818 	}
1819 	if (priv->cpll_hz != CPLL_HZ) {
1820 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[CPLL], priv->cru,
1821 					    CPLL, CPLL_HZ);
1822 		if (!ret)
1823 			priv->cpll_hz = CPLL_HZ;
1824 	}
1825 
1826 	if (priv->gpll_hz != GPLL_HZ) {
1827 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru,
1828 					    GPLL, GPLL_HZ);
1829 		if (!ret)
1830 			priv->gpll_hz = GPLL_HZ;
1831 	}
1832 
1833 	if (priv->hpll_hz != HPLL_HZ) {
1834 		ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru,
1835 					    HPLL, HPLL_HZ);
1836 		if (!ret)
1837 			priv->hpll_hz = HPLL_HZ;
1838 	}
1839 }
1840 
rk3562_clk_probe(struct udevice * dev)1841 static int rk3562_clk_probe(struct udevice *dev)
1842 {
1843 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
1844 	int ret;
1845 
1846 	rk3562_clk_init(priv);
1847 
1848 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1849 	ret = clk_set_defaults(dev);
1850 	if (ret)
1851 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1852 	else
1853 		priv->sync_kernel = true;
1854 
1855 	return 0;
1856 }
1857 
rk3562_clk_ofdata_to_platdata(struct udevice * dev)1858 static int rk3562_clk_ofdata_to_platdata(struct udevice *dev)
1859 {
1860 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
1861 
1862 	priv->cru = dev_read_addr_ptr(dev);
1863 
1864 	return 0;
1865 }
1866 
rk3562_clk_bind(struct udevice * dev)1867 static int rk3562_clk_bind(struct udevice *dev)
1868 {
1869 	struct udevice *sys_child, *sf_child;
1870 	struct softreset_reg *sf_priv;
1871 	struct sysreset_reg *priv;
1872 	int ret;
1873 
1874 	/* The reset driver does not have a device node, so bind it here */
1875 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1876 				 &sys_child);
1877 	if (ret) {
1878 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1879 	} else {
1880 		priv = malloc(sizeof(struct sysreset_reg));
1881 		priv->glb_srst_fst_value = offsetof(struct rk3562_cru,
1882 						    glb_srst_fst);
1883 		priv->glb_srst_snd_value = offsetof(struct rk3562_cru,
1884 						    glb_srst_snd);
1885 		sys_child->priv = priv;
1886 	}
1887 
1888 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1889 					 dev_ofnode(dev), &sf_child);
1890 	if (ret) {
1891 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1892 	} else {
1893 		sf_priv = malloc(sizeof(struct softreset_reg));
1894 		sf_priv->sf_reset_offset = offsetof(struct rk3562_cru,
1895 						    softrst_con[0]);
1896 		/* (0x30444 - 0x400) / 4 + 1 = 49170 */
1897 		sf_priv->sf_reset_num = 49170;
1898 		sf_child->priv = sf_priv;
1899 	}
1900 
1901 	return 0;
1902 }
1903 
1904 static const struct udevice_id rk3562_clk_ids[] = {
1905 	{ .compatible = "rockchip,rk3562-cru" },
1906 	{ }
1907 };
1908 
1909 U_BOOT_DRIVER(rockchip_rk3562_cru) = {
1910 	.name		= "rockchip_rk3562_cru",
1911 	.id		= UCLASS_CLK,
1912 	.of_match	= rk3562_clk_ids,
1913 	.priv_auto_alloc_size = sizeof(struct rk3562_clk_priv),
1914 	.ofdata_to_platdata = rk3562_clk_ofdata_to_platdata,
1915 	.ops		= &rk3562_clk_ops,
1916 	.bind		= rk3562_clk_bind,
1917 	.probe		= rk3562_clk_probe,
1918 };
1919 
1920 /* spl scmi clk */
1921 #ifdef CONFIG_SPL_BUILD
1922 
rk3562_crypto_get_rate(struct rk3562_clk_priv * priv,ulong clk_id)1923 static ulong rk3562_crypto_get_rate(struct rk3562_clk_priv *priv, ulong clk_id)
1924 {
1925 	struct rk3562_cru *cru = priv->cru;
1926 	u32 sel, con;
1927 	ulong rate;
1928 
1929 	con = readl(&cru->periclksel_con[43]);
1930 	switch (clk_id) {
1931 	case CLK_CORE_CRYPTO:
1932 		sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
1933 		       CLK_CORE_CRYPTO_SEL_SHIFT;
1934 		if (sel == CLK_CORE_CRYPTO_SEL_200M)
1935 			rate = 200 * MHz;
1936 		else if (sel == CLK_CORE_CRYPTO_SEL_100M)
1937 			rate = 100 * MHz;
1938 		else
1939 			rate = OSC_HZ;
1940 		break;
1941 	case CLK_PKA_CRYPTO:
1942 		sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
1943 		       CLK_PKA_CRYPTO_SEL_SHIFT;
1944 		if (sel == CLK_PKA_CRYPTO_SEL_300M)
1945 			rate = 300 * MHz;
1946 		else if (sel == CLK_PKA_CRYPTO_SEL_200M)
1947 			rate = 200 * MHz;
1948 		else if (sel == CLK_PKA_CRYPTO_SEL_100M)
1949 			rate = 100 * MHz;
1950 		else
1951 			rate = OSC_HZ;
1952 		break;
1953 	default:
1954 		return -ENOENT;
1955 	}
1956 
1957 	return rate;
1958 }
1959 
rk3562_crypto_set_rate(struct rk3562_clk_priv * priv,ulong clk_id,ulong rate)1960 static ulong rk3562_crypto_set_rate(struct rk3562_clk_priv *priv, ulong clk_id,
1961 				    ulong rate)
1962 {
1963 	struct rk3562_cru *cru = priv->cru;
1964 	u32 mask, shift, sel;
1965 
1966 	switch (clk_id) {
1967 	case CLK_CORE_CRYPTO:
1968 		mask = CLK_CORE_CRYPTO_SEL_MASK;
1969 		shift =	CLK_CORE_CRYPTO_SEL_SHIFT;
1970 		if (rate == 200 * MHz)
1971 			sel = CLK_CORE_CRYPTO_SEL_200M;
1972 		else if (rate == 100 * MHz)
1973 			sel = CLK_CORE_CRYPTO_SEL_100M;
1974 		else
1975 			sel = CLK_CORE_CRYPTO_SEL_24M;
1976 		break;
1977 	case CLK_PKA_CRYPTO:
1978 		mask = CLK_PKA_CRYPTO_SEL_MASK;
1979 		shift =	CLK_PKA_CRYPTO_SEL_SHIFT;
1980 		if (rate == 300 * MHz)
1981 			sel = CLK_PKA_CRYPTO_SEL_300M;
1982 		else if (rate == 200 * MHz)
1983 			sel = CLK_PKA_CRYPTO_SEL_200M;
1984 		else if (rate == 100 * MHz)
1985 			sel = CLK_PKA_CRYPTO_SEL_100M;
1986 		else
1987 			sel = CLK_PKA_CRYPTO_SEL_24M;
1988 		break;
1989 	default:
1990 		return -ENOENT;
1991 	}
1992 	rk_clrsetreg(&cru->periclksel_con[43], mask, sel << shift);
1993 
1994 	return rk3562_crypto_get_rate(priv, clk_id);
1995 }
1996 
rk3562_clk_scmi_get_rate(struct clk * clk)1997 static ulong rk3562_clk_scmi_get_rate(struct clk *clk)
1998 {
1999 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
2000 
2001 	switch (clk->id) {
2002 	case CLK_CORE_CRYPTO:
2003 	case CLK_PKA_CRYPTO:
2004 		return rk3562_crypto_get_rate(priv, clk->id);
2005 	default:
2006 		return -ENOENT;
2007 	}
2008 };
2009 
rk3562_clk_scmi_set_rate(struct clk * clk,ulong rate)2010 static ulong rk3562_clk_scmi_set_rate(struct clk *clk, ulong rate)
2011 {
2012 	struct rk3562_clk_priv *priv = dev_get_priv(clk->dev);
2013 
2014 	switch (clk->id) {
2015 	case CLK_CORE_CRYPTO:
2016 	case CLK_PKA_CRYPTO:
2017 		return rk3562_crypto_set_rate(priv, clk->id, rate);
2018 	default:
2019 		return -ENOENT;
2020 	}
2021 	return 0;
2022 };
2023 
rk3562_scmi_clk_ofdata_to_platdata(struct udevice * dev)2024 static int rk3562_scmi_clk_ofdata_to_platdata(struct udevice *dev)
2025 {
2026 	struct rk3562_clk_priv *priv = dev_get_priv(dev);
2027 
2028 	priv->cru = (struct rk3562_cru *)0xff100000;
2029 
2030 	return 0;
2031 }
2032 
2033 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2034 static const struct clk_ops scmi_clk_ops = {
2035 	.get_rate = rk3562_clk_scmi_get_rate,
2036 	.set_rate = rk3562_clk_scmi_set_rate,
2037 };
2038 
2039 U_BOOT_DRIVER(scmi_clock) = {
2040 	.name = "scmi_clk",
2041 	.id = UCLASS_CLK,
2042 	.ops = &scmi_clk_ops,
2043 	.priv_auto_alloc_size = sizeof(struct rk3562_clk_priv),
2044 	.ofdata_to_platdata = rk3562_scmi_clk_ofdata_to_platdata,
2045 };
2046 #endif
2047