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