1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd
4 * Author: Elaine Zhang <zhangqing@rock-chips.com>
5 */
6
7 #include <common.h>
8 #include <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rv1103b.h>
15 #include <asm/arch/grf_rv1103b.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rockchip,rv1103b-cru.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
24
25 #ifdef CONFIG_SPL_BUILD
26 #ifndef BITS_WITH_WMASK
27 #define BITS_WITH_WMASK(bits, msk, shift) \
28 ((bits) << (shift)) | ((msk) << ((shift) + 16))
29 #endif
30 #endif
31
32 static struct rockchip_pll_rate_table rv1103b_pll_rates[] = {
33 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
34 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
35 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
36 { /* sentinel */ },
37 };
38
39 static struct rockchip_pll_clock rv1103b_pll_clks[] = {
40 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1103B_PLL_CON(24),
41 RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),
42 };
43
44 #ifndef CONFIG_SPL_BUILD
45 #define RV1103B_CLK_DUMP(_id, _name, _iscru) \
46 { \
47 .id = _id, \
48 .name = _name, \
49 .is_cru = _iscru, \
50 }
51
52 static const struct rv1103b_clk_info clks_dump[] = {
53 RV1103B_CLK_DUMP(PLL_GPLL, "gpll", true),
54 RV1103B_CLK_DUMP(ACLK_PERI_SRC, "aclk_peri_src", true),
55 RV1103B_CLK_DUMP(LSCLK_PERI_SRC, "lsclk_peri_src", true),
56 RV1103B_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true),
57 RV1103B_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
58 RV1103B_CLK_DUMP(LSCLK_PMU_ROOT, "lsclk_pmu_root", true),
59 };
60 #endif
61
rv1103b_peri_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)62 static ulong rv1103b_peri_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
63 {
64 struct rv1103b_cru *cru = priv->cru;
65 u32 con, sel, div, rate, prate;
66
67 switch (clk_id) {
68 case ACLK_PERI_SRC:
69 con = readl(&cru->clksel_con[31]);
70 sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
71 if (sel == ACLK_PERI_SEL_600M)
72 rate = 600 * MHz;
73 else if (sel == ACLK_PERI_SEL_480M)
74 rate = 480 * MHz;
75 else
76 rate = 400 * MHz;
77 break;
78 case LSCLK_PERI_SRC:
79 con = readl(&cru->clksel_con[31]);
80 sel = (con & LSCLK_PERI_SEL_MASK) >> LSCLK_PERI_SEL_SHIFT;
81 if (sel == LSCLK_PERI_SEL_300M)
82 rate = 300 * MHz;
83 else
84 rate = 200 * MHz;
85 break;
86 case PCLK_PERI_ROOT:
87 con = readl(&cru->peri_clksel_con[0]);
88 div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
89 rate = DIV_TO_RATE(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
90 div);
91 break;
92 case PCLK_TOP_ROOT:
93 rate = DIV_TO_RATE(priv->gpll_hz, 11);
94 break;
95 case LSCLK_PMU_ROOT:
96 case PCLK_PMU:
97 con = readl(&cru->pmu_clksel_con[2]);
98 sel = (con & LSCLK_PMU_SEL_MASK) >> LSCLK_PMU_SEL_SHIFT;
99 div = (con & LSCLK_PMU_DIV_MASK) >> LSCLK_PMU_DIV_SHIFT;
100 if (sel == LSCLK_PMU_SEL_24M)
101 prate = OSC_HZ;
102 else
103 prate = RC_OSC_HZ;
104 rate = DIV_TO_RATE(prate, div);
105 break;
106 default:
107 return -ENOENT;
108 }
109
110 return rate;
111 }
112
rv1103b_peri_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)113 static ulong rv1103b_peri_set_clk(struct rv1103b_clk_priv *priv,
114 ulong clk_id, ulong rate)
115 {
116 struct rv1103b_cru *cru = priv->cru;
117 int src_clk, div;
118
119 switch (clk_id) {
120 case ACLK_PERI_SRC:
121 if (rate >= 594 * MHz)
122 src_clk = ACLK_PERI_SEL_600M;
123 else if (rate >= 480 * MHz)
124 src_clk = ACLK_PERI_SEL_480M;
125 else
126 src_clk = ACLK_PERI_SEL_400M;
127 rk_clrsetreg(&cru->clksel_con[31],
128 ACLK_PERI_SEL_MASK,
129 src_clk << ACLK_PERI_SEL_SHIFT);
130 break;
131 case LSCLK_PERI_SRC:
132 if (rate >= 297 * MHz)
133 src_clk = LSCLK_PERI_SEL_300M;
134 else
135 src_clk = LSCLK_PERI_SEL_200M;
136 rk_clrsetreg(&cru->clksel_con[31],
137 LSCLK_PERI_SEL_MASK,
138 src_clk << LSCLK_PERI_SEL_SHIFT);
139 break;
140 case PCLK_PERI_ROOT:
141 div = DIV_ROUND_UP(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
142 rate);
143 rk_clrsetreg(&cru->peri_clksel_con[0],
144 PCLK_PERI_DIV_MASK,
145 (div - 1) << PCLK_PERI_DIV_SHIFT);
146 break;
147 case PCLK_TOP_ROOT:
148 break;
149 case LSCLK_PMU_ROOT:
150 case PCLK_PMU:
151 if (!(OSC_HZ % rate)) {
152 src_clk = LSCLK_PMU_SEL_24M;
153 div = DIV_ROUND_UP(OSC_HZ, rate);
154 } else {
155 src_clk = LSCLK_PMU_SEL_RC_OSC;
156 div = DIV_ROUND_UP(RC_OSC_HZ, rate);
157 }
158 rk_clrsetreg(&cru->pmu_clksel_con[2],
159 LSCLK_PMU_SEL_MASK | LSCLK_PMU_DIV_MASK,
160 (src_clk << LSCLK_PMU_SEL_SHIFT) |
161 ((div - 1) << LSCLK_PMU_DIV_SHIFT));
162 break;
163 default:
164 printf("do not support this permid freq\n");
165 return -EINVAL;
166 }
167
168 return rv1103b_peri_get_clk(priv, clk_id);
169 }
170
rv1103b_i2c_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)171 static ulong rv1103b_i2c_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
172 {
173 struct rv1103b_cru *cru = priv->cru;
174 u32 sel, con;
175 ulong rate;
176
177 switch (clk_id) {
178 case CLK_I2C1:
179 case CLK_I2C2:
180 case CLK_I2C3:
181 case CLK_I2C4:
182 case CLK_I2C_PERI:
183 con = readl(&cru->clksel_con[34]);
184 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
185 break;
186 case CLK_I2C0:
187 case CLK_I2C_PMU:
188 con = readl(&cru->clksel_con[34]);
189 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
190 break;
191 default:
192 return -ENOENT;
193 }
194
195 if (sel == CLK_I2C_SEL_100M)
196 rate = 100 * MHz;
197 else
198 rate = OSC_HZ;
199
200 return rate;
201 }
202
rv1103b_crypto_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)203 static ulong rv1103b_crypto_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
204 {
205 struct rv1103b_cru *cru = priv->cru;
206 u32 sel, con, rate;
207
208 switch (clk_id) {
209 case ACLK_CRYPTO:
210 case HCLK_CRYPTO:
211 case HCLK_RK_RNG_NS:
212 case HCLK_RK_RNG_S:
213 return rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC);
214 case CLK_CORE_CRYPTO:
215 con = readl(&cru->clksel_con[35]);
216 sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
217 CLK_CORE_CRYPTO_SEL_SHIFT;
218 break;
219 case CLK_PKA_CRYPTO:
220 con = readl(&cru->clksel_con[35]);
221 sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
222 CLK_PKA_CRYPTO_SEL_SHIFT;
223 break;
224 default:
225 return -ENOENT;
226 }
227 if (sel == CLK_CORE_CRYPTO_SEL_300M)
228 rate = 300 * MHz;
229 else if (sel == CLK_CORE_CRYPTO_SEL_200M)
230 rate = 200 * MHz;
231 else
232 rate = 100 * MHz;
233
234 return rate;
235
236 }
237
rv1103b_crypto_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)238 static ulong rv1103b_crypto_set_clk(struct rv1103b_clk_priv *priv,
239 ulong clk_id, ulong rate)
240 {
241 struct rv1103b_cru *cru = priv->cru;
242 u32 sel;
243
244 if (rate >= 297 * MHz)
245 sel = CLK_CORE_CRYPTO_SEL_300M;
246 else if (rate >= 198 * MHz)
247 sel = CLK_CORE_CRYPTO_SEL_200M;
248 else
249 sel = CLK_CORE_CRYPTO_SEL_100M;
250
251 switch (clk_id) {
252 case ACLK_CRYPTO:
253 case HCLK_CRYPTO:
254 case HCLK_RK_RNG_NS:
255 case HCLK_RK_RNG_S:
256 rv1103b_peri_set_clk(priv, LSCLK_PERI_SRC, rate);
257 case CLK_CORE_CRYPTO:
258 rk_clrsetreg(&cru->clksel_con[35],
259 CLK_CORE_CRYPTO_SEL_MASK,
260 (sel << CLK_CORE_CRYPTO_SEL_SHIFT));
261 break;
262 case CLK_PKA_CRYPTO:
263 rk_clrsetreg(&cru->clksel_con[35],
264 CLK_PKA_CRYPTO_SEL_MASK,
265 (sel << CLK_PKA_CRYPTO_SEL_SHIFT));
266 break;
267 default:
268 return -ENOENT;
269 }
270 return rv1103b_crypto_get_clk(priv, clk_id);
271 }
272
rv1103b_mmc_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)273 static ulong rv1103b_mmc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
274 {
275 struct rv1103b_cru *cru = priv->cru;
276 u32 div, sel, con, prate;
277
278 switch (clk_id) {
279 case CCLK_SDMMC1:
280 case HCLK_SDMMC1:
281 con = readl(&cru->clksel_con[36]);
282 sel = (con & CLK_SDMMC_SEL_MASK) >>
283 CLK_SDMMC_SEL_SHIFT;
284 div = (con & CLK_SDMMC_DIV_MASK) >>
285 CLK_SDMMC_DIV_SHIFT;
286 if (sel == CLK_MMC_SEL_GPLL)
287 prate = priv->gpll_hz;
288 else
289 prate = OSC_HZ;
290 return DIV_TO_RATE(prate, div);
291 case CCLK_SDMMC0:
292 case HCLK_SDMMC0:
293 con = readl(&cru->clksel_con[32]);
294 sel = (con & CLK_SDMMC_SEL_MASK) >>
295 CLK_SDMMC_SEL_SHIFT;
296 div = (con & CLK_SDMMC_DIV_MASK) >>
297 CLK_SDMMC_DIV_SHIFT;
298 if (sel == CLK_MMC_SEL_GPLL)
299 prate = priv->gpll_hz;
300 else
301 prate = OSC_HZ;
302 return DIV_TO_RATE(prate, div);
303 case CCLK_EMMC:
304 case HCLK_EMMC:
305 con = readl(&cru->clksel_con[31]);
306 sel = (con & CLK_EMMC_SEL_MASK) >>
307 CLK_EMMC_SEL_SHIFT;
308 div = (con & CLK_EMMC_DIV_MASK) >>
309 CLK_EMMC_DIV_SHIFT;
310 if (sel == CLK_MMC_SEL_GPLL)
311 prate = priv->gpll_hz;
312 else
313 prate = OSC_HZ;
314 return DIV_TO_RATE(prate, div);
315 case SCLK_SFC_2X:
316 case HCLK_SFC:
317 con = readl(&cru->clksel_con[33]);
318 sel = (con & CLK_SFC_SEL_MASK) >>
319 CLK_SFC_SEL_SHIFT;
320 div = (con & CLK_SFC_DIV_MASK) >>
321 CLK_SFC_DIV_SHIFT;
322 if (sel == CLK_MMC_SEL_GPLL)
323 prate = priv->gpll_hz;
324 else
325 prate = OSC_HZ;
326 return DIV_TO_RATE(prate, div);
327 default:
328 return -ENOENT;
329 }
330 }
331
rv1103b_mmc_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)332 static ulong rv1103b_mmc_set_clk(struct rv1103b_clk_priv *priv,
333 ulong clk_id, ulong rate)
334 {
335 struct rv1103b_cru *cru = priv->cru;
336 u32 sel, src_clk_div;
337 ulong prate = 0;
338
339 if ((OSC_HZ % rate) == 0) {
340 sel = CLK_MMC_SEL_OSC;
341 prate = OSC_HZ;
342 } else {
343 sel = CLK_MMC_SEL_GPLL;
344 prate = priv->gpll_hz;
345 }
346 src_clk_div = DIV_ROUND_UP(prate, rate);
347
348 switch (clk_id) {
349 case CCLK_SDMMC1:
350 case HCLK_SDMMC1:
351 src_clk_div = DIV_ROUND_UP(prate, rate);
352 rk_clrsetreg(&cru->clksel_con[36],
353 CLK_SDMMC_SEL_MASK |
354 CLK_SDMMC_DIV_MASK,
355 (sel << CLK_SDMMC_SEL_SHIFT) |
356 ((src_clk_div - 1) <<
357 CLK_SDMMC_DIV_SHIFT));
358 break;
359 case CCLK_SDMMC0:
360 case HCLK_SDMMC0:
361 src_clk_div = DIV_ROUND_UP(prate, rate);
362 rk_clrsetreg(&cru->clksel_con[32],
363 CLK_SDMMC_SEL_MASK |
364 CLK_SDMMC_DIV_MASK,
365 (sel << CLK_SDMMC_SEL_SHIFT) |
366 ((src_clk_div - 1) <<
367 CLK_SDMMC_DIV_SHIFT));
368 break;
369 case CCLK_EMMC:
370 case HCLK_EMMC:
371 src_clk_div = DIV_ROUND_UP(prate, rate);
372 rk_clrsetreg(&cru->clksel_con[31],
373 CLK_EMMC_SEL_MASK |
374 CLK_EMMC_DIV_MASK,
375 (sel << CLK_EMMC_SEL_SHIFT) |
376 ((src_clk_div - 1) <<
377 CLK_EMMC_DIV_SHIFT));
378 break;
379 case SCLK_SFC_2X:
380 case HCLK_SFC:
381 src_clk_div = DIV_ROUND_UP(prate, rate);
382 rk_clrsetreg(&cru->clksel_con[33],
383 CLK_SFC_SEL_MASK |
384 CLK_SFC_DIV_MASK,
385 (sel << CLK_SFC_SEL_SHIFT) |
386 ((src_clk_div - 1) <<
387 CLK_SFC_DIV_SHIFT));
388 break;
389 default:
390 return -ENOENT;
391 }
392 return rv1103b_mmc_get_clk(priv, clk_id);
393 }
394
rv1103b_i2c_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)395 static ulong rv1103b_i2c_set_clk(struct rv1103b_clk_priv *priv, ulong clk_id,
396 ulong rate)
397 {
398 struct rv1103b_cru *cru = priv->cru;
399 int src_clk;
400
401 if (rate == OSC_HZ)
402 src_clk = CLK_I2C_SEL_24M;
403 else
404 src_clk = CLK_I2C_SEL_100M;
405
406 switch (clk_id) {
407 case CLK_I2C1:
408 case CLK_I2C2:
409 case CLK_I2C3:
410 case CLK_I2C4:
411 case CLK_I2C_PERI:
412 rk_clrsetreg(&cru->clksel_con[34], CLK_I2C1_SEL_MASK,
413 src_clk << CLK_I2C1_SEL_SHIFT);
414 break;
415 case CLK_I2C0:
416 case CLK_I2C_PMU:
417 rk_clrsetreg(&cru->clksel_con[34], CLK_I2C0_SEL_MASK,
418 src_clk << CLK_I2C0_SEL_SHIFT);
419 break;
420 default:
421 return -ENOENT;
422 }
423 return rv1103b_i2c_get_clk(priv, clk_id);
424 }
425
rv1103b_spi_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)426 static ulong rv1103b_spi_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
427 {
428 struct rv1103b_cru *cru = priv->cru;
429 u32 sel, con, rate;
430
431 switch (clk_id) {
432 case CLK_SPI0:
433 con = readl(&cru->clksel_con[34]);
434 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
435 break;
436 default:
437 return -ENOENT;
438 }
439 if (sel == CLK_SPI0_SEL_200M)
440 rate = 200 * MHz;
441 else if (sel == CLK_SPI0_SEL_100M)
442 rate = 100 * MHz;
443 else if (sel == CLK_SPI0_SEL_50M)
444 rate = 50 * MHz;
445 else
446 rate = OSC_HZ;
447
448 return rate;
449 }
450
rv1103b_spi_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)451 static ulong rv1103b_spi_set_clk(struct rv1103b_clk_priv *priv,
452 ulong clk_id, ulong rate)
453 {
454 struct rv1103b_cru *cru = priv->cru;
455 int src_clk;
456
457 if (rate >= 198 * MHz)
458 src_clk = CLK_SPI0_SEL_200M;
459 else if (rate >= 99 * MHz)
460 src_clk = CLK_SPI0_SEL_100M;
461 else if (rate >= 48 * MHz)
462 src_clk = CLK_SPI0_SEL_50M;
463 else
464 src_clk = CLK_SPI0_SEL_24M;
465
466 switch (clk_id) {
467 case CLK_SPI0:
468 rk_clrsetreg(&cru->clksel_con[34], CLK_SPI0_SEL_MASK,
469 src_clk << CLK_SPI0_SEL_SHIFT);
470 break;
471 default:
472 return -ENOENT;
473 }
474
475 return rv1103b_spi_get_clk(priv, clk_id);
476 }
477
rv1103b_pwm_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)478 static ulong rv1103b_pwm_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
479 {
480 struct rv1103b_cru *cru = priv->cru;
481 u32 sel, con;
482
483 switch (clk_id) {
484 case CLK_PWM0:
485 case CLK_PWM0_SRC:
486 con = readl(&cru->clksel_con[34]);
487 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
488 break;
489 case CLK_PWM1:
490 con = readl(&cru->clksel_con[34]);
491 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
492 break;
493 case CLK_PWM2:
494 con = readl(&cru->clksel_con[34]);
495 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
496 break;
497 default:
498 return -ENOENT;
499 }
500
501 switch (sel) {
502 case CLK_PWM_SEL_100M:
503 return 100 * MHz;
504 case CLK_PWM_SEL_24M:
505 return OSC_HZ;
506 default:
507 return -ENOENT;
508 }
509 }
510
rv1103b_pwm_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)511 static ulong rv1103b_pwm_set_clk(struct rv1103b_clk_priv *priv,
512 ulong clk_id, ulong rate)
513 {
514 struct rv1103b_cru *cru = priv->cru;
515 int src_clk;
516
517 if (rate >= 99 * MHz)
518 src_clk = CLK_PWM_SEL_100M;
519 else
520 src_clk = CLK_PWM_SEL_24M;
521
522 switch (clk_id) {
523 case CLK_PWM0:
524 case CLK_PWM0_SRC:
525 rk_clrsetreg(&cru->clksel_con[34],
526 CLK_PWM0_SEL_MASK,
527 src_clk << CLK_PWM0_SEL_SHIFT);
528 break;
529 case CLK_PWM1:
530 rk_clrsetreg(&cru->clksel_con[34],
531 CLK_PWM1_SEL_MASK,
532 src_clk << CLK_PWM1_SEL_SHIFT);
533 break;
534 case CLK_PWM2:
535 rk_clrsetreg(&cru->clksel_con[34],
536 CLK_PWM2_SEL_MASK,
537 src_clk << CLK_PWM2_SEL_SHIFT);
538 break;
539 default:
540 return -ENOENT;
541 }
542
543 return rv1103b_pwm_get_clk(priv, clk_id);
544 }
545
rv1103b_adc_get_clk(struct rv1103b_clk_priv * priv,ulong clk_id)546 static ulong rv1103b_adc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
547 {
548 struct rv1103b_cru *cru = priv->cru;
549 u32 div, con;
550
551 switch (clk_id) {
552 case CLK_SARADC:
553 con = readl(&cru->peri_clksel_con[1]);
554 div = (con & CLK_SARADC_DIV_MASK) >>
555 CLK_SARADC_DIV_SHIFT;
556 return DIV_TO_RATE(OSC_HZ, div);
557 case CLK_TSADC_TSEN:
558 con = readl(&cru->peri_clksel_con[0]);
559 div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
560 CLK_TSADC_TSEN_DIV_SHIFT;
561 return DIV_TO_RATE(OSC_HZ, div);
562 case CLK_TSADC:
563 con = readl(&cru->peri_clksel_con[0]);
564 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
565 return DIV_TO_RATE(OSC_HZ, div);
566 default:
567 return -ENOENT;
568 }
569 }
570
rv1103b_adc_set_clk(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)571 static ulong rv1103b_adc_set_clk(struct rv1103b_clk_priv *priv,
572 ulong clk_id, ulong rate)
573 {
574 struct rv1103b_cru *cru = priv->cru;
575 int src_clk_div;
576
577 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
578
579 switch (clk_id) {
580 case CLK_SARADC:
581 assert(src_clk_div - 1 <= 7);
582 rk_clrsetreg(&cru->peri_clksel_con[1],
583 CLK_SARADC_DIV_MASK,
584 (src_clk_div - 1) <<
585 CLK_SARADC_DIV_SHIFT);
586 break;
587 case CLK_TSADC_TSEN:
588 assert(src_clk_div - 1 <= 32);
589 rk_clrsetreg(&cru->peri_clksel_con[0],
590 CLK_TSADC_TSEN_DIV_MASK,
591 (src_clk_div - 1) <<
592 CLK_TSADC_TSEN_DIV_SHIFT);
593 break;
594 case CLK_TSADC:
595 assert(src_clk_div - 1 <= 32);
596 rk_clrsetreg(&cru->peri_clksel_con[0],
597 CLK_TSADC_DIV_MASK,
598 (src_clk_div - 1) <<
599 CLK_TSADC_DIV_SHIFT);
600 break;
601 default:
602 return -ENOENT;
603 }
604 return rv1103b_adc_get_clk(priv, clk_id);
605 }
606
607 /*
608 *
609 * rational_best_approximation(31415, 10000,
610 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
611 *
612 * you may look at given_numerator as a fixed point number,
613 * with the fractional part size described in given_denominator.
614 *
615 * for theoretical background, see:
616 * http://en.wikipedia.org/wiki/Continued_fraction
617 */
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)618 static void rational_best_approximation(unsigned long given_numerator,
619 unsigned long given_denominator,
620 unsigned long max_numerator,
621 unsigned long max_denominator,
622 unsigned long *best_numerator,
623 unsigned long *best_denominator)
624 {
625 unsigned long n, d, n0, d0, n1, d1;
626
627 n = given_numerator;
628 d = given_denominator;
629 n0 = 0;
630 d1 = 0;
631 n1 = 1;
632 d0 = 1;
633 for (;;) {
634 unsigned long t, a;
635
636 if (n1 > max_numerator || d1 > max_denominator) {
637 n1 = n0;
638 d1 = d0;
639 break;
640 }
641 if (d == 0)
642 break;
643 t = d;
644 a = n / d;
645 d = n % d;
646 n = t;
647 t = n0 + a * n1;
648 n0 = n1;
649 n1 = t;
650 t = d0 + a * d1;
651 d0 = d1;
652 d1 = t;
653 }
654 *best_numerator = n1;
655 *best_denominator = d1;
656 }
657
rv1103b_uart_get_rate(struct rv1103b_clk_priv * priv,ulong clk_id)658 static ulong rv1103b_uart_get_rate(struct rv1103b_clk_priv *priv, ulong clk_id)
659 {
660 struct rv1103b_cru *cru = priv->cru;
661 u32 reg, con, fracdiv, div, src, p_rate;
662 unsigned long m, n;
663
664 switch (clk_id) {
665 case SCLK_UART0:
666 reg = 10;
667 con = readl(&cru->clksel_con[32]);
668 src = (con & CLK_UART0_SEL_MASK) >> CLK_UART0_SEL_SHIFT;
669 con = readl(&cru->clksel_con[5]);
670 div = (con & CLK_UART0_SRC_DIV_MASK) >> CLK_UART0_SRC_DIV_SHIFT;
671 break;
672 case SCLK_UART1:
673 reg = 11;
674 con = readl(&cru->clksel_con[32]);
675 src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
676 con = readl(&cru->clksel_con[5]);
677 div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
678 break;
679 case SCLK_UART2:
680 reg = 12;
681 con = readl(&cru->clksel_con[32]);
682 src = (con & CLK_UART2_SEL_MASK) >> CLK_UART2_SEL_SHIFT;
683 con = readl(&cru->clksel_con[5]);
684 div = (con & CLK_UART2_SRC_DIV_MASK) >> CLK_UART2_SRC_DIV_SHIFT;
685 break;
686 default:
687 return -ENOENT;
688 }
689
690 p_rate = priv->gpll_hz;
691 if (src == CLK_UART_SEL_SRC) {
692 return DIV_TO_RATE(p_rate, div);
693 } else if (src == CLK_UART_SEL_FRAC) {
694 fracdiv = readl(&cru->clksel_con[reg]);
695 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
696 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
697 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
698 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
699 return DIV_TO_RATE(p_rate, div) * n / m;
700 } else {
701 return OSC_HZ;
702 }
703 }
704
rv1103b_uart_set_rate(struct rv1103b_clk_priv * priv,ulong clk_id,ulong rate)705 static ulong rv1103b_uart_set_rate(struct rv1103b_clk_priv *priv,
706 ulong clk_id, ulong rate)
707 {
708 struct rv1103b_cru *cru = priv->cru;
709 u32 reg, uart_src, div;
710 unsigned long m = 0, n = 0, val;
711
712 if (priv->gpll_hz % rate == 0) {
713 uart_src = CLK_UART_SEL_SRC;
714 div = DIV_ROUND_UP(priv->gpll_hz, rate);
715 } else if (rate == OSC_HZ) {
716 uart_src = CLK_UART_SEL_OSC;
717 div = 2;
718 } else {
719 uart_src = CLK_UART_SEL_FRAC;
720 div = 2;
721 rational_best_approximation(rate, priv->gpll_hz / div,
722 GENMASK(16 - 1, 0),
723 GENMASK(16 - 1, 0),
724 &m, &n);
725 }
726
727 switch (clk_id) {
728 case SCLK_UART0:
729 reg = 10;
730 rk_clrsetreg(&cru->clksel_con[5],
731 CLK_UART0_SRC_DIV_MASK,
732 div << CLK_UART0_SRC_DIV_SHIFT);
733 rk_clrsetreg(&cru->clksel_con[32],
734 CLK_UART0_SEL_MASK,
735 uart_src << CLK_UART0_SEL_SHIFT);
736 break;
737 case SCLK_UART1:
738 reg = 11;
739 rk_clrsetreg(&cru->clksel_con[5],
740 CLK_UART1_SRC_DIV_MASK,
741 div << CLK_UART1_SRC_DIV_SHIFT);
742 rk_clrsetreg(&cru->clksel_con[32],
743 CLK_UART1_SEL_MASK,
744 uart_src << CLK_UART1_SEL_SHIFT);
745 break;
746 case SCLK_UART2:
747 reg = 12;
748 rk_clrsetreg(&cru->clksel_con[5],
749 CLK_UART2_SRC_DIV_MASK,
750 div << CLK_UART2_SRC_DIV_SHIFT);
751 rk_clrsetreg(&cru->clksel_con[32],
752 CLK_UART2_SEL_MASK,
753 uart_src << CLK_UART2_SEL_SHIFT);
754 break;
755 default:
756 return -ENOENT;
757 }
758 if (m && n) {
759 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
760 writel(val, &cru->clksel_con[reg]);
761 }
762
763 return rv1103b_uart_get_rate(priv, clk_id);
764 }
765
rv1103b_decom_get_clk(struct rv1103b_clk_priv * priv)766 static ulong rv1103b_decom_get_clk(struct rv1103b_clk_priv *priv)
767 {
768 struct rv1103b_cru *cru = priv->cru;
769 u32 sel, con, prate;
770
771 con = readl(&cru->clksel_con[35]);
772 sel = (con & DCLK_DECOM_SEL_MASK) >>
773 DCLK_DECOM_SEL_SHIFT;
774 if (sel == DCLK_DECOM_SEL_480M)
775 prate = 480 * MHz;
776 else if (sel == DCLK_DECOM_SEL_400M)
777 prate = 400 * MHz;
778 else
779 prate = 300 * MHz;
780 return prate;
781 }
782
rv1103b_decom_set_clk(struct rv1103b_clk_priv * priv,ulong rate)783 static ulong rv1103b_decom_set_clk(struct rv1103b_clk_priv *priv, ulong rate)
784 {
785 struct rv1103b_cru *cru = priv->cru;
786 u32 sel;
787
788 if (rate >= 480 * MHz)
789 sel = DCLK_DECOM_SEL_480M;
790 else if (rate >= 396 * MHz)
791 sel = DCLK_DECOM_SEL_400M;
792 else
793 sel = DCLK_DECOM_SEL_300M;
794 rk_clrsetreg(&cru->clksel_con[35], DCLK_DECOM_SEL_MASK,
795 (sel << DCLK_DECOM_SEL_SHIFT));
796
797 return rv1103b_decom_get_clk(priv);
798 }
799
rv1103b_clk_get_rate(struct clk * clk)800 static ulong rv1103b_clk_get_rate(struct clk *clk)
801 {
802 struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
803 ulong rate = 0;
804
805 if (!priv->gpll_hz) {
806 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
807 return -ENOENT;
808 }
809
810 switch (clk->id) {
811 case PLL_GPLL:
812 rate = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL], priv->cru,
813 GPLL);
814 break;
815 case ACLK_PERI_SRC:
816 case LSCLK_PERI_SRC:
817 case PCLK_PERI_ROOT:
818 case PCLK_TOP_ROOT:
819 case LSCLK_PMU_ROOT:
820 case PCLK_PMU:
821 rate = rv1103b_peri_get_clk(priv, clk->id);
822 break;
823 case ACLK_CRYPTO:
824 case HCLK_CRYPTO:
825 case HCLK_RK_RNG_NS:
826 case HCLK_RK_RNG_S:
827 case CLK_CORE_CRYPTO:
828 case CLK_PKA_CRYPTO:
829 rate = rv1103b_crypto_get_clk(priv, clk->id);
830 break;
831 case CCLK_SDMMC1:
832 case HCLK_SDMMC1:
833 case CCLK_SDMMC0:
834 case HCLK_SDMMC0:
835 case CCLK_EMMC:
836 case HCLK_EMMC:
837 case SCLK_SFC_2X:
838 case HCLK_SFC:
839 rate = rv1103b_mmc_get_clk(priv, clk->id);
840 break;
841 case CLK_I2C1:
842 case CLK_I2C2:
843 case CLK_I2C3:
844 case CLK_I2C4:
845 case CLK_I2C_PERI:
846 case CLK_I2C0:
847 case CLK_I2C_PMU:
848 rate = rv1103b_i2c_get_clk(priv, clk->id);
849 break;
850 case CLK_SPI0:
851 rate = rv1103b_spi_get_clk(priv, clk->id);
852 break;
853 case CLK_PWM0:
854 case CLK_PWM0_SRC:
855 case CLK_PWM1:
856 case CLK_PWM2:
857 rate = rv1103b_pwm_get_clk(priv, clk->id);
858 break;
859 case CLK_SARADC:
860 case CLK_TSADC_TSEN:
861 case CLK_TSADC:
862 rate = rv1103b_adc_get_clk(priv, clk->id);
863 break;
864 case SCLK_UART0:
865 case SCLK_UART1:
866 case SCLK_UART2:
867 rate = rv1103b_uart_get_rate(priv, clk->id);
868 break;
869 case DCLK_DECOM_SRC:
870 case DCLK_DECOM:
871 rate = rv1103b_decom_get_clk(priv);
872 break;
873 case TCLK_WDT_LPMCU:
874 case TCLK_WDT_HPMCU:
875 case TCLK_WDT_NS:
876 case TCLK_WDT_S:
877 rate = OSC_HZ;
878 break;
879 default:
880 return -ENOENT;
881 }
882
883 return rate;
884 };
885
rv1103b_clk_set_rate(struct clk * clk,ulong rate)886 static ulong rv1103b_clk_set_rate(struct clk *clk, ulong rate)
887 {
888 struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
889 ulong ret = 0;
890
891 if (!priv->gpll_hz) {
892 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
893 return -ENOENT;
894 }
895
896 switch (clk->id) {
897 case PLL_GPLL:
898 ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
899 GPLL, rate);
900 break;
901 case ACLK_PERI_SRC:
902 case LSCLK_PERI_SRC:
903 case PCLK_PERI_ROOT:
904 case PCLK_TOP_ROOT:
905 case LSCLK_PMU_ROOT:
906 case PCLK_PMU:
907 ret = rv1103b_peri_set_clk(priv, clk->id, rate);
908 break;
909 case ACLK_CRYPTO:
910 case HCLK_CRYPTO:
911 case HCLK_RK_RNG_NS:
912 case HCLK_RK_RNG_S:
913 case CLK_CORE_CRYPTO:
914 case CLK_PKA_CRYPTO:
915 ret = rv1103b_crypto_set_clk(priv, clk->id, rate);
916 break;
917 case CCLK_SDMMC1:
918 case HCLK_SDMMC1:
919 case CCLK_SDMMC0:
920 case HCLK_SDMMC0:
921 case CCLK_EMMC:
922 case HCLK_EMMC:
923 case SCLK_SFC_2X:
924 case HCLK_SFC:
925 ret = rv1103b_mmc_set_clk(priv, clk->id, rate);
926 break;
927 case CLK_I2C1:
928 case CLK_I2C2:
929 case CLK_I2C3:
930 case CLK_I2C4:
931 case CLK_I2C_PERI:
932 case CLK_I2C0:
933 case CLK_I2C_PMU:
934 ret = rv1103b_i2c_set_clk(priv, clk->id, rate);
935 break;
936 case CLK_SPI0:
937 ret = rv1103b_spi_set_clk(priv, clk->id, rate);
938 break;
939 case CLK_PWM0:
940 case CLK_PWM0_SRC:
941 case CLK_PWM1:
942 case CLK_PWM2:
943 ret = rv1103b_pwm_set_clk(priv, clk->id, rate);
944 break;
945 case CLK_SARADC:
946 case CLK_TSADC_TSEN:
947 case CLK_TSADC:
948 ret = rv1103b_adc_set_clk(priv, clk->id, rate);
949 break;
950 case SCLK_UART0:
951 case SCLK_UART1:
952 case SCLK_UART2:
953 ret = rv1103b_uart_set_rate(priv, clk->id, rate);
954 break;
955 case DCLK_DECOM_SRC:
956 case DCLK_DECOM:
957 rate = rv1103b_decom_set_clk(priv, rate);
958 break;
959 default:
960 return -ENOENT;
961 }
962
963 return ret;
964 };
965
rv1103b_clk_set_parent(struct clk * clk,struct clk * parent)966 static int rv1103b_clk_set_parent(struct clk *clk, struct clk *parent)
967 {
968 switch (clk->id) {
969 default:
970 return -ENOENT;
971 }
972
973 return 0;
974 }
975
976 static struct clk_ops rv1103b_clk_ops = {
977 .get_rate = rv1103b_clk_get_rate,
978 .set_rate = rv1103b_clk_set_rate,
979 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
980 .set_parent = rv1103b_clk_set_parent,
981 #endif
982 };
983
rv1103b_clk_init(struct rv1103b_clk_priv * priv)984 static void rv1103b_clk_init(struct rv1103b_clk_priv *priv)
985 {
986 int ret;
987 u32 div;
988
989 priv->sync_kernel = false;
990 priv->gpll_hz = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL],
991 priv->cru, GPLL);
992 if (priv->gpll_hz != GPLL_HZ) {
993 ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
994 GPLL, GPLL_HZ);
995 if (!ret)
996 priv->gpll_hz = GPLL_HZ;
997 }
998 if (!priv->armclk_enter_hz) {
999 div = (readl(&priv->cru->clksel_con[37]) &
1000 CLK_CORE_GPLL_DIV_MASK) >>
1001 CLK_CORE_GPLL_DIV_SHIFT;
1002 priv->armclk_enter_hz = DIV_TO_RATE(priv->gpll_hz, div);
1003 priv->armclk_init_hz = priv->armclk_enter_hz;
1004 }
1005 }
1006
rv1103b_clk_probe(struct udevice * dev)1007 static int rv1103b_clk_probe(struct udevice *dev)
1008 {
1009 struct rv1103b_clk_priv *priv = dev_get_priv(dev);
1010 int ret;
1011
1012 #ifdef CONFIG_SPL_BUILD
1013 /* fix lsclk_prei div */
1014 writel(BITS_WITH_WMASK(1, 0x1U, 9),
1015 RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(31));
1016 /* fix cpu div */
1017 writel(BITS_WITH_WMASK(1, 0x7U, 13),
1018 RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(37));
1019 /* fix gpll postdiv1 */
1020 writel(BITS_WITH_WMASK(1, 0x7U, 12),
1021 RV1103B_CRU_BASE + RV1103B_PLL_CON(24));
1022 #endif
1023
1024 rv1103b_clk_init(priv);
1025
1026 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1027 ret = clk_set_defaults(dev);
1028 if (ret)
1029 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1030 else
1031 priv->sync_kernel = true;
1032 return 0;
1033 }
1034
rv1103b_clk_ofdata_to_platdata(struct udevice * dev)1035 static int rv1103b_clk_ofdata_to_platdata(struct udevice *dev)
1036 {
1037 struct rv1103b_clk_priv *priv = dev_get_priv(dev);
1038
1039 priv->cru = dev_read_addr_ptr(dev);
1040
1041 return 0;
1042 }
1043
rv1103b_clk_bind(struct udevice * dev)1044 static int rv1103b_clk_bind(struct udevice *dev)
1045 {
1046 int ret;
1047 struct udevice *sys_child, *sf_child;
1048 struct sysreset_reg *priv;
1049 struct softreset_reg *sf_priv;
1050
1051 /* The reset driver does not have a device node, so bind it here */
1052 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1053 &sys_child);
1054 if (ret) {
1055 debug("Warning: No sysreset driver: ret=%d\n", ret);
1056 } else {
1057 priv = malloc(sizeof(struct sysreset_reg));
1058 priv->glb_srst_fst_value = offsetof(struct rv1103b_cru,
1059 glb_srst_fst);
1060 priv->glb_srst_snd_value = offsetof(struct rv1103b_cru,
1061 glb_srst_snd);
1062 sys_child->priv = priv;
1063 }
1064
1065 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1066 dev_ofnode(dev), &sf_child);
1067 if (ret) {
1068 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1069 } else {
1070 sf_priv = malloc(sizeof(struct softreset_reg));
1071 sf_priv->sf_reset_offset = offsetof(struct rv1103b_cru,
1072 peri_softrst_con[0]);
1073 sf_priv->sf_reset_num = CLK_NR_SRST;
1074 sf_child->priv = sf_priv;
1075 }
1076
1077 return 0;
1078 }
1079
1080 static const struct udevice_id rv1103b_clk_ids[] = {
1081 { .compatible = "rockchip,rv1103b-cru" },
1082 { }
1083 };
1084
1085 U_BOOT_DRIVER(rockchip_rv1103b_cru) = {
1086 .name = "rockchip_rv1103b_cru",
1087 .id = UCLASS_CLK,
1088 .of_match = rv1103b_clk_ids,
1089 .priv_auto_alloc_size = sizeof(struct rv1103b_clk_priv),
1090 .ofdata_to_platdata = rv1103b_clk_ofdata_to_platdata,
1091 .ops = &rv1103b_clk_ops,
1092 .bind = rv1103b_clk_bind,
1093 .probe = rv1103b_clk_probe,
1094 };
1095
1096 #ifndef CONFIG_SPL_BUILD
1097 /**
1098 * soc_clk_dump() - Print clock frequencies
1099 * Returns zero on success
1100 *
1101 * Implementation for the clk dump command.
1102 */
soc_clk_dump(void)1103 int soc_clk_dump(void)
1104 {
1105 struct udevice *cru_dev;
1106 struct rv1103b_clk_priv *priv;
1107 const struct rv1103b_clk_info *clk_dump;
1108 struct clk clk;
1109 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1110 unsigned long rate;
1111 int i, ret;
1112
1113 ret = uclass_get_device_by_driver(UCLASS_CLK,
1114 DM_GET_DRIVER(rockchip_rv1103b_cru),
1115 &cru_dev);
1116 if (ret) {
1117 printf("%s failed to get cru device\n", __func__);
1118 return ret;
1119 }
1120
1121 priv = dev_get_priv(cru_dev);
1122 ret = (readl(&priv->cru->core_clksel_con[0]) &
1123 CLK_CORE_SRC_SEL_MASK) >>
1124 CLK_CORE_SRC_SEL_SHIFT;
1125 if (ret == CLK_CORE_SRC_SEL_PVTPLL)
1126 printf("CLK: (arm clk use pvtpll, rate = 1200M)\n");
1127 else
1128 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1129 priv->sync_kernel ? "sync kernel" : "uboot",
1130 priv->armclk_enter_hz / 1000,
1131 priv->armclk_init_hz / 1000,
1132 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1133 priv->set_armclk_rate ? " KHz" : "N/A");
1134 for (i = 0; i < clk_count; i++) {
1135 clk_dump = &clks_dump[i];
1136 if (clk_dump->name) {
1137 clk.id = clk_dump->id;
1138 if (clk_dump->is_cru)
1139 ret = clk_request(cru_dev, &clk);
1140 if (ret < 0)
1141 return ret;
1142
1143 rate = clk_get_rate(&clk);
1144 clk_free(&clk);
1145 if (i == 0) {
1146 if (rate < 0)
1147 printf(" %s %s\n", clk_dump->name,
1148 "unknown");
1149 else
1150 printf(" %s %lu KHz\n", clk_dump->name,
1151 rate / 1000);
1152 } else {
1153 if (rate < 0)
1154 printf(" %s %s\n", clk_dump->name,
1155 "unknown");
1156 else
1157 printf(" %s %lu KHz\n", clk_dump->name,
1158 rate / 1000);
1159 }
1160 }
1161 }
1162
1163 return 0;
1164 }
1165 #endif
1166