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