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