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 default:
1135 return -ENOENT;
1136 }
1137
1138 return rate;
1139 };
1140
rv1106_clk_set_rate(struct clk * clk,ulong rate)1141 static ulong rv1106_clk_set_rate(struct clk *clk, ulong rate)
1142 {
1143 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev);
1144 ulong ret = 0;
1145
1146 if (!priv->gpll_hz) {
1147 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1148 return -ENOENT;
1149 }
1150
1151 switch (clk->id) {
1152 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1153 case PLL_APLL:
1154 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1155 APLL, rate);
1156 break;
1157 case PLL_CPLL:
1158 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1159 CPLL, rate);
1160 break;
1161 case PLL_GPLL:
1162 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1163 GPLL, rate);
1164 break;
1165 case ACLK_PERI_ROOT:
1166 case HCLK_PERI_ROOT:
1167 case PCLK_PERI_ROOT:
1168 case ACLK_BUS_ROOT:
1169 case PCLK_TOP_ROOT:
1170 case PCLK_PMU_ROOT:
1171 case HCLK_PMU_ROOT:
1172 ret = rv1106_peri_set_clk(priv, clk->id, rate);
1173 break;
1174 #endif
1175 case CLK_CORE_CRYPTO:
1176 case CLK_PKA_CRYPTO:
1177 case ACLK_CRYPTO:
1178 ret = rv1106_crypto_set_clk(priv, clk->id, rate);
1179 break;
1180 case CCLK_SRC_SDMMC:
1181 case CCLK_SRC_EMMC:
1182 case SCLK_SFC:
1183 case HCLK_SDMMC:
1184 case HCLK_EMMC:
1185 case HCLK_SFC:
1186 ret = rv1106_mmc_set_clk(priv, clk->id, rate);
1187 break;
1188 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1189 case CLK_I2C0:
1190 case CLK_I2C1:
1191 case CLK_I2C2:
1192 case CLK_I2C3:
1193 case CLK_I2C4:
1194 ret = rv1106_i2c_set_clk(priv, clk->id, rate);
1195 break;
1196 #endif
1197 case CLK_SPI0:
1198 case CLK_SPI1:
1199 ret = rv1106_spi_set_clk(priv, clk->id, rate);
1200 break;
1201 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1202 case CLK_PWM0_PERI:
1203 case CLK_PWM1_PERI:
1204 case CLK_PWM2_PERI:
1205 ret = rv1106_pwm_set_clk(priv, clk->id, rate);
1206 break;
1207 #endif
1208 case CLK_SARADC:
1209 case CLK_TSADC_TSEN:
1210 case CLK_TSADC:
1211 ret = rv1106_adc_set_clk(priv, clk->id, rate);
1212 break;
1213 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1214 case SCLK_UART0:
1215 case SCLK_UART1:
1216 case SCLK_UART2:
1217 case SCLK_UART3:
1218 case SCLK_UART4:
1219 case SCLK_UART5:
1220 ret = rv1106_uart_set_rate(priv, clk->id, rate);
1221 break;
1222 case DCLK_VOP_SRC:
1223 case DCLK_VOP:
1224 case ACLK_VOP_ROOT:
1225 case ACLK_VOP:
1226 rate = rv1106_vop_set_clk(priv, clk->id, rate);
1227 break;
1228 case DCLK_DECOM:
1229 rate = rv1106_decom_set_clk(priv, rate);
1230 break;
1231 #endif
1232 default:
1233 return -ENOENT;
1234 }
1235
1236 return ret;
1237 };
1238
rv1106_clk_set_parent(struct clk * clk,struct clk * parent)1239 static int rv1106_clk_set_parent(struct clk *clk, struct clk *parent)
1240 {
1241 switch (clk->id) {
1242 default:
1243 return -ENOENT;
1244 }
1245
1246 return 0;
1247 }
1248
1249 static struct clk_ops rv1106_clk_ops = {
1250 .get_rate = rv1106_clk_get_rate,
1251 .set_rate = rv1106_clk_set_rate,
1252 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1253 .set_parent = rv1106_clk_set_parent,
1254 #endif
1255 };
1256
1257 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
rv1106_clk_init(struct rv1106_clk_priv * priv)1258 static void rv1106_clk_init(struct rv1106_clk_priv *priv)
1259 {
1260 int ret;
1261
1262 priv->sync_kernel = false;
1263 if (!priv->armclk_enter_hz) {
1264 priv->armclk_enter_hz =
1265 rockchip_pll_get_rate(&rv1106_pll_clks[APLL],
1266 priv->cru, APLL);
1267 priv->armclk_init_hz = priv->armclk_enter_hz;
1268 }
1269
1270 if (priv->armclk_init_hz != APLL_HZ) {
1271 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
1272 APLL, APLL_HZ);
1273 if (!ret)
1274 priv->armclk_init_hz = APLL_HZ;
1275 }
1276
1277 if (priv->cpll_hz != CPLL_HZ) {
1278 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
1279 CPLL, CPLL_HZ);
1280 if (!ret)
1281 priv->cpll_hz = CPLL_HZ;
1282 }
1283
1284 if (priv->gpll_hz != GPLL_HZ) {
1285 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
1286 GPLL, GPLL_HZ);
1287 if (!ret)
1288 priv->gpll_hz = GPLL_HZ;
1289 }
1290 }
1291 #endif
1292
rv1106_clk_probe(struct udevice * dev)1293 static int rv1106_clk_probe(struct udevice *dev)
1294 {
1295 struct rv1106_clk_priv *priv = dev_get_priv(dev);
1296 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY
1297 int ret;
1298
1299 rv1106_clk_init(priv);
1300
1301 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1302 ret = clk_set_defaults(dev);
1303 if (ret)
1304 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1305 else
1306 priv->sync_kernel = true;
1307 #else
1308 priv->gpll_hz = GPLL_HZ;
1309 priv->cpll_hz = CPLL_HZ;
1310 #endif
1311 rk_clrsetreg(&priv->cru->core_clksel_con[0],
1312 CLK_CORE_DIV_MASK,
1313 0 << CLK_CORE_DIV_SHIFT);
1314
1315 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1316 /* increase the aclk_decom frequency */
1317 rv1106_peri_set_clk(priv, ACLK_PERI_ROOT, 400 * MHz);
1318 #endif
1319 return 0;
1320 }
1321
rv1106_clk_ofdata_to_platdata(struct udevice * dev)1322 static int rv1106_clk_ofdata_to_platdata(struct udevice *dev)
1323 {
1324 struct rv1106_clk_priv *priv = dev_get_priv(dev);
1325
1326 priv->cru = dev_read_addr_ptr(dev);
1327
1328 return 0;
1329 }
1330
rv1106_clk_bind(struct udevice * dev)1331 static int rv1106_clk_bind(struct udevice *dev)
1332 {
1333 int ret;
1334 struct udevice *sys_child, *sf_child;
1335 struct sysreset_reg *priv;
1336 struct softreset_reg *sf_priv;
1337
1338 /* The reset driver does not have a device node, so bind it here */
1339 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1340 &sys_child);
1341 if (ret) {
1342 debug("Warning: No sysreset driver: ret=%d\n", ret);
1343 } else {
1344 priv = malloc(sizeof(struct sysreset_reg));
1345 priv->glb_srst_fst_value = offsetof(struct rv1106_cru,
1346 glb_srst_fst);
1347 priv->glb_srst_snd_value = offsetof(struct rv1106_cru,
1348 glb_srst_snd);
1349 sys_child->priv = priv;
1350 }
1351
1352 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1353 dev_ofnode(dev), &sf_child);
1354 if (ret) {
1355 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1356 } else {
1357 sf_priv = malloc(sizeof(struct softreset_reg));
1358 sf_priv->sf_reset_offset = offsetof(struct rv1106_cru,
1359 pmu_softrst_con[0]);
1360 sf_priv->sf_reset_num = 31745;
1361 sf_child->priv = sf_priv;
1362 }
1363
1364 return 0;
1365 }
1366
1367 static const struct udevice_id rv1106_clk_ids[] = {
1368 { .compatible = "rockchip,rv1106-cru" },
1369 { }
1370 };
1371
1372 U_BOOT_DRIVER(rockchip_rv1106_cru) = {
1373 .name = "rockchip_rv1106_cru",
1374 .id = UCLASS_CLK,
1375 .of_match = rv1106_clk_ids,
1376 .priv_auto_alloc_size = sizeof(struct rv1106_clk_priv),
1377 .ofdata_to_platdata = rv1106_clk_ofdata_to_platdata,
1378 .ops = &rv1106_clk_ops,
1379 .bind = rv1106_clk_bind,
1380 .probe = rv1106_clk_probe,
1381 };
1382
rv1106_grfclk_get_rate(struct clk * clk)1383 static ulong rv1106_grfclk_get_rate(struct clk *clk)
1384 {
1385 struct udevice *cru_dev;
1386 struct rv1106_clk_priv *cru_priv;
1387 int ret;
1388 ulong rate = 0;
1389
1390 ret = uclass_get_device_by_driver(UCLASS_CLK,
1391 DM_GET_DRIVER(rockchip_rv1106_cru),
1392 &cru_dev);
1393 if (ret) {
1394 printf("%s: could not find cru device\n", __func__);
1395 return ret;
1396 }
1397 cru_priv = dev_get_priv(cru_dev);
1398
1399 switch (clk->id) {
1400 case SCLK_EMMC_SAMPLE:
1401 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_EMMC) / 2;
1402 break;
1403 case SCLK_SDMMC_SAMPLE:
1404 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_SDMMC) / 2;
1405 break;
1406 case SCLK_SDIO_SAMPLE:
1407 rate = rv1106_mmc_get_clk(cru_priv, CCLK_SRC_SDIO) / 2;
1408 break;
1409 default:
1410 return -ENOENT;
1411 }
1412
1413 return rate;
1414 };
1415
1416 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1417 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1418 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1419 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1420
1421 #define PSECS_PER_SEC 1000000000000LL
1422 /*
1423 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1424 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1425 */
1426 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1427
rv1106_mmc_get_phase(struct clk * clk)1428 int rv1106_mmc_get_phase(struct clk *clk)
1429 {
1430 struct rv1106_grf_clk_priv *priv = dev_get_priv(clk->dev);
1431 u32 raw_value = 0, delay_num;
1432 u16 degrees = 0;
1433 ulong rate;
1434
1435 rate = rv1106_grfclk_get_rate(clk);
1436 if (rate < 0)
1437 return rate;
1438
1439 if (clk->id == SCLK_EMMC_SAMPLE)
1440 raw_value = readl(&priv->grf->emmc_con1);
1441 else if (clk->id == SCLK_SDMMC_SAMPLE)
1442 raw_value = readl(&priv->grf->sdmmc_con1);
1443 else if (clk->id == SCLK_SDIO_SAMPLE)
1444 raw_value = readl(&priv->grf->sdio_con1);
1445
1446 raw_value >>= 1;
1447 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1448
1449 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1450 /* degrees/delaynum * 10000 */
1451 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1452 36 * (rate / 1000000);
1453
1454 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1455 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1456 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1457 }
1458
1459 return degrees % 360;
1460 }
1461
rv1106_mmc_set_phase(struct clk * clk,u32 degrees)1462 int rv1106_mmc_set_phase(struct clk *clk, u32 degrees)
1463 {
1464 struct rv1106_grf_clk_priv *priv = dev_get_priv(clk->dev);
1465 u8 nineties, remainder, delay_num;
1466 u32 raw_value, delay;
1467 ulong rate;
1468
1469 rate = rv1106_grfclk_get_rate(clk);
1470 if (rate < 0)
1471 return rate;
1472
1473 nineties = degrees / 90;
1474 remainder = (degrees % 90);
1475
1476 /*
1477 * Convert to delay; do a little extra work to make sure we
1478 * don't overflow 32-bit / 64-bit numbers.
1479 */
1480 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1481 delay *= remainder;
1482 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1483 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1484
1485 delay_num = (u8)min_t(u32, delay, 255);
1486
1487 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1488 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1489 raw_value |= nineties;
1490
1491 raw_value <<= 1;
1492 if (clk->id == SCLK_EMMC_SAMPLE)
1493 writel(raw_value | 0xffff0000, &priv->grf->emmc_con1);
1494 else if (clk->id == SCLK_SDMMC_SAMPLE)
1495 writel(raw_value | 0xffff0000, &priv->grf->sdmmc_con1);
1496 else if (clk->id == SCLK_SDIO_SAMPLE)
1497 writel(raw_value | 0xffff0000, &priv->grf->sdio_con1);
1498
1499 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1500 degrees, delay_num, raw_value, rv1106_mmc_get_phase(clk));
1501
1502 return 0;
1503 }
1504
rv1106_grfclk_get_phase(struct clk * clk)1505 static int rv1106_grfclk_get_phase(struct clk *clk)
1506 {
1507 int ret;
1508
1509 debug("%s %ld\n", __func__, clk->id);
1510 switch (clk->id) {
1511 case SCLK_EMMC_SAMPLE:
1512 case SCLK_SDMMC_SAMPLE:
1513 case SCLK_SDIO_SAMPLE:
1514 ret = rv1106_mmc_get_phase(clk);
1515 break;
1516 default:
1517 return -ENOENT;
1518 }
1519 return ret;
1520 }
1521
rv1106_grfclk_set_phase(struct clk * clk,int degrees)1522 static int rv1106_grfclk_set_phase(struct clk *clk, int degrees)
1523 {
1524 int ret;
1525
1526 debug("%s %ld\n", __func__, clk->id);
1527 switch (clk->id) {
1528 case SCLK_EMMC_SAMPLE:
1529 case SCLK_SDMMC_SAMPLE:
1530 case SCLK_SDIO_SAMPLE:
1531 ret = rv1106_mmc_set_phase(clk, degrees);
1532 break;
1533 default:
1534 return -ENOENT;
1535 }
1536
1537 return ret;
1538 }
1539
1540 static struct clk_ops rv1106_grfclk_ops = {
1541 .get_rate = rv1106_grfclk_get_rate,
1542 .get_phase = rv1106_grfclk_get_phase,
1543 .set_phase = rv1106_grfclk_set_phase,
1544 };
1545
rv1106_grfclk_probe(struct udevice * dev)1546 static int rv1106_grfclk_probe(struct udevice *dev)
1547 {
1548 struct rv1106_grf_clk_priv *priv = dev_get_priv(dev);
1549
1550 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1551 if (IS_ERR(priv->grf))
1552 return PTR_ERR(priv->grf);
1553
1554 return 0;
1555 }
1556
rv1106_grfclk_ofdata_to_platdata(struct udevice * dev)1557 static int rv1106_grfclk_ofdata_to_platdata(struct udevice *dev)
1558 {
1559 return 0;
1560 }
1561
rv1106_grfclk_bind(struct udevice * dev)1562 static int rv1106_grfclk_bind(struct udevice *dev)
1563 {
1564 return 0;
1565 }
1566
1567 static const struct udevice_id rv1106_grfclk_ids[] = {
1568 { .compatible = "rockchip,rv1106-grf-cru" },
1569 { }
1570 };
1571
1572 U_BOOT_DRIVER(rockchip_rv1106_grf_cru) = {
1573 .name = "rockchip_rv1106_grf_cru",
1574 .id = UCLASS_CLK,
1575 .of_match = rv1106_grfclk_ids,
1576 .priv_auto_alloc_size = sizeof(struct rv1106_grf_clk_priv),
1577 .ofdata_to_platdata = rv1106_grfclk_ofdata_to_platdata,
1578 .ops = &rv1106_grfclk_ops,
1579 .bind = rv1106_grfclk_bind,
1580 .probe = rv1106_grfclk_probe,
1581 };
1582
1583 #ifndef CONFIG_SPL_BUILD
1584 /**
1585 * soc_clk_dump() - Print clock frequencies
1586 * Returns zero on success
1587 *
1588 * Implementation for the clk dump command.
1589 */
soc_clk_dump(void)1590 int soc_clk_dump(void)
1591 {
1592 struct udevice *cru_dev;
1593 struct rv1106_clk_priv *priv;
1594 const struct rv1106_clk_info *clk_dump;
1595 struct clk clk;
1596 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1597 unsigned long rate;
1598 int i, ret;
1599
1600 ret = uclass_get_device_by_driver(UCLASS_CLK,
1601 DM_GET_DRIVER(rockchip_rv1106_cru),
1602 &cru_dev);
1603 if (ret) {
1604 printf("%s failed to get cru device\n", __func__);
1605 return ret;
1606 }
1607
1608 priv = dev_get_priv(cru_dev);
1609 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1610 priv->sync_kernel ? "sync kernel" : "uboot",
1611 priv->armclk_enter_hz / 1000,
1612 priv->armclk_init_hz / 1000,
1613 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1614 priv->set_armclk_rate ? " KHz" : "N/A");
1615 for (i = 0; i < clk_count; i++) {
1616 clk_dump = &clks_dump[i];
1617 if (clk_dump->name) {
1618 clk.id = clk_dump->id;
1619 if (clk_dump->is_cru)
1620 ret = clk_request(cru_dev, &clk);
1621 if (ret < 0)
1622 return ret;
1623
1624 rate = clk_get_rate(&clk);
1625 clk_free(&clk);
1626 if (i == 0) {
1627 if (rate < 0)
1628 printf(" %s %s\n", clk_dump->name,
1629 "unknown");
1630 else
1631 printf(" %s %lu KHz\n", clk_dump->name,
1632 rate / 1000);
1633 } else {
1634 if (rate < 0)
1635 printf(" %s %s\n", clk_dump->name,
1636 "unknown");
1637 else
1638 printf(" %s %lu KHz\n", clk_dump->name,
1639 rate / 1000);
1640 }
1641 }
1642 }
1643
1644 return 0;
1645 }
1646 #endif
1647