1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2021 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_rv1106.h>
15 #include <asm/arch/grf_rv1106.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rv1106-cru.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
24
25 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
26 static struct rockchip_pll_rate_table rv1106_pll_rates[] = {
27 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
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(816000000, 1, 68, 2, 1, 1, 0),
33 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
34 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
35 { /* sentinel */ },
36 };
37
38 static struct rockchip_pll_clock rv1106_pll_clks[] = {
39 [APLL] = PLL(pll_rk3328, PLL_APLL, RV1106_PLL_CON(0),
40 RV1106_MODE_CON, 0, 10, 0, rv1106_pll_rates),
41 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1106_PLL_CON(16),
42 RV1106_SUBDDRMODE_CON, 0, 10, 0, NULL),
43 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1106_PLL_CON(8),
44 RV1106_MODE_CON, 2, 10, 0, rv1106_pll_rates),
45 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1106_PLL_CON(24),
46 RV1106_MODE_CON, 4, 10, 0, rv1106_pll_rates),
47 };
48 #endif
49
50 #ifndef CONFIG_SPL_BUILD
51 #define RV1106_CLK_DUMP(_id, _name, _iscru) \
52 { \
53 .id = _id, \
54 .name = _name, \
55 .is_cru = _iscru, \
56 }
57
58 static const struct rv1106_clk_info clks_dump[] = {
59 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
60 RV1106_CLK_DUMP(PLL_APLL, "apll", true),
61 RV1106_CLK_DUMP(PLL_DPLL, "dpll", true),
62 RV1106_CLK_DUMP(PLL_GPLL, "gpll", true),
63 RV1106_CLK_DUMP(PLL_CPLL, "cpll", true),
64 RV1106_CLK_DUMP(ACLK_PERI_ROOT, "aclk_peri_root", true),
65 RV1106_CLK_DUMP(HCLK_PERI_ROOT, "hclK_peri_root", true),
66 RV1106_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true),
67 RV1106_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
68 RV1106_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
69 RV1106_CLK_DUMP(PCLK_PMU_ROOT, "pclk_pmu_root", true),
70 RV1106_CLK_DUMP(HCLK_PMU_ROOT, "hclk_pmu_root", true),
71 #endif
72 };
73 #endif
74
75 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
rv1106_peri_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)76 static ulong rv1106_peri_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
77 {
78 struct rv1106_cru *cru = priv->cru;
79 u32 con, sel, rate;
80
81 switch (clk_id) {
82 case ACLK_PERI_ROOT:
83 con = readl(&cru->peri_clksel_con[1]);
84 sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
85 if (sel == ACLK_PERI_SEL_400M)
86 rate = 400 * MHz;
87 else if (sel == ACLK_PERI_SEL_200M)
88 rate = 200 * MHz;
89 else if (sel == ACLK_PERI_SEL_100M)
90 rate = 100 * MHz;
91 else
92 rate = OSC_HZ;
93 break;
94 case HCLK_PERI_ROOT:
95 con = readl(&cru->peri_clksel_con[1]);
96 sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT;
97 if (sel == HCLK_PERI_SEL_200M)
98 rate = 200 * MHz;
99 else if (sel == HCLK_PERI_SEL_100M)
100 rate = 100 * MHz;
101 else if (sel == HCLK_PERI_SEL_50M)
102 rate = 50 * MHz;
103 else
104 rate = OSC_HZ;
105 break;
106 case PCLK_PERI_ROOT:
107 con = readl(&cru->peri_clksel_con[1]);
108 sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
109 if (sel == PCLK_PERI_SEL_100M)
110 rate = 100 * MHz;
111 else if (sel == PCLK_PERI_SEL_50M)
112 rate = 50 * MHz;
113 else
114 rate = OSC_HZ;
115 break;
116 case ACLK_BUS_ROOT:
117 con = readl(&cru->peri_clksel_con[9]);
118 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
119 if (sel == ACLK_BUS_SEL_300M)
120 rate = 300 * MHz;
121 else if (sel == ACLK_BUS_SEL_200M)
122 rate = 200 * MHz;
123 else if (sel == ACLK_BUS_SEL_100M)
124 rate = 100 * MHz;
125 else
126 rate = OSC_HZ;
127 break;
128 case PCLK_TOP_ROOT:
129 con = readl(&cru->clksel_con[24]);
130 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
131 if (sel == PCLK_TOP_SEL_100M)
132 rate = 100 * MHz;
133 else if (sel == PCLK_TOP_SEL_50M)
134 rate = 50 * MHz;
135 else
136 rate = OSC_HZ;
137 break;
138 case PCLK_PMU_ROOT:
139 con = readl(&cru->pmu_clksel_con[0]);
140 sel = (con & PCLK_PMU_SEL_MASK) >> PCLK_PMU_SEL_SHIFT;
141 if (sel == PCLK_PMU_SEL_100M)
142 rate = 100 * MHz;
143 else
144 rate = OSC_HZ;
145 break;
146 case HCLK_PMU_ROOT:
147 con = readl(&cru->pmu_clksel_con[0]);
148 sel = (con & HCLK_PMU_SEL_MASK) >> HCLK_PMU_SEL_SHIFT;
149 if (sel == HCLK_PMU_SEL_200M)
150 rate = 200 * MHz;
151 else if (sel == HCLK_PMU_SEL_100M)
152 rate = 100 * MHz;
153 else
154 rate = OSC_HZ;
155 break;
156 default:
157 return -ENOENT;
158 }
159
160 return rate;
161 }
162
rv1106_peri_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)163 static ulong rv1106_peri_set_clk(struct rv1106_clk_priv *priv,
164 ulong clk_id, ulong rate)
165 {
166 struct rv1106_cru *cru = priv->cru;
167 int src_clk;
168
169 switch (clk_id) {
170 case ACLK_PERI_ROOT:
171 if (rate >= 396 * MHz)
172 src_clk = ACLK_PERI_SEL_400M;
173 else if (rate >= 198 * MHz)
174 src_clk = ACLK_PERI_SEL_200M;
175 else if (rate >= 99 * MHz)
176 src_clk = ACLK_PERI_SEL_100M;
177 else
178 src_clk = ACLK_PERI_SEL_24M;
179 rk_clrsetreg(&cru->peri_clksel_con[1],
180 ACLK_PERI_SEL_MASK,
181 src_clk << ACLK_PERI_SEL_SHIFT);
182 break;
183 case HCLK_PERI_ROOT:
184 if (rate >= 198 * MHz)
185 src_clk = HCLK_PERI_SEL_200M;
186 else if (rate >= 99 * MHz)
187 src_clk = HCLK_PERI_SEL_100M;
188 else if (rate >= 48 * MHz)
189 src_clk = HCLK_PERI_SEL_50M;
190 else
191 src_clk = HCLK_PERI_SEL_24M;
192 rk_clrsetreg(&cru->peri_clksel_con[1],
193 HCLK_PERI_SEL_MASK,
194 src_clk << HCLK_PERI_SEL_SHIFT);
195 break;
196 case PCLK_PERI_ROOT:
197 if (rate >= 99 * MHz)
198 src_clk = PCLK_PERI_SEL_100M;
199 else if (rate >= 48 * MHz)
200 src_clk = PCLK_PERI_SEL_50M;
201 else
202 src_clk = PCLK_PERI_SEL_24M;
203 rk_clrsetreg(&cru->peri_clksel_con[1],
204 PCLK_PERI_SEL_MASK,
205 src_clk << PCLK_PERI_SEL_SHIFT);
206 break;
207 case ACLK_BUS_ROOT:
208 if (rate >= 297 * MHz)
209 src_clk = ACLK_BUS_SEL_300M;
210 else if (rate >= 198 * MHz)
211 src_clk = ACLK_BUS_SEL_200M;
212 else if (rate >= 99 * MHz)
213 src_clk = ACLK_BUS_SEL_100M;
214 else
215 src_clk = ACLK_BUS_SEL_24M;
216 rk_clrsetreg(&cru->peri_clksel_con[9],
217 ACLK_BUS_SEL_MASK,
218 src_clk << ACLK_BUS_SEL_SHIFT);
219 break;
220 case PCLK_TOP_ROOT:
221 if (rate >= 99 * MHz)
222 src_clk = PCLK_TOP_SEL_100M;
223 else if (rate >= 48 * MHz)
224 src_clk = PCLK_TOP_SEL_50M;
225 else
226 src_clk = PCLK_TOP_SEL_24M;
227 rk_clrsetreg(&cru->clksel_con[24],
228 PCLK_TOP_SEL_MASK,
229 src_clk << PCLK_TOP_SEL_SHIFT);
230 break;
231 case PCLK_PMU_ROOT:
232 if (rate >= 99 * MHz)
233 src_clk = PCLK_PMU_SEL_100M;
234 else
235 src_clk = PCLK_PMU_SEL_24M;
236 rk_clrsetreg(&cru->pmu_clksel_con[0],
237 PCLK_PMU_SEL_MASK,
238 src_clk << PCLK_PMU_SEL_SHIFT);
239 break;
240 case HCLK_PMU_ROOT:
241 if (rate >= 198 * MHz)
242 src_clk = HCLK_PMU_SEL_200M;
243 else if (rate >= 99 * MHz)
244 src_clk = HCLK_PMU_SEL_100M;
245 else
246 src_clk = HCLK_PMU_SEL_24M;
247 rk_clrsetreg(&cru->pmu_clksel_con[0],
248 HCLK_PMU_SEL_MASK,
249 src_clk << HCLK_PMU_SEL_SHIFT);
250 break;
251 default:
252 printf("do not support this permid freq\n");
253 return -EINVAL;
254 }
255
256 return rv1106_peri_get_clk(priv, clk_id);
257 }
258
rv1106_i2c_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)259 static ulong rv1106_i2c_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
260 {
261 struct rv1106_cru *cru = priv->cru;
262 u32 sel, con;
263 ulong rate;
264
265 switch (clk_id) {
266 case CLK_I2C1:
267 con = readl(&cru->pmu_clksel_con[0]);
268 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
269 if (sel == CLK_I2C1_SEL_200M)
270 rate = 200 * MHz;
271 else if (sel == CLK_I2C1_SEL_100M)
272 rate = 100 * MHz;
273 else if (sel == CLK_I2C1_SEL_24M)
274 rate = OSC_HZ;
275 else
276 rate = 32768;
277 return rate;
278 case CLK_I2C0:
279 con = readl(&cru->peri_clksel_con[1]);
280 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
281 break;
282 case CLK_I2C2:
283 con = readl(&cru->peri_clksel_con[1]);
284 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
285 break;
286 case CLK_I2C3:
287 con = readl(&cru->peri_clksel_con[1]);
288 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
289 break;
290 case CLK_I2C4:
291 con = readl(&cru->peri_clksel_con[2]);
292 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
293 break;
294 default:
295 return -ENOENT;
296 }
297
298 if (sel == CLK_I2C0_SEL_200M)
299 rate = 200 * MHz;
300 else if (sel == CLK_I2C0_SEL_100M)
301 rate = 100 * MHz;
302 else if (sel == CLK_I2C0_SEL_50M)
303 rate = 50 * MHz;
304 else
305 rate = OSC_HZ;
306
307 return rate;
308 }
309 #endif
310
rv1106_crypto_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)311 static ulong rv1106_crypto_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
312 {
313 struct rv1106_cru *cru = priv->cru;
314 u32 sel, con;
315
316 switch (clk_id) {
317 case CLK_CORE_CRYPTO:
318 con = readl(&cru->peri_clksel_con[6]);
319 sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
320 CLK_CORE_CRYPTO_SEL_SHIFT;
321 break;
322 case CLK_PKA_CRYPTO:
323 con = readl(&cru->peri_clksel_con[6]);
324 sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
325 CLK_PKA_CRYPTO_SEL_SHIFT;
326 break;
327 default:
328 return -ENOENT;
329 }
330 switch (sel) {
331 case CLK_CRYPTO_SEL_300M:
332 return 300 * MHz;
333 case CLK_CRYPTO_SEL_200M:
334 return 200 * MHz;
335 case CLK_CRYPTO_SEL_100M:
336 return 100 * MHz;
337 case CLK_CRYPTO_SEL_24M:
338 return OSC_HZ;
339 default:
340 return -ENOENT;
341 }
342 }
343
rv1106_crypto_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)344 static ulong rv1106_crypto_set_clk(struct rv1106_clk_priv *priv,
345 ulong clk_id, ulong rate)
346 {
347 struct rv1106_cru *cru = priv->cru;
348 u32 sel;
349
350 if (rate >= 297 * MHz)
351 sel = CLK_CRYPTO_SEL_300M;
352 else if (rate >= 198 * MHz)
353 sel = CLK_CRYPTO_SEL_200M;
354 else if (rate >= 99 * MHz)
355 sel = CLK_CRYPTO_SEL_100M;
356 else
357 sel = CLK_CRYPTO_SEL_24M;
358
359 switch (clk_id) {
360 case CLK_CORE_CRYPTO:
361 rk_clrsetreg(&cru->peri_clksel_con[6],
362 CLK_CORE_CRYPTO_SEL_MASK,
363 sel << CLK_CORE_CRYPTO_SEL_SHIFT);
364 break;
365 case CLK_PKA_CRYPTO:
366 rk_clrsetreg(&cru->peri_clksel_con[6],
367 CLK_PKA_CRYPTO_SEL_MASK,
368 sel << CLK_PKA_CRYPTO_SEL_SHIFT);
369 break;
370 default:
371 return -ENOENT;
372 }
373 return rv1106_crypto_get_clk(priv, clk_id);
374 }
375
rv1106_mmc_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)376 static ulong rv1106_mmc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
377 {
378 struct rv1106_cru *cru = priv->cru;
379 u32 div, sel, con, prate;
380
381 switch (clk_id) {
382 case CCLK_SRC_SDMMC:
383 case HCLK_SDMMC:
384 con = readl(&cru->vi_clksel_con[1]);
385 sel = (con & CLK_SDMMC_SEL_MASK) >>
386 CLK_SDMMC_SEL_SHIFT;
387 div = (con & CLK_SDMMC_DIV_MASK) >>
388 CLK_SDMMC_DIV_SHIFT;
389 if (sel == CLK_MMC_SEL_400M)
390 prate = 400 * MHz;
391 else
392 prate = OSC_HZ;
393 return DIV_TO_RATE(prate, div);
394 case CCLK_SRC_EMMC:
395 case HCLK_EMMC:
396 con = readl(&cru->peri_clksel_con[7]);
397 sel = (con & CLK_EMMC_SEL_MASK) >>
398 CLK_EMMC_SEL_SHIFT;
399 div = (con & CLK_EMMC_DIV_MASK) >>
400 CLK_EMMC_DIV_SHIFT;
401 if (sel)
402 prate = OSC_HZ;
403 else
404 prate = 400 * MHz;
405 return DIV_TO_RATE(prate, div);
406 case SCLK_SFC:
407 case HCLK_SFC:
408 con = readl(&cru->peri_clksel_con[7]);
409 sel = (con & CLK_SFC_SEL_MASK) >>
410 CLK_SFC_SEL_SHIFT;
411 div = (con & CLK_SFC_DIV_MASK) >>
412 CLK_SFC_DIV_SHIFT;
413 if (sel == CLK_SFC_SEL_500M)
414 prate = 500 * MHz;
415 else if (sel == CLK_SFC_SEL_300M)
416 prate = 300 * MHz;
417 else if (sel == CLK_SFC_SEL_200M)
418 prate = 200 * MHz;
419 else
420 prate = OSC_HZ;
421 return DIV_TO_RATE(prate, div);
422 default:
423 return -ENOENT;
424 }
425 }
426
rv1106_mmc_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)427 static ulong rv1106_mmc_set_clk(struct rv1106_clk_priv *priv,
428 ulong clk_id, ulong rate)
429 {
430 struct rv1106_cru *cru = priv->cru;
431 u32 sel, src_clk_div;
432 ulong prate = 0;
433
434 if ((OSC_HZ % rate) == 0) {
435 sel = CLK_MMC_SEL_24M;
436 prate = OSC_HZ;
437 } else {
438 sel = CLK_MMC_SEL_400M;
439 prate = 400 * MHz;
440 }
441 src_clk_div = DIV_ROUND_UP(prate, rate);
442
443 switch (clk_id) {
444 case CCLK_SRC_SDMMC:
445 case HCLK_SDMMC:
446 if ((OSC_HZ % rate) == 0) {
447 sel = CLK_MMC_SEL_24M;
448 prate = OSC_HZ;
449 } else {
450 sel = CLK_MMC_SEL_400M;
451 prate = 400 * MHz;
452 }
453 src_clk_div = DIV_ROUND_UP(prate, rate);
454 rk_clrsetreg(&cru->vi_clksel_con[1],
455 CLK_SDMMC_SEL_MASK |
456 CLK_SDMMC_DIV_MASK,
457 (sel << CLK_SDMMC_SEL_SHIFT) |
458 ((src_clk_div - 1) <<
459 CLK_SDMMC_DIV_SHIFT));
460 break;
461 case CCLK_SRC_EMMC:
462 case HCLK_EMMC:
463 if ((OSC_HZ % rate) == 0) {
464 sel = CLK_MMC_SEL_24M;
465 prate = OSC_HZ;
466 } else {
467 sel = CLK_MMC_SEL_400M;
468 prate = 400 * MHz;
469 }
470 src_clk_div = DIV_ROUND_UP(prate, rate);
471 rk_clrsetreg(&cru->peri_clksel_con[7],
472 CLK_EMMC_SEL_MASK |
473 CLK_EMMC_DIV_MASK,
474 (sel << CLK_EMMC_SEL_SHIFT) |
475 ((src_clk_div - 1) <<
476 CLK_EMMC_DIV_SHIFT));
477 break;
478 case SCLK_SFC:
479 case HCLK_SFC:
480 if ((OSC_HZ % rate) == 0) {
481 sel = CLK_SFC_SEL_24M;
482 prate = OSC_HZ;
483 } else if ((500 * MHz % rate) == 0) {
484 sel = CLK_SFC_SEL_500M;
485 prate = 500 * MHz;
486 } else if ((300 * MHz % rate) == 0) {
487 sel = CLK_SFC_SEL_300M;
488 prate = 300 * MHz;
489 } else {
490 sel = CLK_SFC_SEL_200M;
491 prate = 200 * MHz;
492 }
493 src_clk_div = DIV_ROUND_UP(prate, rate);
494 rk_clrsetreg(&cru->peri_clksel_con[7],
495 CLK_SFC_SEL_MASK |
496 CLK_SFC_DIV_MASK,
497 (sel << CLK_SFC_SEL_SHIFT) |
498 ((src_clk_div - 1) <<
499 CLK_SFC_DIV_SHIFT));
500 break;
501 default:
502 return -ENOENT;
503 }
504 return rv1106_mmc_get_clk(priv, clk_id);
505 }
506
507 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
rv1106_i2c_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)508 static ulong rv1106_i2c_set_clk(struct rv1106_clk_priv *priv, ulong clk_id,
509 ulong rate)
510 {
511 struct rv1106_cru *cru = priv->cru;
512 int src_clk;
513
514 if (rate >= 198 * MHz)
515 src_clk = CLK_I2C0_SEL_200M;
516 else if (rate >= 99 * MHz)
517 src_clk = CLK_I2C0_SEL_100M;
518 else if (rate >= 48 * MHz)
519 src_clk = CLK_I2C0_SEL_50M;
520 else
521 src_clk = CLK_I2C0_SEL_24M;
522
523 switch (clk_id) {
524 case CLK_I2C1:
525 if (rate >= 198 * MHz)
526 src_clk = CLK_I2C1_SEL_200M;
527 else if (rate >= 99 * MHz)
528 src_clk = CLK_I2C1_SEL_100M;
529 else if (rate >= 24 * MHz)
530 src_clk = CLK_I2C1_SEL_24M;
531 else
532 src_clk = CLK_I2C1_SEL_32K;
533 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C1_SEL_MASK,
534 src_clk << CLK_I2C1_SEL_SHIFT);
535 return rv1106_i2c_get_clk(priv, clk_id);
536 case CLK_I2C0:
537 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C0_SEL_MASK,
538 src_clk << CLK_I2C0_SEL_SHIFT);
539 break;
540 case CLK_I2C2:
541 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C2_SEL_MASK,
542 src_clk << CLK_I2C2_SEL_SHIFT);
543 break;
544 case CLK_I2C3:
545 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C3_SEL_MASK,
546 src_clk << CLK_I2C3_SEL_SHIFT);
547 break;
548 case CLK_I2C4:
549 rk_clrsetreg(&cru->peri_clksel_con[2], CLK_I2C4_SEL_MASK,
550 src_clk << CLK_I2C4_SEL_SHIFT);
551 break;
552 default:
553 return -ENOENT;
554 }
555
556 return rv1106_i2c_get_clk(priv, clk_id);
557 }
558 #endif
559
rv1106_spi_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)560 static ulong rv1106_spi_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
561 {
562 struct rv1106_cru *cru = priv->cru;
563 u32 sel, con, rate;
564
565 switch (clk_id) {
566 case CLK_SPI0:
567 con = readl(&cru->vepu_clksel_con[0]);
568 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
569 break;
570 case CLK_SPI1:
571 con = readl(&cru->peri_clksel_con[6]);
572 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
573 break;
574 default:
575 return -ENOENT;
576 }
577 if (sel == CLK_SPI0_SEL_200M)
578 rate = 200 * MHz;
579 else if (sel == CLK_SPI0_SEL_100M)
580 rate = 100 * MHz;
581 else if (sel == CLK_SPI0_SEL_50M)
582 rate = 50 * MHz;
583 else
584 rate = OSC_HZ;
585
586 return rate;
587 }
588
rv1106_spi_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)589 static ulong rv1106_spi_set_clk(struct rv1106_clk_priv *priv,
590 ulong clk_id, ulong rate)
591 {
592 struct rv1106_cru *cru = priv->cru;
593 int src_clk;
594
595 if (rate >= 198 * MHz)
596 src_clk = CLK_SPI0_SEL_200M;
597 else if (rate >= 99 * MHz)
598 src_clk = CLK_SPI0_SEL_100M;
599 else if (rate >= 48 * MHz)
600 src_clk = CLK_SPI0_SEL_50M;
601 else
602 src_clk = CLK_SPI0_SEL_24M;
603
604 switch (clk_id) {
605 case CLK_SPI0:
606 rk_clrsetreg(&cru->vepu_clksel_con[0], CLK_SPI0_SEL_MASK,
607 src_clk << CLK_SPI0_SEL_SHIFT);
608 break;
609 case CLK_SPI1:
610 rk_clrsetreg(&cru->peri_clksel_con[6], CLK_SPI1_SEL_MASK,
611 src_clk << CLK_SPI1_SEL_SHIFT);
612 break;
613 default:
614 return -ENOENT;
615 }
616
617 return rv1106_spi_get_clk(priv, clk_id);
618 }
619
620 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
rv1106_pwm_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)621 static ulong rv1106_pwm_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
622 {
623 struct rv1106_cru *cru = priv->cru;
624 u32 sel, con;
625
626 switch (clk_id) {
627 case CLK_PWM0_PERI:
628 con = readl(&cru->peri_clksel_con[11]);
629 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
630 break;
631 case CLK_PWM1_PERI:
632 con = readl(&cru->peri_clksel_con[6]);
633 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
634 break;
635 case CLK_PWM2_PERI:
636 con = readl(&cru->peri_clksel_con[6]);
637 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
638 break;
639 default:
640 return -ENOENT;
641 }
642
643 switch (sel) {
644 case CLK_PWM_SEL_100M:
645 return 100 * MHz;
646 case CLK_PWM_SEL_50M:
647 return 100 * MHz;
648 case CLK_PWM_SEL_24M:
649 return OSC_HZ;
650 default:
651 return -ENOENT;
652 }
653 }
654
rv1106_pwm_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)655 static ulong rv1106_pwm_set_clk(struct rv1106_clk_priv *priv,
656 ulong clk_id, ulong rate)
657 {
658 struct rv1106_cru *cru = priv->cru;
659 int src_clk;
660
661 if (rate >= 99 * MHz)
662 src_clk = CLK_PWM_SEL_100M;
663 else if (rate >= 48 * MHz)
664 src_clk = CLK_PWM_SEL_50M;
665 else
666 src_clk = CLK_PWM_SEL_24M;
667
668 switch (clk_id) {
669 case CLK_PWM0_PERI:
670 rk_clrsetreg(&cru->peri_clksel_con[11],
671 CLK_PWM0_SEL_MASK,
672 src_clk << CLK_PWM0_SEL_SHIFT);
673 break;
674 case CLK_PWM1_PERI:
675 rk_clrsetreg(&cru->peri_clksel_con[6],
676 CLK_PWM1_SEL_MASK,
677 src_clk << CLK_PWM1_SEL_SHIFT);
678 break;
679 case CLK_PWM2_PERI:
680 rk_clrsetreg(&cru->peri_clksel_con[6],
681 CLK_PWM2_SEL_MASK,
682 src_clk << CLK_PWM2_SEL_SHIFT);
683 break;
684 default:
685 return -ENOENT;
686 }
687
688 return rv1106_pwm_get_clk(priv, clk_id);
689 }
690 #endif
691
rv1106_adc_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)692 static ulong rv1106_adc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
693 {
694 struct rv1106_cru *cru = priv->cru;
695 u32 div, con;
696
697 switch (clk_id) {
698 case CLK_SARADC:
699 con = readl(&cru->peri_clksel_con[6]);
700 div = (con & CLK_SARADC_DIV_MASK) >>
701 CLK_SARADC_DIV_SHIFT;
702 return DIV_TO_RATE(OSC_HZ, div);
703 case CLK_TSADC_TSEN:
704 con = readl(&cru->vo_clksel_con[3]);
705 div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
706 CLK_TSADC_TSEN_DIV_SHIFT;
707 return DIV_TO_RATE(OSC_HZ, div);
708 case CLK_TSADC:
709 con = readl(&cru->vo_clksel_con[3]);
710 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
711 return DIV_TO_RATE(OSC_HZ, div);
712 default:
713 return -ENOENT;
714 }
715 }
716
rv1106_adc_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)717 static ulong rv1106_adc_set_clk(struct rv1106_clk_priv *priv,
718 ulong clk_id, ulong rate)
719 {
720 struct rv1106_cru *cru = priv->cru;
721 int src_clk_div;
722
723 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
724
725 switch (clk_id) {
726 case CLK_SARADC:
727 assert(src_clk_div - 1 <= 7);
728 rk_clrsetreg(&cru->peri_clksel_con[6],
729 CLK_SARADC_DIV_MASK,
730 (src_clk_div - 1) <<
731 CLK_SARADC_DIV_SHIFT);
732 break;
733 case CLK_TSADC_TSEN:
734 assert(src_clk_div - 1 <= 128);
735 rk_clrsetreg(&cru->vo_clksel_con[3],
736 CLK_TSADC_TSEN_DIV_MASK,
737 (src_clk_div - 1) <<
738 CLK_TSADC_TSEN_DIV_SHIFT);
739 break;
740 case CLK_TSADC:
741 assert(src_clk_div - 1 <= 128);
742 rk_clrsetreg(&cru->vo_clksel_con[3],
743 CLK_TSADC_DIV_MASK,
744 (src_clk_div - 1) <<
745 CLK_TSADC_DIV_SHIFT);
746 break;
747 default:
748 return -ENOENT;
749 }
750 return rv1106_adc_get_clk(priv, clk_id);
751 }
752
753 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
754 /*
755 *
756 * rational_best_approximation(31415, 10000,
757 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
758 *
759 * you may look at given_numerator as a fixed point number,
760 * with the fractional part size described in given_denominator.
761 *
762 * for theoretical background, see:
763 * http://en.wikipedia.org/wiki/Continued_fraction
764 */
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)765 static void rational_best_approximation(unsigned long given_numerator,
766 unsigned long given_denominator,
767 unsigned long max_numerator,
768 unsigned long max_denominator,
769 unsigned long *best_numerator,
770 unsigned long *best_denominator)
771 {
772 unsigned long n, d, n0, d0, n1, d1;
773
774 n = given_numerator;
775 d = given_denominator;
776 n0 = 0;
777 d1 = 0;
778 n1 = 1;
779 d0 = 1;
780 for (;;) {
781 unsigned long t, a;
782
783 if (n1 > max_numerator || d1 > max_denominator) {
784 n1 = n0;
785 d1 = d0;
786 break;
787 }
788 if (d == 0)
789 break;
790 t = d;
791 a = n / d;
792 d = n % d;
793 n = t;
794 t = n0 + a * n1;
795 n0 = n1;
796 n1 = t;
797 t = d0 + a * d1;
798 d0 = d1;
799 d1 = t;
800 }
801 *best_numerator = n1;
802 *best_denominator = d1;
803 }
804
rv1106_uart_get_rate(struct rv1106_clk_priv * priv,ulong clk_id)805 static ulong rv1106_uart_get_rate(struct rv1106_clk_priv *priv, ulong clk_id)
806 {
807 struct rv1106_cru *cru = priv->cru;
808 u32 reg, con, fracdiv, div, src, p_src, p_rate;
809 unsigned long m, n;
810
811 switch (clk_id) {
812 case SCLK_UART0:
813 reg = 5;
814 break;
815 case SCLK_UART1:
816 reg = 7;
817 break;
818 case SCLK_UART2:
819 reg = 9;
820 break;
821 case SCLK_UART3:
822 reg = 11;
823 break;
824 case SCLK_UART4:
825 reg = 13;
826 break;
827 case SCLK_UART5:
828 reg = 15;
829 break;
830 default:
831 return -ENOENT;
832 }
833 con = readl(&cru->clksel_con[reg + 2]);
834 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
835 con = readl(&cru->clksel_con[reg]);
836 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
837 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
838 if (p_src == CLK_UART_SRC_SEL_GPLL)
839 p_rate = priv->gpll_hz;
840 else if (p_src == CLK_UART_SRC_SEL_CPLL)
841 p_rate = priv->cpll_hz;
842 else
843 p_rate = 480000000;
844 if (src == CLK_UART_SEL_SRC) {
845 return DIV_TO_RATE(p_rate, div);
846 } else if (src == CLK_UART_SEL_FRAC) {
847 fracdiv = readl(&cru->clksel_con[reg + 1]);
848 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
849 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
850 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
851 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
852 return DIV_TO_RATE(p_rate, div) * n / m;
853 } else {
854 return OSC_HZ;
855 }
856 }
857
rv1106_uart_set_rate(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)858 static ulong rv1106_uart_set_rate(struct rv1106_clk_priv *priv,
859 ulong clk_id, ulong rate)
860 {
861 struct rv1106_cru *cru = priv->cru;
862 u32 reg, clk_src, uart_src, div;
863 unsigned long m = 0, n = 0, val;
864
865 if (priv->gpll_hz % rate == 0) {
866 clk_src = CLK_UART_SRC_SEL_GPLL;
867 uart_src = CLK_UART_SEL_SRC;
868 div = DIV_ROUND_UP(priv->gpll_hz, rate);
869 } else if (priv->cpll_hz % rate == 0) {
870 clk_src = CLK_UART_SRC_SEL_CPLL;
871 uart_src = CLK_UART_SEL_SRC;
872 div = DIV_ROUND_UP(priv->gpll_hz, rate);
873 } else if (rate == OSC_HZ) {
874 clk_src = CLK_UART_SRC_SEL_GPLL;
875 uart_src = CLK_UART_SEL_XIN24M;
876 div = 2;
877 } else {
878 clk_src = CLK_UART_SRC_SEL_GPLL;
879 uart_src = CLK_UART_SEL_FRAC;
880 div = 2;
881 rational_best_approximation(rate, priv->gpll_hz / div,
882 GENMASK(16 - 1, 0),
883 GENMASK(16 - 1, 0),
884 &m, &n);
885 }
886
887 switch (clk_id) {
888 case SCLK_UART0:
889 reg = 5;
890 break;
891 case SCLK_UART1:
892 reg = 7;
893 break;
894 case SCLK_UART2:
895 reg = 9;
896 break;
897 case SCLK_UART3:
898 reg = 11;
899 break;
900 case SCLK_UART4:
901 reg = 13;
902 break;
903 case SCLK_UART5:
904 reg = 15;
905 break;
906 default:
907 return -ENOENT;
908 }
909 rk_clrsetreg(&cru->clksel_con[reg],
910 CLK_UART_SRC_SEL_MASK |
911 CLK_UART_SRC_DIV_MASK,
912 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
913 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
914 rk_clrsetreg(&cru->clksel_con[reg + 2],
915 CLK_UART_SEL_MASK,
916 uart_src << CLK_UART_SEL_SHIFT);
917 if (m && n) {
918 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
919 writel(val, &cru->clksel_con[reg + 1]);
920 }
921
922 return rv1106_uart_get_rate(priv, clk_id);
923 }
924
rv1106_vop_get_clk(struct rv1106_clk_priv * priv,ulong clk_id)925 static ulong rv1106_vop_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
926 {
927 struct rv1106_cru *cru = priv->cru;
928 u32 div, sel, con;
929
930 switch (clk_id) {
931 case ACLK_VOP_ROOT:
932 case ACLK_VOP:
933 con = readl(&cru->vo_clksel_con[1]);
934 sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT;
935 if (sel == ACLK_VOP_SEL_300M)
936 return 300 * MHz;
937 else if (sel == ACLK_VOP_SEL_200M)
938 return 200 * MHz;
939 else if (sel == ACLK_VOP_SEL_100M)
940 return 100 * MHz;
941 else
942 return OSC_HZ;
943 case DCLK_VOP_SRC:
944 case DCLK_VOP:
945 con = readl(&cru->clksel_con[23]);
946 sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
947 div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
948 if (sel == DCLK_VOP_SEL_GPLL)
949 return DIV_TO_RATE(priv->gpll_hz, div);
950 else
951 return DIV_TO_RATE(priv->cpll_hz, div);
952 default:
953 return -ENOENT;
954 }
955 }
956
rv1106_vop_set_clk(struct rv1106_clk_priv * priv,ulong clk_id,ulong rate)957 static ulong rv1106_vop_set_clk(struct rv1106_clk_priv *priv,
958 ulong clk_id, ulong rate)
959 {
960 struct rv1106_cru *cru = priv->cru;
961 int div, sel;
962
963 switch (clk_id) {
964 case ACLK_VOP_ROOT:
965 case ACLK_VOP:
966 if (rate >= 297 * MHz)
967 sel = ACLK_VOP_SEL_300M;
968 else if (rate >= 198 * MHz)
969 sel = ACLK_VOP_SEL_200M;
970 else if (rate >= 99 * MHz)
971 sel = ACLK_VOP_SEL_100M;
972 else
973 sel = ACLK_VOP_SEL_24M;
974 rk_clrsetreg(&cru->vo_clksel_con[1],
975 ACLK_VOP_SEL_MASK,
976 sel << ACLK_VOP_SEL_SHIFT);
977 break;
978 case DCLK_VOP_SRC:
979 case DCLK_VOP:
980 if ((priv->cpll_hz % rate) == 0) {
981 sel = DCLK_VOP_SEL_CPLL;
982 div = DIV_ROUND_UP(priv->cpll_hz, rate);
983 } else {
984 sel = DCLK_VOP_SEL_GPLL;
985 div = DIV_ROUND_UP(priv->gpll_hz, rate);
986 }
987 rk_clrsetreg(&cru->clksel_con[23],
988 DCLK_VOP_SEL_MASK |
989 DCLK_VOP_DIV_MASK,
990 sel << DCLK_VOP_SEL_SHIFT |
991 (div - 1) << DCLK_VOP_DIV_SHIFT);
992 break;
993 default:
994 return -ENOENT;
995 }
996
997 return rv1106_vop_get_clk(priv, clk_id);
998 }
999
rv1106_decom_get_clk(struct rv1106_clk_priv * priv)1000 static ulong rv1106_decom_get_clk(struct rv1106_clk_priv *priv)
1001 {
1002 struct rv1106_cru *cru = priv->cru;
1003 u32 sel, con, prate;
1004
1005 con = readl(&cru->peri_clksel_con[7]);
1006 sel = (con & DCLK_DECOM_SEL_MASK) >>
1007 DCLK_DECOM_SEL_SHIFT;
1008 if (sel == DCLK_DECOM_SEL_400M)
1009 prate = 400 * MHz;
1010 else if (sel == DCLK_DECOM_SEL_200M)
1011 prate = 200 * MHz;
1012 else if (sel == DCLK_DECOM_SEL_100M)
1013 prate = 100 * MHz;
1014 else
1015 prate = OSC_HZ;
1016 return prate;
1017 }
1018
rv1106_decom_set_clk(struct rv1106_clk_priv * priv,ulong rate)1019 static ulong rv1106_decom_set_clk(struct rv1106_clk_priv *priv, ulong rate)
1020 {
1021 struct rv1106_cru *cru = priv->cru;
1022 u32 sel;
1023
1024 if (rate >= 396 * MHz)
1025 sel = DCLK_DECOM_SEL_400M;
1026 else if (rate >= 198 * MHz)
1027 sel = DCLK_DECOM_SEL_200M;
1028 else if (rate >= 99 * MHz)
1029 sel = DCLK_DECOM_SEL_100M;
1030 else
1031 sel = DCLK_DECOM_SEL_24M;
1032 rk_clrsetreg(&cru->peri_clksel_con[7], DCLK_DECOM_SEL_MASK,
1033 (sel << DCLK_DECOM_SEL_SHIFT));
1034
1035 return rv1106_decom_get_clk(priv);
1036 }
1037 #endif
1038
rv1106_clk_get_rate(struct clk * clk)1039 static ulong rv1106_clk_get_rate(struct clk *clk)
1040 {
1041 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1042 ulong rate = 0;
1043
1044 if (!priv->gpll_hz) {
1045 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1046 return -ENOENT;
1047 }
1048
1049 switch (clk->id) {
1050 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1051 case PLL_APLL:
1052 rate = rockchip_pll_get_rate(&rv1106_pll_clks[APLL], priv->cru,
1053 APLL);
1054 break;
1055 case PLL_DPLL:
1056 rate = rockchip_pll_get_rate(&rv1106_pll_clks[DPLL], priv->cru,
1057 DPLL);
1058 break;
1059 case PLL_CPLL:
1060 rate = rockchip_pll_get_rate(&rv1106_pll_clks[CPLL], priv->cru,
1061 CPLL);
1062 break;
1063 case PLL_GPLL:
1064 rate = rockchip_pll_get_rate(&rv1106_pll_clks[GPLL], priv->cru,
1065 GPLL);
1066 break;
1067 case ACLK_PERI_ROOT:
1068 case HCLK_PERI_ROOT:
1069 case PCLK_PERI_ROOT:
1070 case ACLK_BUS_ROOT:
1071 case PCLK_TOP_ROOT:
1072 case PCLK_PMU_ROOT:
1073 case HCLK_PMU_ROOT:
1074 rate = rv1106_peri_get_clk(priv, clk->id);
1075 break;
1076 #endif
1077 case CLK_CORE_CRYPTO:
1078 case CLK_PKA_CRYPTO:
1079 case ACLK_CRYPTO:
1080 rate = rv1106_crypto_get_clk(priv, clk->id);
1081 break;
1082 case CCLK_SRC_SDMMC:
1083 case CCLK_SRC_EMMC:
1084 case SCLK_SFC:
1085 case HCLK_SDMMC:
1086 case HCLK_EMMC:
1087 case HCLK_SFC:
1088 rate = rv1106_mmc_get_clk(priv, clk->id);
1089 break;
1090 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1091 case CLK_I2C0:
1092 case CLK_I2C1:
1093 case CLK_I2C2:
1094 case CLK_I2C3:
1095 case CLK_I2C4:
1096 rate = rv1106_i2c_get_clk(priv, clk->id);
1097 break;
1098 #endif
1099 case CLK_SPI0:
1100 case CLK_SPI1:
1101 rate = rv1106_spi_get_clk(priv, clk->id);
1102 break;
1103 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1104 case CLK_PWM0_PERI:
1105 case CLK_PWM1_PERI:
1106 case CLK_PWM2_PERI:
1107 rate = rv1106_pwm_get_clk(priv, clk->id);
1108 break;
1109 #endif
1110 case CLK_SARADC:
1111 case CLK_TSADC_TSEN:
1112 case CLK_TSADC:
1113 rate = rv1106_adc_get_clk(priv, clk->id);
1114 break;
1115 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1116 case SCLK_UART0:
1117 case SCLK_UART1:
1118 case SCLK_UART2:
1119 case SCLK_UART3:
1120 case SCLK_UART4:
1121 case SCLK_UART5:
1122 rate = rv1106_uart_get_rate(priv, clk->id);
1123 break;
1124 case DCLK_VOP_SRC:
1125 case DCLK_VOP:
1126 case ACLK_VOP_ROOT:
1127 case ACLK_VOP:
1128 rate = rv1106_vop_get_clk(priv, clk->id);
1129 break;
1130 case DCLK_DECOM:
1131 rate = rv1106_decom_get_clk(priv);
1132 break;
1133 #endif
1134 case TCLK_WDT_NS:
1135 rate = OSC_HZ;
1136 break;
1137 default:
1138 return -ENOENT;
1139 }
1140
1141 return rate;
1142 };
1143
rv1106_clk_set_rate(struct clk * clk,ulong rate)1144 static ulong rv1106_clk_set_rate(struct clk *clk, ulong rate)
1145 {
1146 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1147 ulong ret = 0;
1148
1149 if (!priv->gpll_hz) {
1150 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1151 return -ENOENT;
1152 }
1153
1154 switch (clk->id) {
1155 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1156 case PLL_APLL:
1157 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1158 APLL, rate);
1159 break;
1160 case PLL_CPLL:
1161 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1162 CPLL, rate);
1163 break;
1164 case PLL_GPLL:
1165 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1166 GPLL, rate);
1167 break;
1168 case ACLK_PERI_ROOT:
1169 case HCLK_PERI_ROOT:
1170 case PCLK_PERI_ROOT:
1171 case ACLK_BUS_ROOT:
1172 case PCLK_TOP_ROOT:
1173 case PCLK_PMU_ROOT:
1174 case HCLK_PMU_ROOT:
1175 ret = rv1106_peri_set_clk(priv, clk->id, rate);
1176 break;
1177 #endif
1178 case CLK_CORE_CRYPTO:
1179 case CLK_PKA_CRYPTO:
1180 case ACLK_CRYPTO:
1181 ret = rv1106_crypto_set_clk(priv, clk->id, rate);
1182 break;
1183 case CCLK_SRC_SDMMC:
1184 case CCLK_SRC_EMMC:
1185 case SCLK_SFC:
1186 case HCLK_SDMMC:
1187 case HCLK_EMMC:
1188 case HCLK_SFC:
1189 ret = rv1106_mmc_set_clk(priv, clk->id, rate);
1190 break;
1191 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1192 case CLK_I2C0:
1193 case CLK_I2C1:
1194 case CLK_I2C2:
1195 case CLK_I2C3:
1196 case CLK_I2C4:
1197 ret = rv1106_i2c_set_clk(priv, clk->id, rate);
1198 break;
1199 #endif
1200 case CLK_SPI0:
1201 case CLK_SPI1:
1202 ret = rv1106_spi_set_clk(priv, clk->id, rate);
1203 break;
1204 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1205 case CLK_PWM0_PERI:
1206 case CLK_PWM1_PERI:
1207 case CLK_PWM2_PERI:
1208 ret = rv1106_pwm_set_clk(priv, clk->id, rate);
1209 break;
1210 #endif
1211 case CLK_SARADC:
1212 case CLK_TSADC_TSEN:
1213 case CLK_TSADC:
1214 ret = rv1106_adc_set_clk(priv, clk->id, rate);
1215 break;
1216 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1217 case SCLK_UART0:
1218 case SCLK_UART1:
1219 case SCLK_UART2:
1220 case SCLK_UART3:
1221 case SCLK_UART4:
1222 case SCLK_UART5:
1223 ret = rv1106_uart_set_rate(priv, clk->id, rate);
1224 break;
1225 case DCLK_VOP_SRC:
1226 case DCLK_VOP:
1227 case ACLK_VOP_ROOT:
1228 case ACLK_VOP:
1229 rate = rv1106_vop_set_clk(priv, clk->id, rate);
1230 break;
1231 case DCLK_DECOM:
1232 rate = rv1106_decom_set_clk(priv, rate);
1233 break;
1234 #endif
1235 default:
1236 return -ENOENT;
1237 }
1238
1239 return ret;
1240 };
1241
rv1106_clk_set_parent(struct clk * clk,struct clk * parent)1242 static int rv1106_clk_set_parent(struct clk *clk, struct clk *parent)
1243 {
1244 switch (clk->id) {
1245 default:
1246 return -ENOENT;
1247 }
1248
1249 return 0;
1250 }
1251
1252 static struct clk_ops rv1106_clk_ops = {
1253 .get_rate = rv1106_clk_get_rate,
1254 .set_rate = rv1106_clk_set_rate,
1255 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1256 .set_parent = rv1106_clk_set_parent,
1257 #endif
1258 };
1259
1260 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
rv1106_clk_init(struct rv1106_clk_priv * priv)1261 static void rv1106_clk_init(struct rv1106_clk_priv *priv)
1262 {
1263 int ret;
1264
1265 priv->sync_kernel = false;
1266 if (!priv->armclk_enter_hz) {
1267 priv->armclk_enter_hz =
1268 rockchip_pll_get_rate(&rv1106_pll_clks[APLL],
1269 priv->cru, APLL);
1270 priv->armclk_init_hz = priv->armclk_enter_hz;
1271 }
1272
1273 if (priv->armclk_init_hz != APLL_HZ) {
1274 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1275 APLL, APLL_HZ);
1276 if (!ret)
1277 priv->armclk_init_hz = APLL_HZ;
1278 }
1279
1280 if (priv->cpll_hz != CPLL_HZ) {
1281 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1282 CPLL, CPLL_HZ);
1283 if (!ret)
1284 priv->cpll_hz = CPLL_HZ;
1285 }
1286
1287 if (priv->gpll_hz != GPLL_HZ) {
1288 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1289 GPLL, GPLL_HZ);
1290 if (!ret)
1291 priv->gpll_hz = GPLL_HZ;
1292 }
1293 }
1294 #endif
1295
rv1106_clk_probe(struct udevice * dev)1296 static int rv1106_clk_probe(struct udevice *dev)
1297 {
1298 struct rv1106_clk_priv *priv = dev_get_priv(dev);
1299 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1300 int ret;
1301
1302 rv1106_clk_init(priv);
1303
1304 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1305 ret = clk_set_defaults(dev);
1306 if (ret)
1307 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1308 else
1309 priv->sync_kernel = true;
1310 #else
1311 priv->gpll_hz = GPLL_HZ;
1312 priv->cpll_hz = CPLL_HZ;
1313 #endif
1314 rk_clrsetreg(&priv->cru->core_clksel_con[0],
1315 CLK_CORE_DIV_MASK,
1316 0 << CLK_CORE_DIV_SHIFT);
1317
1318 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1319 /* increase the aclk_decom frequency */
1320 rv1106_peri_set_clk(priv, ACLK_PERI_ROOT, 400 * MHz);
1321 #endif
1322 return 0;
1323 }
1324
rv1106_clk_ofdata_to_platdata(struct udevice * dev)1325 static int rv1106_clk_ofdata_to_platdata(struct udevice *dev)
1326 {
1327 struct rv1106_clk_priv *priv = dev_get_priv(dev);
1328
1329 priv->cru = dev_read_addr_ptr(dev);
1330
1331 return 0;
1332 }
1333
rv1106_clk_bind(struct udevice * dev)1334 static int rv1106_clk_bind(struct udevice *dev)
1335 {
1336 int ret;
1337 struct udevice *sys_child, *sf_child;
1338 struct sysreset_reg *priv;
1339 struct softreset_reg *sf_priv;
1340
1341 /* The reset driver does not have a device node, so bind it here */
1342 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1343 &sys_child);
1344 if (ret) {
1345 debug("Warning: No sysreset driver: ret=%d\n", ret);
1346 } else {
1347 priv = malloc(sizeof(struct sysreset_reg));
1348 priv->glb_srst_fst_value = offsetof(struct rv1106_cru,
1349 glb_srst_fst);
1350 priv->glb_srst_snd_value = offsetof(struct rv1106_cru,
1351 glb_srst_snd);
1352 sys_child->priv = priv;
1353 }
1354
1355 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1356 dev_ofnode(dev), &sf_child);
1357 if (ret) {
1358 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1359 } else {
1360 sf_priv = malloc(sizeof(struct softreset_reg));
1361 sf_priv->sf_reset_offset = offsetof(struct rv1106_cru,
1362 pmu_softrst_con[0]);
1363 sf_priv->sf_reset_num = 31745;
1364 sf_child->priv = sf_priv;
1365 }
1366
1367 return 0;
1368 }
1369
1370 static const struct udevice_id rv1106_clk_ids[] = {
1371 { .compatible = "rockchip,rv1106-cru" },
1372 { }
1373 };
1374
1375 U_BOOT_DRIVER(rockchip_rv1106_cru) = {
1376 .name = "rockchip_rv1106_cru",
1377 .id = UCLASS_CLK,
1378 .of_match = rv1106_clk_ids,
1379 .priv_auto_alloc_size = sizeof(struct rv1106_clk_priv),
1380 .ofdata_to_platdata = rv1106_clk_ofdata_to_platdata,
1381 .ops = &rv1106_clk_ops,
1382 .bind = rv1106_clk_bind,
1383 .probe = rv1106_clk_probe,
1384 };
1385
rv1106_grfclk_get_rate(struct clk * clk)1386 static ulong rv1106_grfclk_get_rate(struct clk *clk)
1387 {
1388 struct udevice *cru_dev;
1389 struct rv1106_clk_priv *cru_priv;
1390 int ret;
1391 ulong rate = 0;
1392
1393 ret = uclass_get_device_by_driver(UCLASS_CLK,
1394 DM_GET_DRIVER(rockchip_rv1106_cru),
1395 &cru_dev);
1396 if (ret) {
1397 printf("%s: could not find cru device\n", __func__);
1398 return ret;
1399 }
1400 cru_priv = dev_get_priv(cru_dev);
1401
1402 switch (clk->id) {
1403 case SCLK_EMMC_SAMPLE:
1404 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_EMMC) / 2;
1405 break;
1406 case SCLK_SDMMC_SAMPLE:
1407 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_SDMMC) / 2;
1408 break;
1409 case SCLK_SDIO_SAMPLE:
1410 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_SDIO) / 2;
1411 break;
1412 default:
1413 return -ENOENT;
1414 }
1415
1416 return rate;
1417 };
1418
1419 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1420 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1421 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1422 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1423
1424 #define PSECS_PER_SEC 1000000000000LL
1425 /*
1426 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1427 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1428 */
1429 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1430
rv1106_mmc_get_phase(struct clk * clk)1431 int rv1106_mmc_get_phase(struct clk *clk)
1432 {
1433 struct rv1106_grf_clk_priv *priv = dev_get_priv(clk->dev);
1434 u32 raw_value = 0, delay_num;
1435 u16 degrees = 0;
1436 ulong rate;
1437
1438 rate = rv1106_grfclk_get_rate(clk);
1439 if (rate < 0)
1440 return rate;
1441
1442 if (clk->id == SCLK_EMMC_SAMPLE)
1443 raw_value = readl(&priv->grf->emmc_con1);
1444 else if (clk->id == SCLK_SDMMC_SAMPLE)
1445 raw_value = readl(&priv->grf->sdmmc_con1);
1446 else if (clk->id == SCLK_SDIO_SAMPLE)
1447 raw_value = readl(&priv->grf->sdio_con1);
1448
1449 raw_value >>= 1;
1450 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1451
1452 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1453 /* degrees/delaynum * 10000 */
1454 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1455 36 * (rate / 1000000);
1456
1457 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1458 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1459 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1460 }
1461
1462 return degrees % 360;
1463 }
1464
rv1106_mmc_set_phase(struct clk * clk,u32 degrees)1465 int rv1106_mmc_set_phase(struct clk *clk, u32 degrees)
1466 {
1467 struct rv1106_grf_clk_priv *priv = dev_get_priv(clk->dev);
1468 u8 nineties, remainder, delay_num;
1469 u32 raw_value, delay;
1470 ulong rate;
1471
1472 rate = rv1106_grfclk_get_rate(clk);
1473 if (rate < 0)
1474 return rate;
1475
1476 nineties = degrees / 90;
1477 remainder = (degrees % 90);
1478
1479 /*
1480 * Convert to delay; do a little extra work to make sure we
1481 * don't overflow 32-bit / 64-bit numbers.
1482 */
1483 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1484 delay *= remainder;
1485 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1486 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1487
1488 delay_num = (u8)min_t(u32, delay, 255);
1489
1490 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1491 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1492 raw_value |= nineties;
1493
1494 raw_value <<= 1;
1495 if (clk->id == SCLK_EMMC_SAMPLE)
1496 writel(raw_value | 0xffff0000, &priv->grf->emmc_con1);
1497 else if (clk->id == SCLK_SDMMC_SAMPLE)
1498 writel(raw_value | 0xffff0000, &priv->grf->sdmmc_con1);
1499 else if (clk->id == SCLK_SDIO_SAMPLE)
1500 writel(raw_value | 0xffff0000, &priv->grf->sdio_con1);
1501
1502 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1503 degrees, delay_num, raw_value, rv1106_mmc_get_phase(clk));
1504
1505 return 0;
1506 }
1507
rv1106_grfclk_get_phase(struct clk * clk)1508 static int rv1106_grfclk_get_phase(struct clk *clk)
1509 {
1510 int ret;
1511
1512 debug("%s %ld\n", __func__, clk->id);
1513 switch (clk->id) {
1514 case SCLK_EMMC_SAMPLE:
1515 case SCLK_SDMMC_SAMPLE:
1516 case SCLK_SDIO_SAMPLE:
1517 ret = rv1106_mmc_get_phase(clk);
1518 break;
1519 default:
1520 return -ENOENT;
1521 }
1522 return ret;
1523 }
1524
rv1106_grfclk_set_phase(struct clk * clk,int degrees)1525 static int rv1106_grfclk_set_phase(struct clk *clk, int degrees)
1526 {
1527 int ret;
1528
1529 debug("%s %ld\n", __func__, clk->id);
1530 switch (clk->id) {
1531 case SCLK_EMMC_SAMPLE:
1532 case SCLK_SDMMC_SAMPLE:
1533 case SCLK_SDIO_SAMPLE:
1534 ret = rv1106_mmc_set_phase(clk, degrees);
1535 break;
1536 default:
1537 return -ENOENT;
1538 }
1539
1540 return ret;
1541 }
1542
1543 static struct clk_ops rv1106_grfclk_ops = {
1544 .get_rate = rv1106_grfclk_get_rate,
1545 .get_phase = rv1106_grfclk_get_phase,
1546 .set_phase = rv1106_grfclk_set_phase,
1547 };
1548
rv1106_grfclk_probe(struct udevice * dev)1549 static int rv1106_grfclk_probe(struct udevice *dev)
1550 {
1551 struct rv1106_grf_clk_priv *priv = dev_get_priv(dev);
1552
1553 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1554 if (IS_ERR(priv->grf))
1555 return PTR_ERR(priv->grf);
1556
1557 return 0;
1558 }
1559
rv1106_grfclk_ofdata_to_platdata(struct udevice * dev)1560 static int rv1106_grfclk_ofdata_to_platdata(struct udevice *dev)
1561 {
1562 return 0;
1563 }
1564
rv1106_grfclk_bind(struct udevice * dev)1565 static int rv1106_grfclk_bind(struct udevice *dev)
1566 {
1567 return 0;
1568 }
1569
1570 static const struct udevice_id rv1106_grfclk_ids[] = {
1571 { .compatible = "rockchip,rv1106-grf-cru" },
1572 { }
1573 };
1574
1575 U_BOOT_DRIVER(rockchip_rv1106_grf_cru) = {
1576 .name = "rockchip_rv1106_grf_cru",
1577 .id = UCLASS_CLK,
1578 .of_match = rv1106_grfclk_ids,
1579 .priv_auto_alloc_size = sizeof(struct rv1106_grf_clk_priv),
1580 .ofdata_to_platdata = rv1106_grfclk_ofdata_to_platdata,
1581 .ops = &rv1106_grfclk_ops,
1582 .bind = rv1106_grfclk_bind,
1583 .probe = rv1106_grfclk_probe,
1584 };
1585
1586 #ifndef CONFIG_SPL_BUILD
1587 /**
1588 * soc_clk_dump() - Print clock frequencies
1589 * Returns zero on success
1590 *
1591 * Implementation for the clk dump command.
1592 */
soc_clk_dump(void)1593 int soc_clk_dump(void)
1594 {
1595 struct udevice *cru_dev;
1596 struct rv1106_clk_priv *priv;
1597 const struct rv1106_clk_info *clk_dump;
1598 struct clk clk;
1599 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1600 unsigned long rate;
1601 int i, ret;
1602
1603 ret = uclass_get_device_by_driver(UCLASS_CLK,
1604 DM_GET_DRIVER(rockchip_rv1106_cru),
1605 &cru_dev);
1606 if (ret) {
1607 printf("%s failed to get cru device\n", __func__);
1608 return ret;
1609 }
1610
1611 priv = dev_get_priv(cru_dev);
1612 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1613 priv->sync_kernel ? "sync kernel" : "uboot",
1614 priv->armclk_enter_hz / 1000,
1615 priv->armclk_init_hz / 1000,
1616 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1617 priv->set_armclk_rate ? " KHz" : "N/A");
1618 for (i = 0; i < clk_count; i++) {
1619 clk_dump = &clks_dump[i];
1620 if (clk_dump->name) {
1621 clk.id = clk_dump->id;
1622 if (clk_dump->is_cru)
1623 ret = clk_request(cru_dev, &clk);
1624 if (ret < 0)
1625 return ret;
1626
1627 rate = clk_get_rate(&clk);
1628 clk_free(&clk);
1629 if (i == 0) {
1630 if (rate < 0)
1631 printf(" %s %s\n", clk_dump->name,
1632 "unknown");
1633 else
1634 printf(" %s %lu KHz\n", clk_dump->name,
1635 rate / 1000);
1636 } else {
1637 if (rate < 0)
1638 printf(" %s %s\n", clk_dump->name,
1639 "unknown");
1640 else
1641 printf(" %s %lu KHz\n", clk_dump->name,
1642 rate / 1000);
1643 }
1644 }
1645 }
1646
1647 return 0;
1648 }
1649 #endif
1650