blob: d5e45e7602c7c1c7fe2e5738e6ae8b3e969b278b [file] [log] [blame]
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001// 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-rockchip/cru_rk3568.h>
14#include <asm/arch-rockchip/clock.h>
15#include <asm/arch-rockchip/hardware.h>
16#include <asm/io.h>
17#include <dm/lists.h>
18#include <dt-bindings/clock/rk3568-cru.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21
22#if CONFIG_IS_ENABLED(OF_PLATDATA)
23struct rk3568_clk_plat {
24 struct dtd_rockchip_rk3568_cru dtd;
25};
26
27struct rk3568_pmuclk_plat {
28 struct dtd_rockchip_rk3568_pmucru dtd;
29};
30#endif
31
32#define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
33{ \
34 .rate = _rate##U, \
35 .aclk_div = _aclk_div, \
36 .pclk_div = _pclk_div, \
37}
38
39#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
40
41static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = {
42 RK3568_CPUCLK_RATE(1416000000, 1, 5),
43 RK3568_CPUCLK_RATE(1296000000, 1, 5),
44 RK3568_CPUCLK_RATE(1200000000, 1, 3),
45 RK3568_CPUCLK_RATE(1104000000, 1, 3),
46 RK3568_CPUCLK_RATE(1008000000, 1, 3),
47 RK3568_CPUCLK_RATE(912000000, 1, 3),
48 RK3568_CPUCLK_RATE(816000000, 1, 3),
49 RK3568_CPUCLK_RATE(600000000, 1, 1),
50 RK3568_CPUCLK_RATE(408000000, 1, 1),
51 { /* sentinel */ },
52};
53
54static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
55 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
56 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
57 RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
58 RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
59 RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
60 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
61 RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
62 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
63 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
64 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
65 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
66 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
67 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
68 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
69 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
70 RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
71 RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
72 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
73 { /* sentinel */ },
74};
75
76static struct rockchip_pll_clock rk3568_pll_clks[] = {
77 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0),
78 RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates),
79 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8),
80 RK3568_MODE_CON, 2, 10, 0, NULL),
81 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24),
82 RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates),
83 [GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16),
84 RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates),
85 [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32),
86 RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates),
87 [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40),
88 RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates),
89 [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0),
90 RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates),
91 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16),
92 RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates),
93};
94
95#ifndef CONFIG_SPL_BUILD
96static ulong
97rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
98 ulong pll_id, ulong rate)
99{
100 struct udevice *pmucru_dev;
101 struct rk3568_pmuclk_priv *pmu_priv;
102 int ret;
103
104 ret = uclass_get_device_by_driver(UCLASS_CLK,
105 DM_DRIVER_GET(rockchip_rk3568_pmucru),
106 &pmucru_dev);
107 if (ret) {
108 printf("%s: could not find pmucru device\n", __func__);
109 return ret;
110 }
111 pmu_priv = dev_get_priv(pmucru_dev);
112
113 rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
114 pmu_priv->pmucru, pll_id, rate);
115
116 return 0;
117}
118#endif
119
120static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
121 ulong pll_id)
122{
123 struct udevice *pmucru_dev;
124 struct rk3568_pmuclk_priv *pmu_priv;
125 int ret;
126
127 ret = uclass_get_device_by_driver(UCLASS_CLK,
128 DM_DRIVER_GET(rockchip_rk3568_pmucru),
129 &pmucru_dev);
130 if (ret) {
131 printf("%s: could not find pmucru device\n", __func__);
132 return ret;
133 }
134 pmu_priv = dev_get_priv(pmucru_dev);
135
136 return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
137 pmu_priv->pmucru, pll_id);
138}
139
140/*
141 *
142 * rational_best_approximation(31415, 10000,
143 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
144 *
145 * you may look at given_numerator as a fixed point number,
146 * with the fractional part size described in given_denominator.
147 *
148 * for theoretical background, see:
149 * http://en.wikipedia.org/wiki/Continued_fraction
150 */
151static void rational_best_approximation(unsigned long given_numerator,
152 unsigned long given_denominator,
153 unsigned long max_numerator,
154 unsigned long max_denominator,
155 unsigned long *best_numerator,
156 unsigned long *best_denominator)
157{
158 unsigned long n, d, n0, d0, n1, d1;
159
160 n = given_numerator;
161 d = given_denominator;
162 n0 = 0;
163 d1 = 0;
164 n1 = 1;
165 d0 = 1;
166 for (;;) {
167 unsigned long t, a;
168
169 if (n1 > max_numerator || d1 > max_denominator) {
170 n1 = n0;
171 d1 = d0;
172 break;
173 }
174 if (d == 0)
175 break;
176 t = d;
177 a = n / d;
178 d = n % d;
179 n = t;
180 t = n0 + a * n1;
181 n0 = n1;
182 n1 = t;
183 t = d0 + a * d1;
184 d0 = d1;
185 d1 = t;
186 }
187 *best_numerator = n1;
188 *best_denominator = d1;
189}
190
191static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
192{
193 struct rk3568_pmucru *pmucru = priv->pmucru;
194 unsigned long m, n;
195 u32 fracdiv;
196
197 fracdiv = readl(&pmucru->pmu_clksel_con[1]);
198 m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
199 m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
200 n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
201 n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
202
203 return OSC_HZ * m / n;
204}
205
206static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
207 ulong rate)
208{
209 struct rk3568_pmucru *pmucru = priv->pmucru;
210 unsigned long m, n, val;
211
212 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
213 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
214
215 rational_best_approximation(rate, OSC_HZ,
216 GENMASK(16 - 1, 0),
217 GENMASK(16 - 1, 0),
218 &m, &n);
219 val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
220 writel(val, &pmucru->pmu_clksel_con[1]);
221
222 return rk3568_rtc32k_get_pmuclk(priv);
223}
224
225static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
226 ulong clk_id)
227{
228 struct rk3568_pmucru *pmucru = priv->pmucru;
229 u32 div, con;
230
231 switch (clk_id) {
232 case CLK_I2C0:
233 con = readl(&pmucru->pmu_clksel_con[3]);
234 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
235 break;
236 default:
237 return -ENOENT;
238 }
239
240 return DIV_TO_RATE(priv->ppll_hz, div);
241}
242
243static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
244 ulong clk_id, ulong rate)
245{
246 struct rk3568_pmucru *pmucru = priv->pmucru;
247 int src_clk_div;
248
249 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
250 assert(src_clk_div - 1 <= 127);
251
252 switch (clk_id) {
253 case CLK_I2C0:
254 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
255 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
256 break;
257 default:
258 return -ENOENT;
259 }
260
261 return rk3568_i2c_get_pmuclk(priv, clk_id);
262}
263
264static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
265 ulong clk_id)
266{
267 struct rk3568_pmucru *pmucru = priv->pmucru;
268 u32 div, sel, con, parent;
269
270 switch (clk_id) {
271 case CLK_PWM0:
272 con = readl(&pmucru->pmu_clksel_con[6]);
273 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
274 div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
275 if (sel == CLK_PWM0_SEL_XIN24M)
276 parent = OSC_HZ;
277 else
278 parent = priv->ppll_hz;
279 break;
280 default:
281 return -ENOENT;
282 }
283
284 return DIV_TO_RATE(parent, div);
285}
286
287static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
288 ulong clk_id, ulong rate)
289{
290 struct rk3568_pmucru *pmucru = priv->pmucru;
291 int src_clk_div;
292
293 switch (clk_id) {
294 case CLK_PWM0:
295 if (rate == OSC_HZ) {
296 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
297 CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
298 (CLK_PWM0_SEL_XIN24M <<
299 CLK_PWM0_SEL_SHIFT) |
300 0 << CLK_PWM0_SEL_SHIFT);
301 } else {
302 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
303 assert(src_clk_div - 1 <= 127);
304 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
305 CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
306 (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) |
307 (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
308 }
309 break;
310 default:
311 return -ENOENT;
312 }
313
314 return rk3568_pwm_get_pmuclk(priv, clk_id);
315}
316
317static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
318{
319 struct rk3568_pmucru *pmucru = priv->pmucru;
320 u32 div, con, sel, parent;
321
322 con = readl(&pmucru->pmu_clksel_con[2]);
323 sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
324 div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
325 if (sel)
326 parent = GPLL_HZ;
327 else
328 parent = priv->ppll_hz;
329
330 return DIV_TO_RATE(parent, div);
331}
332
333static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
334 ulong rate)
335{
336 struct rk3568_pmucru *pmucru = priv->pmucru;
337 int src_clk_div;
338
339 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
340 assert(src_clk_div - 1 <= 31);
341
342 rk_clrsetreg(&pmucru->pmu_clksel_con[2],
343 PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
344 (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) |
345 ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
346
347 return rk3568_pmu_get_pmuclk(priv);
348}
349
350static ulong rk3568_pmuclk_get_rate(struct clk *clk)
351{
352 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
353 ulong rate = 0;
354
355 if (!priv->ppll_hz) {
356 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
357 return -ENOENT;
358 }
359
360 debug("%s %ld\n", __func__, clk->id);
361 switch (clk->id) {
362 case PLL_PPLL:
363 rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
364 priv->pmucru, PPLL);
365 break;
366 case PLL_HPLL:
367 rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
368 priv->pmucru, HPLL);
369 break;
370 case CLK_RTC_32K:
371 case CLK_RTC32K_FRAC:
372 rate = rk3568_rtc32k_get_pmuclk(priv);
373 break;
374 case CLK_I2C0:
375 rate = rk3568_i2c_get_pmuclk(priv, clk->id);
376 break;
377 case CLK_PWM0:
378 rate = rk3568_pwm_get_pmuclk(priv, clk->id);
379 break;
380 case PCLK_PMU:
381 rate = rk3568_pmu_get_pmuclk(priv);
382 break;
383 default:
384 return -ENOENT;
385 }
386
387 return rate;
388}
389
390static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
391{
392 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
393 ulong ret = 0;
394
395 if (!priv->ppll_hz) {
396 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
397 return -ENOENT;
398 }
399
400 debug("%s %ld %ld\n", __func__, clk->id, rate);
401 switch (clk->id) {
402 case PLL_PPLL:
403 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
404 priv->pmucru, PPLL, rate);
405 priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
406 priv->pmucru, PPLL);
407 break;
408 case PLL_HPLL:
409 ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL],
410 priv->pmucru, HPLL, rate);
411 priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
412 priv->pmucru, HPLL);
413 break;
414 case CLK_RTC_32K:
415 case CLK_RTC32K_FRAC:
416 ret = rk3568_rtc32k_set_pmuclk(priv, rate);
417 break;
418 case CLK_I2C0:
419 ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
420 break;
421 case CLK_PWM0:
422 ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
423 break;
424 case PCLK_PMU:
425 ret = rk3568_pmu_set_pmuclk(priv, rate);
426 break;
427 default:
428 return -ENOENT;
429 }
430
431 return ret;
432}
433
434static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
435{
436 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
437 struct rk3568_pmucru *pmucru = priv->pmucru;
438
439 if (parent->id == CLK_RTC32K_FRAC)
440 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
441 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
442 else
443 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
444 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
445
446 return 0;
447}
448
449static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
450{
451 switch (clk->id) {
452 case CLK_RTC_32K:
453 return rk3568_rtc32k_set_parent(clk, parent);
454 default:
455 return -ENOENT;
456 }
457}
458
459static struct clk_ops rk3568_pmuclk_ops = {
460 .get_rate = rk3568_pmuclk_get_rate,
461 .set_rate = rk3568_pmuclk_set_rate,
462 .set_parent = rk3568_pmuclk_set_parent,
463};
464
465static int rk3568_pmuclk_probe(struct udevice *dev)
466{
467 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
468 int ret = 0;
469
470 if (priv->ppll_hz != PPLL_HZ) {
471 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
472 priv->pmucru,
473 PPLL, PPLL_HZ);
474 if (!ret)
475 priv->ppll_hz = PPLL_HZ;
476 }
477
478 /* Ungate PCIe30phy refclk_m and refclk_n */
479 rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
480 return 0;
481}
482
483static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
484{
485 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
486
487 priv->pmucru = dev_read_addr_ptr(dev);
488
489 return 0;
490}
491
492static int rk3568_pmuclk_bind(struct udevice *dev)
493{
494#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
495 int ret = 0;
496
497 ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]);
498 ret = rockchip_reset_bind(dev, ret, 1);
499 if (ret)
500 debug("Warning: pmucru software reset driver bind faile\n");
501#endif
502
503 return 0;
504}
505
506static const struct udevice_id rk3568_pmuclk_ids[] = {
507 { .compatible = "rockchip,rk3568-pmucru" },
508 { }
509};
510
511U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
512 .name = "rockchip_rk3568_pmucru",
513 .id = UCLASS_CLK,
514 .of_match = rk3568_pmuclk_ids,
515 .priv_auto = sizeof(struct rk3568_pmuclk_priv),
516 .of_to_plat = rk3568_pmuclk_ofdata_to_platdata,
517 .ops = &rk3568_pmuclk_ops,
518 .bind = rk3568_pmuclk_bind,
519 .probe = rk3568_pmuclk_probe,
520#if CONFIG_IS_ENABLED(OF_PLATDATA)
521 .plat_auto = sizeof(struct rk3568_pmuclk_plat),
522#endif
523
524};
525
526static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
527{
528 struct rk3568_cru *cru = priv->cru;
529 const struct rockchip_cpu_rate_table *rate;
530 ulong old_rate;
531
532 rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
533 if (!rate) {
534 printf("%s unsupported rate\n", __func__);
535 return -EINVAL;
536 }
537
538 rk_clrsetreg(&cru->clksel_con[0],
539 CLK_CORE_PRE_SEL_MASK,
540 (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
541 rk_clrsetreg(&cru->clksel_con[2],
542 SCLK_CORE_PRE_SEL_MASK |
543 SCLK_CORE_SRC_SEL_MASK |
544 SCLK_CORE_SRC_DIV_MASK,
545 (SCLK_CORE_PRE_SEL_SRC <<
546 SCLK_CORE_PRE_SEL_SHIFT) |
547 (SCLK_CORE_SRC_SEL_APLL <<
548 SCLK_CORE_SRC_SEL_SHIFT) |
549 (1 << SCLK_CORE_SRC_DIV_SHIFT));
550
551 /*
552 * set up dependent divisors for DBG and ACLK clocks.
553 */
554 old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
555 priv->cru, APLL);
556 if (old_rate > hz) {
557 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
558 priv->cru, APLL, hz))
559 return -EINVAL;
560 rk_clrsetreg(&cru->clksel_con[3],
561 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
562 rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
563 rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
564 rk_clrsetreg(&cru->clksel_con[4],
565 PERIPHCLK_CORE_PRE_DIV_MASK |
566 PCLK_CORE_PRE_DIV_MASK,
567 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
568 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
569 rk_clrsetreg(&cru->clksel_con[5],
570 ACLK_CORE_NDFT_DIV_MASK,
571 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
572 } else if (old_rate < hz) {
573 rk_clrsetreg(&cru->clksel_con[3],
574 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
575 rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
576 rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
577 rk_clrsetreg(&cru->clksel_con[4],
578 PERIPHCLK_CORE_PRE_DIV_MASK |
579 PCLK_CORE_PRE_DIV_MASK,
580 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
581 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
582 rk_clrsetreg(&cru->clksel_con[5],
583 ACLK_CORE_NDFT_DIV_MASK,
584 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
585 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
586 priv->cru, APLL, hz))
587 return -EINVAL;
588 }
589
590 return 0;
591}
592
593static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
594 ulong clk_id)
595{
596 struct rk3568_cru *cru = priv->cru;
597 int div, mask, shift, con;
598
599 switch (clk_id) {
600 case CPLL_500M:
601 con = 78;
602 mask = CPLL_500M_DIV_MASK;
603 shift = CPLL_500M_DIV_SHIFT;
604 break;
605 case CPLL_333M:
606 con = 79;
607 mask = CPLL_333M_DIV_MASK;
608 shift = CPLL_333M_DIV_SHIFT;
609 break;
610 case CPLL_250M:
611 con = 79;
612 mask = CPLL_250M_DIV_MASK;
613 shift = CPLL_250M_DIV_SHIFT;
614 break;
615 case CPLL_125M:
616 con = 80;
617 mask = CPLL_125M_DIV_MASK;
618 shift = CPLL_125M_DIV_SHIFT;
619 break;
620 case CPLL_100M:
621 con = 82;
622 mask = CPLL_100M_DIV_MASK;
623 shift = CPLL_100M_DIV_SHIFT;
624 break;
625 case CPLL_62P5M:
626 con = 80;
627 mask = CPLL_62P5M_DIV_MASK;
628 shift = CPLL_62P5M_DIV_SHIFT;
629 break;
630 case CPLL_50M:
631 con = 81;
632 mask = CPLL_50M_DIV_MASK;
633 shift = CPLL_50M_DIV_SHIFT;
634 break;
635 case CPLL_25M:
636 con = 81;
637 mask = CPLL_25M_DIV_MASK;
638 shift = CPLL_25M_DIV_SHIFT;
639 break;
640 default:
641 return -ENOENT;
642 }
643
644 div = (readl(&cru->clksel_con[con]) & mask) >> shift;
645 return DIV_TO_RATE(priv->cpll_hz, div);
646}
647
648static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
649 ulong clk_id, ulong rate)
650{
651 struct rk3568_cru *cru = priv->cru;
652 int div, mask, shift, con;
653
654 switch (clk_id) {
655 case CPLL_500M:
656 con = 78;
657 mask = CPLL_500M_DIV_MASK;
658 shift = CPLL_500M_DIV_SHIFT;
659 break;
660 case CPLL_333M:
661 con = 79;
662 mask = CPLL_333M_DIV_MASK;
663 shift = CPLL_333M_DIV_SHIFT;
664 break;
665 case CPLL_250M:
666 con = 79;
667 mask = CPLL_250M_DIV_MASK;
668 shift = CPLL_250M_DIV_SHIFT;
669 break;
670 case CPLL_125M:
671 con = 80;
672 mask = CPLL_125M_DIV_MASK;
673 shift = CPLL_125M_DIV_SHIFT;
674 break;
675 case CPLL_100M:
676 con = 82;
677 mask = CPLL_100M_DIV_MASK;
678 shift = CPLL_100M_DIV_SHIFT;
679 break;
680 case CPLL_62P5M:
681 con = 80;
682 mask = CPLL_62P5M_DIV_MASK;
683 shift = CPLL_62P5M_DIV_SHIFT;
684 break;
685 case CPLL_50M:
686 con = 81;
687 mask = CPLL_50M_DIV_MASK;
688 shift = CPLL_50M_DIV_SHIFT;
689 break;
690 case CPLL_25M:
691 con = 81;
692 mask = CPLL_25M_DIV_MASK;
693 shift = CPLL_25M_DIV_SHIFT;
694 break;
695 default:
696 return -ENOENT;
697 }
698
699 div = DIV_ROUND_UP(priv->cpll_hz, rate);
700 assert(div - 1 <= 31);
701 rk_clrsetreg(&cru->clksel_con[con],
702 mask, (div - 1) << shift);
703 return rk3568_cpll_div_get_rate(priv, clk_id);
704}
705
706static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
707{
708 struct rk3568_cru *cru = priv->cru;
709 u32 con, sel, rate;
710
711 switch (clk_id) {
712 case ACLK_BUS:
713 con = readl(&cru->clksel_con[50]);
714 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
715 if (sel == ACLK_BUS_SEL_200M)
716 rate = 200 * MHz;
717 else if (sel == ACLK_BUS_SEL_150M)
718 rate = 150 * MHz;
719 else if (sel == ACLK_BUS_SEL_100M)
720 rate = 100 * MHz;
721 else
722 rate = OSC_HZ;
723 break;
724 case PCLK_BUS:
725 case PCLK_WDT_NS:
726 con = readl(&cru->clksel_con[50]);
727 sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
728 if (sel == PCLK_BUS_SEL_100M)
729 rate = 100 * MHz;
730 else if (sel == PCLK_BUS_SEL_75M)
731 rate = 75 * MHz;
732 else if (sel == PCLK_BUS_SEL_50M)
733 rate = 50 * MHz;
734 else
735 rate = OSC_HZ;
736 break;
737 default:
738 return -ENOENT;
739 }
740
741 return rate;
742}
743
744static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
745 ulong clk_id, ulong rate)
746{
747 struct rk3568_cru *cru = priv->cru;
748 int src_clk;
749
750 switch (clk_id) {
751 case ACLK_BUS:
752 if (rate == 200 * MHz)
753 src_clk = ACLK_BUS_SEL_200M;
754 else if (rate == 150 * MHz)
755 src_clk = ACLK_BUS_SEL_150M;
756 else if (rate == 100 * MHz)
757 src_clk = ACLK_BUS_SEL_100M;
758 else
759 src_clk = ACLK_BUS_SEL_24M;
760 rk_clrsetreg(&cru->clksel_con[50],
761 ACLK_BUS_SEL_MASK,
762 src_clk << ACLK_BUS_SEL_SHIFT);
763 break;
764 case PCLK_BUS:
765 case PCLK_WDT_NS:
766 if (rate == 100 * MHz)
767 src_clk = PCLK_BUS_SEL_100M;
768 else if (rate == 75 * MHz)
769 src_clk = PCLK_BUS_SEL_75M;
770 else if (rate == 50 * MHz)
771 src_clk = PCLK_BUS_SEL_50M;
772 else
773 src_clk = PCLK_BUS_SEL_24M;
774 rk_clrsetreg(&cru->clksel_con[50],
775 PCLK_BUS_SEL_MASK,
776 src_clk << PCLK_BUS_SEL_SHIFT);
777 break;
778
779 default:
780 printf("do not support this bus freq\n");
781 return -EINVAL;
782 }
783
784 return rk3568_bus_get_clk(priv, clk_id);
785}
786
787static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
788{
789 struct rk3568_cru *cru = priv->cru;
790 u32 con, sel, rate;
791
792 switch (clk_id) {
793 case ACLK_PERIMID:
794 con = readl(&cru->clksel_con[10]);
795 sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
796 if (sel == ACLK_PERIMID_SEL_300M)
797 rate = 300 * MHz;
798 else if (sel == ACLK_PERIMID_SEL_200M)
799 rate = 200 * MHz;
800 else if (sel == ACLK_PERIMID_SEL_100M)
801 rate = 100 * MHz;
802 else
803 rate = OSC_HZ;
804 break;
805 case HCLK_PERIMID:
806 con = readl(&cru->clksel_con[10]);
807 sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
808 if (sel == HCLK_PERIMID_SEL_150M)
809 rate = 150 * MHz;
810 else if (sel == HCLK_PERIMID_SEL_100M)
811 rate = 100 * MHz;
812 else if (sel == HCLK_PERIMID_SEL_75M)
813 rate = 75 * MHz;
814 else
815 rate = OSC_HZ;
816 break;
817 default:
818 return -ENOENT;
819 }
820
821 return rate;
822}
823
824static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
825 ulong clk_id, ulong rate)
826{
827 struct rk3568_cru *cru = priv->cru;
828 int src_clk;
829
830 switch (clk_id) {
831 case ACLK_PERIMID:
832 if (rate == 300 * MHz)
833 src_clk = ACLK_PERIMID_SEL_300M;
834 else if (rate == 200 * MHz)
835 src_clk = ACLK_PERIMID_SEL_200M;
836 else if (rate == 100 * MHz)
837 src_clk = ACLK_PERIMID_SEL_100M;
838 else
839 src_clk = ACLK_PERIMID_SEL_24M;
840 rk_clrsetreg(&cru->clksel_con[10],
841 ACLK_PERIMID_SEL_MASK,
842 src_clk << ACLK_PERIMID_SEL_SHIFT);
843 break;
844 case HCLK_PERIMID:
845 if (rate == 150 * MHz)
846 src_clk = HCLK_PERIMID_SEL_150M;
847 else if (rate == 100 * MHz)
848 src_clk = HCLK_PERIMID_SEL_100M;
849 else if (rate == 75 * MHz)
850 src_clk = HCLK_PERIMID_SEL_75M;
851 else
852 src_clk = HCLK_PERIMID_SEL_24M;
853 rk_clrsetreg(&cru->clksel_con[10],
854 HCLK_PERIMID_SEL_MASK,
855 src_clk << HCLK_PERIMID_SEL_SHIFT);
856 break;
857
858 default:
859 printf("do not support this permid freq\n");
860 return -EINVAL;
861 }
862
863 return rk3568_perimid_get_clk(priv, clk_id);
864}
865
866static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
867{
868 struct rk3568_cru *cru = priv->cru;
869 u32 con, sel, rate;
870
871 switch (clk_id) {
872 case ACLK_TOP_HIGH:
873 con = readl(&cru->clksel_con[73]);
874 sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
875 if (sel == ACLK_TOP_HIGH_SEL_500M)
876 rate = 500 * MHz;
877 else if (sel == ACLK_TOP_HIGH_SEL_400M)
878 rate = 400 * MHz;
879 else if (sel == ACLK_TOP_HIGH_SEL_300M)
880 rate = 300 * MHz;
881 else
882 rate = OSC_HZ;
883 break;
884 case ACLK_TOP_LOW:
885 con = readl(&cru->clksel_con[73]);
886 sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
887 if (sel == ACLK_TOP_LOW_SEL_400M)
888 rate = 400 * MHz;
889 else if (sel == ACLK_TOP_LOW_SEL_300M)
890 rate = 300 * MHz;
891 else if (sel == ACLK_TOP_LOW_SEL_200M)
892 rate = 200 * MHz;
893 else
894 rate = OSC_HZ;
895 break;
896 case HCLK_TOP:
897 con = readl(&cru->clksel_con[73]);
898 sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
899 if (sel == HCLK_TOP_SEL_150M)
900 rate = 150 * MHz;
901 else if (sel == HCLK_TOP_SEL_100M)
902 rate = 100 * MHz;
903 else if (sel == HCLK_TOP_SEL_75M)
904 rate = 75 * MHz;
905 else
906 rate = OSC_HZ;
907 break;
908 case PCLK_TOP:
909 con = readl(&cru->clksel_con[73]);
910 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
911 if (sel == PCLK_TOP_SEL_100M)
912 rate = 100 * MHz;
913 else if (sel == PCLK_TOP_SEL_75M)
914 rate = 75 * MHz;
915 else if (sel == PCLK_TOP_SEL_50M)
916 rate = 50 * MHz;
917 else
918 rate = OSC_HZ;
919 break;
920 default:
921 return -ENOENT;
922 }
923
924 return rate;
925}
926
927static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
928 ulong clk_id, ulong rate)
929{
930 struct rk3568_cru *cru = priv->cru;
931 int src_clk;
932
933 switch (clk_id) {
934 case ACLK_TOP_HIGH:
935 if (rate == 500 * MHz)
936 src_clk = ACLK_TOP_HIGH_SEL_500M;
937 else if (rate == 400 * MHz)
938 src_clk = ACLK_TOP_HIGH_SEL_400M;
939 else if (rate == 300 * MHz)
940 src_clk = ACLK_TOP_HIGH_SEL_300M;
941 else
942 src_clk = ACLK_TOP_HIGH_SEL_24M;
943 rk_clrsetreg(&cru->clksel_con[73],
944 ACLK_TOP_HIGH_SEL_MASK,
945 src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
946 break;
947 case ACLK_TOP_LOW:
948 if (rate == 400 * MHz)
949 src_clk = ACLK_TOP_LOW_SEL_400M;
950 else if (rate == 300 * MHz)
951 src_clk = ACLK_TOP_LOW_SEL_300M;
952 else if (rate == 200 * MHz)
953 src_clk = ACLK_TOP_LOW_SEL_200M;
954 else
955 src_clk = ACLK_TOP_LOW_SEL_24M;
956 rk_clrsetreg(&cru->clksel_con[73],
957 ACLK_TOP_LOW_SEL_MASK,
958 src_clk << ACLK_TOP_LOW_SEL_SHIFT);
959 break;
960 case HCLK_TOP:
961 if (rate == 150 * MHz)
962 src_clk = HCLK_TOP_SEL_150M;
963 else if (rate == 100 * MHz)
964 src_clk = HCLK_TOP_SEL_100M;
965 else if (rate == 75 * MHz)
966 src_clk = HCLK_TOP_SEL_75M;
967 else
968 src_clk = HCLK_TOP_SEL_24M;
969 rk_clrsetreg(&cru->clksel_con[73],
970 HCLK_TOP_SEL_MASK,
971 src_clk << HCLK_TOP_SEL_SHIFT);
972 break;
973 case PCLK_TOP:
974 if (rate == 100 * MHz)
975 src_clk = PCLK_TOP_SEL_100M;
976 else if (rate == 75 * MHz)
977 src_clk = PCLK_TOP_SEL_75M;
978 else if (rate == 50 * MHz)
979 src_clk = PCLK_TOP_SEL_50M;
980 else
981 src_clk = PCLK_TOP_SEL_24M;
982 rk_clrsetreg(&cru->clksel_con[73],
983 PCLK_TOP_SEL_MASK,
984 src_clk << PCLK_TOP_SEL_SHIFT);
985 break;
986
987 default:
988 printf("do not support this permid freq\n");
989 return -EINVAL;
990 }
991
992 return rk3568_top_get_clk(priv, clk_id);
993}
994
995static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
996{
997 struct rk3568_cru *cru = priv->cru;
998 u32 sel, con;
999 ulong rate;
1000
1001 switch (clk_id) {
1002 case CLK_I2C1:
1003 case CLK_I2C2:
1004 case CLK_I2C3:
1005 case CLK_I2C4:
1006 case CLK_I2C5:
1007 con = readl(&cru->clksel_con[71]);
1008 sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
1009 if (sel == CLK_I2C_SEL_200M)
1010 rate = 200 * MHz;
1011 else if (sel == CLK_I2C_SEL_100M)
1012 rate = 100 * MHz;
1013 else if (sel == CLK_I2C_SEL_CPLL_100M)
1014 rate = 100 * MHz;
1015 else
1016 rate = OSC_HZ;
1017 break;
1018 default:
1019 return -ENOENT;
1020 }
1021
1022 return rate;
1023}
1024
1025static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1026 ulong rate)
1027{
1028 struct rk3568_cru *cru = priv->cru;
1029 int src_clk;
1030
1031 if (rate == 200 * MHz)
1032 src_clk = CLK_I2C_SEL_200M;
1033 else if (rate == 100 * MHz)
1034 src_clk = CLK_I2C_SEL_100M;
1035 else
1036 src_clk = CLK_I2C_SEL_24M;
1037
1038 switch (clk_id) {
1039 case CLK_I2C1:
1040 case CLK_I2C2:
1041 case CLK_I2C3:
1042 case CLK_I2C4:
1043 case CLK_I2C5:
1044 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1045 src_clk << CLK_I2C_SEL_SHIFT);
1046 break;
1047 default:
1048 return -ENOENT;
1049 }
1050
1051 return rk3568_i2c_get_clk(priv, clk_id);
1052}
1053
1054static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1055{
1056 struct rk3568_cru *cru = priv->cru;
1057 u32 sel, con;
1058
1059 con = readl(&cru->clksel_con[72]);
1060
1061 switch (clk_id) {
1062 case CLK_SPI0:
1063 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1064 break;
1065 case CLK_SPI1:
1066 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1067 break;
1068 case CLK_SPI2:
1069 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1070 break;
1071 case CLK_SPI3:
1072 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1073 break;
1074 default:
1075 return -ENOENT;
1076 }
1077
1078 switch (sel) {
1079 case CLK_SPI_SEL_200M:
1080 return 200 * MHz;
1081 case CLK_SPI_SEL_24M:
1082 return OSC_HZ;
1083 case CLK_SPI_SEL_CPLL_100M:
1084 return 100 * MHz;
1085 default:
1086 return -ENOENT;
1087 }
1088}
1089
1090static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1091 ulong clk_id, ulong rate)
1092{
1093 struct rk3568_cru *cru = priv->cru;
1094 int src_clk;
1095
1096 if (rate == 200 * MHz)
1097 src_clk = CLK_SPI_SEL_200M;
1098 else if (rate == 100 * MHz)
1099 src_clk = CLK_SPI_SEL_CPLL_100M;
1100 else
1101 src_clk = CLK_SPI_SEL_24M;
1102
1103 switch (clk_id) {
1104 case CLK_SPI0:
1105 rk_clrsetreg(&cru->clksel_con[72],
1106 CLK_SPI0_SEL_MASK,
1107 src_clk << CLK_SPI0_SEL_SHIFT);
1108 break;
1109 case CLK_SPI1:
1110 rk_clrsetreg(&cru->clksel_con[72],
1111 CLK_SPI1_SEL_MASK,
1112 src_clk << CLK_SPI1_SEL_SHIFT);
1113 break;
1114 case CLK_SPI2:
1115 rk_clrsetreg(&cru->clksel_con[72],
1116 CLK_SPI2_SEL_MASK,
1117 src_clk << CLK_SPI2_SEL_SHIFT);
1118 break;
1119 case CLK_SPI3:
1120 rk_clrsetreg(&cru->clksel_con[72],
1121 CLK_SPI3_SEL_MASK,
1122 src_clk << CLK_SPI3_SEL_SHIFT);
1123 break;
1124 default:
1125 return -ENOENT;
1126 }
1127
1128 return rk3568_spi_get_clk(priv, clk_id);
1129}
1130
1131static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1132{
1133 struct rk3568_cru *cru = priv->cru;
1134 u32 sel, con;
1135
1136 con = readl(&cru->clksel_con[72]);
1137
1138 switch (clk_id) {
1139 case CLK_PWM1:
1140 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1141 break;
1142 case CLK_PWM2:
1143 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1144 break;
1145 case CLK_PWM3:
1146 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1147 break;
1148 default:
1149 return -ENOENT;
1150 }
1151
1152 switch (sel) {
1153 case CLK_PWM_SEL_100M:
1154 return 100 * MHz;
1155 case CLK_PWM_SEL_24M:
1156 return OSC_HZ;
1157 case CLK_PWM_SEL_CPLL_100M:
1158 return 100 * MHz;
1159 default:
1160 return -ENOENT;
1161 }
1162}
1163
1164static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1165 ulong clk_id, ulong rate)
1166{
1167 struct rk3568_cru *cru = priv->cru;
1168 int src_clk;
1169
1170 if (rate == 100 * MHz)
1171 src_clk = CLK_PWM_SEL_100M;
1172 else
1173 src_clk = CLK_PWM_SEL_24M;
1174
1175 switch (clk_id) {
1176 case CLK_PWM1:
1177 rk_clrsetreg(&cru->clksel_con[72],
1178 CLK_PWM1_SEL_MASK,
1179 src_clk << CLK_PWM1_SEL_SHIFT);
1180 break;
1181 case CLK_PWM2:
1182 rk_clrsetreg(&cru->clksel_con[72],
1183 CLK_PWM2_SEL_MASK,
1184 src_clk << CLK_PWM2_SEL_SHIFT);
1185 break;
1186 case CLK_PWM3:
1187 rk_clrsetreg(&cru->clksel_con[72],
1188 CLK_PWM3_SEL_MASK,
1189 src_clk << CLK_PWM3_SEL_SHIFT);
1190 break;
1191 default:
1192 return -ENOENT;
1193 }
1194
1195 return rk3568_pwm_get_clk(priv, clk_id);
1196}
1197
1198static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1199{
1200 struct rk3568_cru *cru = priv->cru;
1201 u32 div, sel, con, prate;
1202
1203 switch (clk_id) {
1204 case CLK_SARADC:
1205 return OSC_HZ;
1206 case CLK_TSADC_TSEN:
1207 con = readl(&cru->clksel_con[51]);
1208 div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
1209 CLK_TSADC_TSEN_DIV_SHIFT;
1210 sel = (con & CLK_TSADC_TSEN_SEL_MASK) >>
1211 CLK_TSADC_TSEN_SEL_SHIFT;
1212 if (sel == CLK_TSADC_TSEN_SEL_24M)
1213 prate = OSC_HZ;
1214 else
1215 prate = 100 * MHz;
1216 return DIV_TO_RATE(prate, div);
1217 case CLK_TSADC:
1218 con = readl(&cru->clksel_con[51]);
1219 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
1220 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1221 return DIV_TO_RATE(prate, div);
1222 default:
1223 return -ENOENT;
1224 }
1225}
1226
1227static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1228 ulong clk_id, ulong rate)
1229{
1230 struct rk3568_cru *cru = priv->cru;
1231 int src_clk_div;
1232 ulong prate = 0;
1233
1234 switch (clk_id) {
1235 case CLK_SARADC:
1236 return OSC_HZ;
1237 case CLK_TSADC_TSEN:
1238 if (!(OSC_HZ % rate)) {
1239 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
1240 assert(src_clk_div - 1 <= 7);
1241 rk_clrsetreg(&cru->clksel_con[51],
1242 CLK_TSADC_TSEN_SEL_MASK |
1243 CLK_TSADC_TSEN_DIV_MASK,
1244 (CLK_TSADC_TSEN_SEL_24M <<
1245 CLK_TSADC_TSEN_SEL_SHIFT) |
1246 (src_clk_div - 1) <<
1247 CLK_TSADC_TSEN_DIV_SHIFT);
1248 } else {
1249 src_clk_div = DIV_ROUND_UP(100 * MHz, rate);
1250 assert(src_clk_div - 1 <= 7);
1251 rk_clrsetreg(&cru->clksel_con[51],
1252 CLK_TSADC_TSEN_SEL_MASK |
1253 CLK_TSADC_TSEN_DIV_MASK,
1254 (CLK_TSADC_TSEN_SEL_100M <<
1255 CLK_TSADC_TSEN_SEL_SHIFT) |
1256 (src_clk_div - 1) <<
1257 CLK_TSADC_TSEN_DIV_SHIFT);
1258 }
1259 break;
1260 case CLK_TSADC:
1261 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1262 src_clk_div = DIV_ROUND_UP(prate, rate);
1263 assert(src_clk_div - 1 <= 128);
1264 rk_clrsetreg(&cru->clksel_con[51],
1265 CLK_TSADC_DIV_MASK,
1266 (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1267 break;
1268 default:
1269 return -ENOENT;
1270 }
1271 return rk3568_adc_get_clk(priv, clk_id);
1272}
1273
1274static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1275{
1276 struct rk3568_cru *cru = priv->cru;
1277 u32 sel, con;
1278
1279 switch (clk_id) {
1280 case ACLK_SECURE_FLASH:
1281 case ACLK_CRYPTO_NS:
1282 con = readl(&cru->clksel_con[27]);
1283 sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >>
1284 ACLK_SECURE_FLASH_SEL_SHIFT;
1285 if (sel == ACLK_SECURE_FLASH_SEL_200M)
1286 return 200 * MHz;
1287 else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1288 return 150 * MHz;
1289 else if (sel == ACLK_SECURE_FLASH_SEL_100M)
1290 return 100 * MHz;
1291 else
1292 return 24 * MHz;
1293 case HCLK_SECURE_FLASH:
1294 case HCLK_CRYPTO_NS:
1295 case CLK_CRYPTO_NS_RNG:
1296 con = readl(&cru->clksel_con[27]);
1297 sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >>
1298 HCLK_SECURE_FLASH_SEL_SHIFT;
1299 if (sel == HCLK_SECURE_FLASH_SEL_150M)
1300 return 150 * MHz;
1301 else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1302 return 100 * MHz;
1303 else if (sel == HCLK_SECURE_FLASH_SEL_75M)
1304 return 75 * MHz;
1305 else
1306 return 24 * MHz;
1307 case CLK_CRYPTO_NS_CORE:
1308 con = readl(&cru->clksel_con[27]);
1309 sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >>
1310 CLK_CRYPTO_CORE_SEL_SHIFT;
1311 if (sel == CLK_CRYPTO_CORE_SEL_200M)
1312 return 200 * MHz;
1313 else if (sel == CLK_CRYPTO_CORE_SEL_150M)
1314 return 150 * MHz;
1315 else
1316 return 100 * MHz;
1317 case CLK_CRYPTO_NS_PKA:
1318 con = readl(&cru->clksel_con[27]);
1319 sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >>
1320 CLK_CRYPTO_PKA_SEL_SHIFT;
1321 if (sel == CLK_CRYPTO_PKA_SEL_300M)
1322 return 300 * MHz;
1323 else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1324 return 200 * MHz;
1325 else
1326 return 100 * MHz;
1327 default:
1328 return -ENOENT;
1329 }
1330}
1331
1332static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1333 ulong clk_id, ulong rate)
1334{
1335 struct rk3568_cru *cru = priv->cru;
1336 u32 src_clk, mask, shift;
1337
1338 switch (clk_id) {
1339 case ACLK_SECURE_FLASH:
1340 case ACLK_CRYPTO_NS:
1341 mask = ACLK_SECURE_FLASH_SEL_MASK;
1342 shift = ACLK_SECURE_FLASH_SEL_SHIFT;
1343 if (rate == 200 * MHz)
1344 src_clk = ACLK_SECURE_FLASH_SEL_200M;
1345 else if (rate == 150 * MHz)
1346 src_clk = ACLK_SECURE_FLASH_SEL_150M;
1347 else if (rate == 100 * MHz)
1348 src_clk = ACLK_SECURE_FLASH_SEL_100M;
1349 else
1350 src_clk = ACLK_SECURE_FLASH_SEL_24M;
1351 break;
1352 case HCLK_SECURE_FLASH:
1353 case HCLK_CRYPTO_NS:
1354 case CLK_CRYPTO_NS_RNG:
1355 mask = HCLK_SECURE_FLASH_SEL_MASK;
1356 shift = HCLK_SECURE_FLASH_SEL_SHIFT;
1357 if (rate == 150 * MHz)
1358 src_clk = HCLK_SECURE_FLASH_SEL_150M;
1359 else if (rate == 100 * MHz)
1360 src_clk = HCLK_SECURE_FLASH_SEL_100M;
1361 else if (rate == 75 * MHz)
1362 src_clk = HCLK_SECURE_FLASH_SEL_75M;
1363 else
1364 src_clk = HCLK_SECURE_FLASH_SEL_24M;
1365 break;
1366 case CLK_CRYPTO_NS_CORE:
1367 mask = CLK_CRYPTO_CORE_SEL_MASK;
1368 shift = CLK_CRYPTO_CORE_SEL_SHIFT;
1369 if (rate == 200 * MHz)
1370 src_clk = CLK_CRYPTO_CORE_SEL_200M;
1371 else if (rate == 150 * MHz)
1372 src_clk = CLK_CRYPTO_CORE_SEL_150M;
1373 else
1374 src_clk = CLK_CRYPTO_CORE_SEL_100M;
1375 break;
1376 case CLK_CRYPTO_NS_PKA:
1377 mask = CLK_CRYPTO_PKA_SEL_MASK;
1378 shift = CLK_CRYPTO_PKA_SEL_SHIFT;
1379 if (rate == 300 * MHz)
1380 src_clk = CLK_CRYPTO_PKA_SEL_300M;
1381 else if (rate == 200 * MHz)
1382 src_clk = CLK_CRYPTO_PKA_SEL_200M;
1383 else
1384 src_clk = CLK_CRYPTO_PKA_SEL_100M;
1385 break;
1386 default:
1387 return -ENOENT;
1388 }
1389
1390 rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1391
1392 return rk3568_crypto_get_rate(priv, clk_id);
1393}
1394
1395static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1396{
1397 struct rk3568_cru *cru = priv->cru;
1398 u32 sel, con;
1399
1400 switch (clk_id) {
1401 case HCLK_SDMMC0:
1402 case CLK_SDMMC0:
1403 con = readl(&cru->clksel_con[30]);
1404 sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1405 break;
1406 case CLK_SDMMC1:
1407 con = readl(&cru->clksel_con[30]);
1408 sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1409 break;
1410 case CLK_SDMMC2:
1411 con = readl(&cru->clksel_con[32]);
1412 sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1413 break;
1414 default:
1415 return -ENOENT;
1416 }
1417
1418 switch (sel) {
1419 case CLK_SDMMC_SEL_24M:
1420 return OSC_HZ;
1421 case CLK_SDMMC_SEL_400M:
1422 return 400 * MHz;
1423 case CLK_SDMMC_SEL_300M:
1424 return 300 * MHz;
1425 case CLK_SDMMC_SEL_100M:
1426 return 100 * MHz;
1427 case CLK_SDMMC_SEL_50M:
1428 return 50 * MHz;
1429 case CLK_SDMMC_SEL_750K:
1430 return 750 * KHz;
1431 default:
1432 return -ENOENT;
1433 }
1434}
1435
1436static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1437 ulong clk_id, ulong rate)
1438{
1439 struct rk3568_cru *cru = priv->cru;
1440 int src_clk;
1441
1442 switch (rate) {
1443 case OSC_HZ:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001444 case 26 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001445 src_clk = CLK_SDMMC_SEL_24M;
1446 break;
1447 case 400 * MHz:
1448 src_clk = CLK_SDMMC_SEL_400M;
1449 break;
1450 case 300 * MHz:
1451 src_clk = CLK_SDMMC_SEL_300M;
1452 break;
1453 case 100 * MHz:
1454 src_clk = CLK_SDMMC_SEL_100M;
1455 break;
1456 case 52 * MHz:
1457 case 50 * MHz:
1458 src_clk = CLK_SDMMC_SEL_50M;
1459 break;
1460 case 750 * KHz:
1461 case 400 * KHz:
1462 src_clk = CLK_SDMMC_SEL_750K;
1463 break;
1464 default:
1465 return -ENOENT;
1466 }
1467
1468 switch (clk_id) {
1469 case HCLK_SDMMC0:
1470 case CLK_SDMMC0:
1471 rk_clrsetreg(&cru->clksel_con[30],
1472 CLK_SDMMC0_SEL_MASK,
1473 src_clk << CLK_SDMMC0_SEL_SHIFT);
1474 break;
1475 case CLK_SDMMC1:
1476 rk_clrsetreg(&cru->clksel_con[30],
1477 CLK_SDMMC1_SEL_MASK,
1478 src_clk << CLK_SDMMC1_SEL_SHIFT);
1479 break;
1480 case CLK_SDMMC2:
1481 rk_clrsetreg(&cru->clksel_con[32],
1482 CLK_SDMMC2_SEL_MASK,
1483 src_clk << CLK_SDMMC2_SEL_SHIFT);
1484 break;
1485 default:
1486 return -ENOENT;
1487 }
1488
1489 return rk3568_sdmmc_get_clk(priv, clk_id);
1490}
1491
1492static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1493{
1494 struct rk3568_cru *cru = priv->cru;
1495 u32 sel, con;
1496
1497 con = readl(&cru->clksel_con[28]);
1498 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1499 switch (sel) {
1500 case SCLK_SFC_SEL_24M:
1501 return OSC_HZ;
1502 case SCLK_SFC_SEL_50M:
1503 return 50 * MHz;
1504 case SCLK_SFC_SEL_75M:
1505 return 75 * MHz;
1506 case SCLK_SFC_SEL_100M:
1507 return 100 * MHz;
1508 case SCLK_SFC_SEL_125M:
1509 return 125 * MHz;
1510 case SCLK_SFC_SEL_150M:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001511 return 150 * MHz;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001512 default:
1513 return -ENOENT;
1514 }
1515}
1516
1517static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1518{
1519 struct rk3568_cru *cru = priv->cru;
1520 int src_clk;
1521
1522 switch (rate) {
1523 case OSC_HZ:
1524 src_clk = SCLK_SFC_SEL_24M;
1525 break;
1526 case 50 * MHz:
1527 src_clk = SCLK_SFC_SEL_50M;
1528 break;
1529 case 75 * MHz:
1530 src_clk = SCLK_SFC_SEL_75M;
1531 break;
1532 case 100 * MHz:
1533 src_clk = SCLK_SFC_SEL_100M;
1534 break;
1535 case 125 * MHz:
1536 src_clk = SCLK_SFC_SEL_125M;
1537 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001538 case 150 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001539 src_clk = SCLK_SFC_SEL_150M;
1540 break;
1541 default:
1542 return -ENOENT;
1543 }
1544
1545 rk_clrsetreg(&cru->clksel_con[28],
1546 SCLK_SFC_SEL_MASK,
1547 src_clk << SCLK_SFC_SEL_SHIFT);
1548
1549 return rk3568_sfc_get_clk(priv);
1550}
1551
1552static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1553{
1554 struct rk3568_cru *cru = priv->cru;
1555 u32 sel, con;
1556
1557 con = readl(&cru->clksel_con[28]);
1558 sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1559 switch (sel) {
1560 case NCLK_NANDC_SEL_200M:
1561 return 200 * MHz;
1562 case NCLK_NANDC_SEL_150M:
1563 return 150 * MHz;
1564 case NCLK_NANDC_SEL_100M:
1565 return 100 * MHz;
1566 case NCLK_NANDC_SEL_24M:
1567 return OSC_HZ;
1568 default:
1569 return -ENOENT;
1570 }
1571}
1572
1573static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1574{
1575 struct rk3568_cru *cru = priv->cru;
1576 int src_clk;
1577
1578 switch (rate) {
1579 case OSC_HZ:
1580 src_clk = NCLK_NANDC_SEL_24M;
1581 break;
1582 case 100 * MHz:
1583 src_clk = NCLK_NANDC_SEL_100M;
1584 break;
1585 case 150 * MHz:
1586 src_clk = NCLK_NANDC_SEL_150M;
1587 break;
1588 case 200 * MHz:
1589 src_clk = NCLK_NANDC_SEL_200M;
1590 break;
1591 default:
1592 return -ENOENT;
1593 }
1594
1595 rk_clrsetreg(&cru->clksel_con[28],
1596 NCLK_NANDC_SEL_MASK,
1597 src_clk << NCLK_NANDC_SEL_SHIFT);
1598
1599 return rk3568_nand_get_clk(priv);
1600}
1601
1602static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1603{
1604 struct rk3568_cru *cru = priv->cru;
1605 u32 sel, con;
1606
1607 con = readl(&cru->clksel_con[28]);
1608 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1609 switch (sel) {
1610 case CCLK_EMMC_SEL_200M:
1611 return 200 * MHz;
1612 case CCLK_EMMC_SEL_150M:
1613 return 150 * MHz;
1614 case CCLK_EMMC_SEL_100M:
1615 return 100 * MHz;
1616 case CCLK_EMMC_SEL_50M:
1617 return 50 * MHz;
1618 case CCLK_EMMC_SEL_375K:
1619 return 375 * KHz;
1620 case CCLK_EMMC_SEL_24M:
1621 return OSC_HZ;
1622 default:
1623 return -ENOENT;
1624 }
1625}
1626
1627static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1628{
1629 struct rk3568_cru *cru = priv->cru;
1630 int src_clk;
1631
1632 switch (rate) {
1633 case OSC_HZ:
1634 src_clk = CCLK_EMMC_SEL_24M;
1635 break;
1636 case 52 * MHz:
1637 case 50 * MHz:
1638 src_clk = CCLK_EMMC_SEL_50M;
1639 break;
1640 case 100 * MHz:
1641 src_clk = CCLK_EMMC_SEL_100M;
1642 break;
1643 case 150 * MHz:
1644 src_clk = CCLK_EMMC_SEL_150M;
1645 break;
1646 case 200 * MHz:
1647 src_clk = CCLK_EMMC_SEL_200M;
1648 break;
1649 case 400 * KHz:
1650 case 375 * KHz:
1651 src_clk = CCLK_EMMC_SEL_375K;
1652 break;
1653 default:
1654 return -ENOENT;
1655 }
1656
1657 rk_clrsetreg(&cru->clksel_con[28],
1658 CCLK_EMMC_SEL_MASK,
1659 src_clk << CCLK_EMMC_SEL_SHIFT);
1660
1661 return rk3568_emmc_get_clk(priv);
1662}
1663
1664static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1665{
1666 struct rk3568_cru *cru = priv->cru;
1667 u32 sel, con;
1668
1669 con = readl(&cru->clksel_con[28]);
1670 sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1671 switch (sel) {
1672 case BCLK_EMMC_SEL_200M:
1673 return 200 * MHz;
1674 case BCLK_EMMC_SEL_150M:
1675 return 150 * MHz;
1676 case BCLK_EMMC_SEL_125M:
1677 return 125 * MHz;
1678 default:
1679 return -ENOENT;
1680 }
1681}
1682
1683static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1684{
1685 struct rk3568_cru *cru = priv->cru;
1686 int src_clk;
1687
1688 switch (rate) {
1689 case 200 * MHz:
1690 src_clk = BCLK_EMMC_SEL_200M;
1691 break;
1692 case 150 * MHz:
1693 src_clk = BCLK_EMMC_SEL_150M;
1694 break;
1695 case 125 * MHz:
1696 src_clk = BCLK_EMMC_SEL_125M;
1697 break;
1698 default:
1699 return -ENOENT;
1700 }
1701
1702 rk_clrsetreg(&cru->clksel_con[28],
1703 BCLK_EMMC_SEL_MASK,
1704 src_clk << BCLK_EMMC_SEL_SHIFT);
1705
1706 return rk3568_emmc_get_bclk(priv);
1707}
1708
1709#ifndef CONFIG_SPL_BUILD
1710static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1711{
1712 struct rk3568_cru *cru = priv->cru;
1713 u32 div, sel, con, parent;
1714
1715 con = readl(&cru->clksel_con[38]);
1716 div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1717 sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1718 if (sel == ACLK_VOP_PRE_SEL_GPLL)
1719 parent = priv->gpll_hz;
1720 else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1721 parent = priv->cpll_hz;
1722 else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1723 parent = priv->vpll_hz;
1724 else
1725 parent = priv->hpll_hz;
1726
1727 return DIV_TO_RATE(parent, div);
1728}
1729
1730static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1731{
1732 struct rk3568_cru *cru = priv->cru;
1733 int src_clk_div, src_clk_mux;
1734
1735 if ((priv->cpll_hz % rate) == 0) {
1736 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1737 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1738 } else {
1739 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1740 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1741 }
1742 assert(src_clk_div - 1 <= 31);
1743 rk_clrsetreg(&cru->clksel_con[38],
1744 ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1745 src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1746 (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1747
1748 return rk3568_aclk_vop_get_clk(priv);
1749}
1750
1751static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1752{
1753 struct rk3568_cru *cru = priv->cru;
1754 u32 conid, div, sel, con, parent;
1755
1756 switch (clk_id) {
1757 case DCLK_VOP0:
1758 conid = 39;
1759 break;
1760 case DCLK_VOP1:
1761 conid = 40;
1762 break;
1763 case DCLK_VOP2:
1764 conid = 41;
1765 break;
1766 default:
1767 return -ENOENT;
1768 }
1769
1770 con = readl(&cru->clksel_con[conid]);
1771 div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1772 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1773 if (sel == DCLK_VOP_SEL_HPLL)
1774 parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1775 else if (sel == DCLK_VOP_SEL_VPLL)
1776 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1777 priv->cru, VPLL);
1778 else if (sel == DCLK_VOP_SEL_GPLL)
1779 parent = priv->gpll_hz;
1780 else if (sel == DCLK_VOP_SEL_CPLL)
1781 parent = priv->cpll_hz;
1782 else
1783 return -ENOENT;
1784
1785 return DIV_TO_RATE(parent, div);
1786}
1787
1788#define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1789
1790static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1791 ulong clk_id, ulong rate)
1792{
1793 struct rk3568_cru *cru = priv->cru;
1794 ulong pll_rate, now, best_rate = 0;
1795 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1796
1797 switch (clk_id) {
1798 case DCLK_VOP0:
1799 conid = 39;
1800 break;
1801 case DCLK_VOP1:
1802 conid = 40;
1803 break;
1804 case DCLK_VOP2:
1805 conid = 41;
1806 break;
1807 default:
1808 return -ENOENT;
1809 }
1810
1811 con = readl(&cru->clksel_con[conid]);
1812 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1813
1814 if (sel == DCLK_VOP_SEL_HPLL) {
1815 div = 1;
1816 rk_clrsetreg(&cru->clksel_con[conid],
1817 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1818 (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1819 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1820 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1821 } else if (sel == DCLK_VOP_SEL_VPLL) {
1822 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1823 rk_clrsetreg(&cru->clksel_con[conid],
1824 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1825 (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1826 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1827 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1828 priv->cru, VPLL, div * rate);
1829 } else {
1830 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1831 switch (i) {
1832 case DCLK_VOP_SEL_GPLL:
1833 pll_rate = priv->gpll_hz;
1834 break;
1835 case DCLK_VOP_SEL_CPLL:
1836 pll_rate = priv->cpll_hz;
1837 break;
1838 default:
1839 printf("do not support this vop pll sel\n");
1840 return -EINVAL;
1841 }
1842
1843 div = DIV_ROUND_UP(pll_rate, rate);
1844 if (div > 255)
1845 continue;
1846 now = pll_rate / div;
1847 if (abs(rate - now) < abs(rate - best_rate)) {
1848 best_rate = now;
1849 best_div = div;
1850 best_sel = i;
1851 }
1852 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1853 pll_rate, best_rate, best_div, best_sel);
1854 }
1855
1856 if (best_rate) {
1857 rk_clrsetreg(&cru->clksel_con[conid],
1858 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1859 best_sel << DCLK0_VOP_SEL_SHIFT |
1860 (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1861 } else {
1862 printf("do not support this vop freq %lu\n", rate);
1863 return -EINVAL;
1864 }
1865 }
1866 return rk3568_dclk_vop_get_clk(priv, clk_id);
1867}
1868
1869static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1870 ulong mac_id)
1871{
1872 struct rk3568_cru *cru = priv->cru;
1873 u32 sel, con;
1874
1875 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1876 sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1877
1878 switch (sel) {
1879 case CLK_MAC0_2TOP_SEL_125M:
1880 return 125 * MHz;
1881 case CLK_MAC0_2TOP_SEL_50M:
1882 return 50 * MHz;
1883 case CLK_MAC0_2TOP_SEL_25M:
1884 return 25 * MHz;
1885 case CLK_MAC0_2TOP_SEL_PPLL:
1886 return rk3568_pmu_pll_get_rate(priv, HPLL);
1887 default:
1888 return -ENOENT;
1889 }
1890}
1891
1892static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1893 ulong mac_id, ulong rate)
1894{
1895 struct rk3568_cru *cru = priv->cru;
1896 int src_clk;
1897
1898 switch (rate) {
1899 case 125 * MHz:
1900 src_clk = CLK_MAC0_2TOP_SEL_125M;
1901 break;
1902 case 50 * MHz:
1903 src_clk = CLK_MAC0_2TOP_SEL_50M;
1904 break;
1905 case 25 * MHz:
1906 src_clk = CLK_MAC0_2TOP_SEL_25M;
1907 break;
1908 default:
1909 return -ENOENT;
1910 }
1911
1912 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1913 CLK_MAC0_2TOP_SEL_MASK,
1914 src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1915
1916 return rk3568_gmac_src_get_clk(priv, mac_id);
1917}
1918
1919static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1920 ulong mac_id)
1921{
1922 struct rk3568_cru *cru = priv->cru;
1923 u32 sel, con;
1924
1925 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1926 sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1927
1928 switch (sel) {
1929 case CLK_MAC0_OUT_SEL_125M:
1930 return 125 * MHz;
1931 case CLK_MAC0_OUT_SEL_50M:
1932 return 50 * MHz;
1933 case CLK_MAC0_OUT_SEL_25M:
1934 return 25 * MHz;
1935 case CLK_MAC0_OUT_SEL_24M:
1936 return OSC_HZ;
1937 default:
1938 return -ENOENT;
1939 }
1940}
1941
1942static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1943 ulong mac_id, ulong rate)
1944{
1945 struct rk3568_cru *cru = priv->cru;
1946 int src_clk;
1947
1948 switch (rate) {
1949 case 125 * MHz:
1950 src_clk = CLK_MAC0_OUT_SEL_125M;
1951 break;
1952 case 50 * MHz:
1953 src_clk = CLK_MAC0_OUT_SEL_50M;
1954 break;
1955 case 25 * MHz:
1956 src_clk = CLK_MAC0_OUT_SEL_25M;
1957 break;
1958 case 24 * MHz:
1959 src_clk = CLK_MAC0_OUT_SEL_24M;
1960 break;
1961 default:
1962 return -ENOENT;
1963 }
1964
1965 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1966 CLK_MAC0_OUT_SEL_MASK,
1967 src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1968
1969 return rk3568_gmac_out_get_clk(priv, mac_id);
1970}
1971
1972static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1973 ulong mac_id)
1974{
1975 struct rk3568_cru *cru = priv->cru;
1976 u32 sel, con;
1977
1978 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1979 sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1980
1981 switch (sel) {
1982 case CLK_GMAC0_PTP_REF_SEL_62_5M:
1983 return 62500 * KHz;
1984 case CLK_GMAC0_PTP_REF_SEL_100M:
1985 return 100 * MHz;
1986 case CLK_GMAC0_PTP_REF_SEL_50M:
1987 return 50 * MHz;
1988 case CLK_GMAC0_PTP_REF_SEL_24M:
1989 return OSC_HZ;
1990 default:
1991 return -ENOENT;
1992 }
1993}
1994
1995static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1996 ulong mac_id, ulong rate)
1997{
1998 struct rk3568_cru *cru = priv->cru;
1999 int src_clk;
2000
2001 switch (rate) {
2002 case 62500 * KHz:
2003 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2004 break;
2005 case 100 * MHz:
2006 src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2007 break;
2008 case 50 * MHz:
2009 src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2010 break;
2011 case 24 * MHz:
2012 src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2013 break;
2014 default:
2015 return -ENOENT;
2016 }
2017
2018 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2019 CLK_GMAC0_PTP_REF_SEL_MASK,
2020 src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2021
2022 return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2023}
2024
2025static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2026 ulong mac_id, ulong rate)
2027{
2028 struct rk3568_cru *cru = priv->cru;
2029 u32 con, sel, div_sel;
2030
2031 con = readl(&cru->clksel_con[31 + mac_id * 2]);
2032 sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2033
2034 if (sel == RMII0_MODE_SEL_RGMII) {
2035 if (rate == 2500000)
2036 div_sel = RGMII0_CLK_SEL_2_5M;
2037 else if (rate == 25000000)
2038 div_sel = RGMII0_CLK_SEL_25M;
2039 else
2040 div_sel = RGMII0_CLK_SEL_125M;
2041 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2042 RGMII0_CLK_SEL_MASK,
2043 div_sel << RGMII0_CLK_SEL_SHIFT);
2044 } else if (sel == RMII0_MODE_SEL_RMII) {
2045 if (rate == 2500000)
2046 div_sel = RMII0_CLK_SEL_2_5M;
2047 else
2048 div_sel = RMII0_CLK_SEL_25M;
2049 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2050 RMII0_CLK_SEL_MASK,
2051 div_sel << RMII0_CLK_SEL_SHIFT);
2052 }
2053
2054 return 0;
2055}
2056
2057static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2058{
2059 struct rk3568_cru *cru = priv->cru;
2060 u32 con, div, p_rate;
2061
2062 con = readl(&cru->clksel_con[79]);
2063 div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2064 p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2065
2066 con = readl(&cru->clksel_con[43]);
2067 div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2068 switch (div) {
2069 case DCLK_EBC_SEL_GPLL_400M:
2070 return 400 * MHz;
2071 case DCLK_EBC_SEL_CPLL_333M:
2072 return p_rate;
2073 case DCLK_EBC_SEL_GPLL_200M:
2074 return 200 * MHz;
2075 default:
2076 return -ENOENT;
2077 }
2078}
2079
2080static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2081{
2082 struct rk3568_cru *cru = priv->cru;
2083 int src_clk_div;
2084
2085 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2086 assert(src_clk_div - 1 <= 31);
2087 rk_clrsetreg(&cru->clksel_con[79],
2088 CPLL_333M_DIV_MASK,
2089 (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2090 rk_clrsetreg(&cru->clksel_con[43],
2091 DCLK_EBC_SEL_MASK,
2092 DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2093
2094 return rk3568_ebc_get_clk(priv);
2095}
2096
2097static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2098{
2099 struct rk3568_cru *cru = priv->cru;
2100 u32 con, div, src, p_rate;
2101
2102 switch (clk_id) {
2103 case ACLK_RKVDEC_PRE:
2104 case ACLK_RKVDEC:
2105 con = readl(&cru->clksel_con[47]);
2106 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2107 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2108 if (src == ACLK_RKVDEC_SEL_CPLL)
2109 p_rate = priv->cpll_hz;
2110 else
2111 p_rate = priv->gpll_hz;
2112 return DIV_TO_RATE(p_rate, div);
2113 case CLK_RKVDEC_CORE:
2114 con = readl(&cru->clksel_con[49]);
2115 src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2116 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2117 div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2118 >> CLK_RKVDEC_CORE_DIV_SHIFT;
2119 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2120 p_rate = priv->cpll_hz;
2121 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2122 p_rate = priv->npll_hz;
2123 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2124 p_rate = priv->vpll_hz;
2125 else
2126 p_rate = priv->gpll_hz;
2127 return DIV_TO_RATE(p_rate, div);
2128 default:
2129 return -ENOENT;
2130 }
2131}
2132
2133static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2134 ulong clk_id, ulong rate)
2135{
2136 struct rk3568_cru *cru = priv->cru;
2137 int src_clk_div, src, p_rate;
2138
2139 switch (clk_id) {
2140 case ACLK_RKVDEC_PRE:
2141 case ACLK_RKVDEC:
2142 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2143 >> ACLK_RKVDEC_SEL_SHIFT;
2144 if (src == ACLK_RKVDEC_SEL_CPLL)
2145 p_rate = priv->cpll_hz;
2146 else
2147 p_rate = priv->gpll_hz;
2148 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2149 assert(src_clk_div - 1 <= 31);
2150 rk_clrsetreg(&cru->clksel_con[47],
2151 ACLK_RKVDEC_SEL_MASK |
2152 ACLK_RKVDEC_DIV_MASK,
2153 (src << ACLK_RKVDEC_SEL_SHIFT) |
2154 (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2155 break;
2156 case CLK_RKVDEC_CORE:
2157 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2158 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2159 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2160 p_rate = priv->cpll_hz;
2161 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2162 p_rate = priv->npll_hz;
2163 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2164 p_rate = priv->vpll_hz;
2165 else
2166 p_rate = priv->gpll_hz;
2167 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2168 assert(src_clk_div - 1 <= 31);
2169 rk_clrsetreg(&cru->clksel_con[49],
2170 CLK_RKVDEC_CORE_SEL_MASK |
2171 CLK_RKVDEC_CORE_DIV_MASK,
2172 (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2173 (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2174 break;
2175 default:
2176 return -ENOENT;
2177 }
2178
2179 return rk3568_rkvdec_get_clk(priv, clk_id);
2180}
2181
2182static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2183{
2184 struct rk3568_cru *cru = priv->cru;
2185 u32 reg, con, fracdiv, div, src, p_src, p_rate;
2186 unsigned long m, n;
2187
2188 switch (clk_id) {
2189 case SCLK_UART1:
2190 reg = 52;
2191 break;
2192 case SCLK_UART2:
2193 reg = 54;
2194 break;
2195 case SCLK_UART3:
2196 reg = 56;
2197 break;
2198 case SCLK_UART4:
2199 reg = 58;
2200 break;
2201 case SCLK_UART5:
2202 reg = 60;
2203 break;
2204 case SCLK_UART6:
2205 reg = 62;
2206 break;
2207 case SCLK_UART7:
2208 reg = 64;
2209 break;
2210 case SCLK_UART8:
2211 reg = 66;
2212 break;
2213 case SCLK_UART9:
2214 reg = 68;
2215 break;
2216 default:
2217 return -ENOENT;
2218 }
2219 con = readl(&cru->clksel_con[reg]);
2220 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2221 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2222 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2223 if (p_src == CLK_UART_SRC_SEL_GPLL)
2224 p_rate = priv->gpll_hz;
2225 else if (p_src == CLK_UART_SRC_SEL_CPLL)
2226 p_rate = priv->cpll_hz;
2227 else
2228 p_rate = 480000000;
2229 if (src == CLK_UART_SEL_SRC) {
2230 return DIV_TO_RATE(p_rate, div);
2231 } else if (src == CLK_UART_SEL_FRAC) {
2232 fracdiv = readl(&cru->clksel_con[reg + 1]);
2233 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2234 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2235 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2236 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2237 return DIV_TO_RATE(p_rate, div) * n / m;
2238 } else {
2239 return OSC_HZ;
2240 }
2241}
2242
2243static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2244 ulong clk_id, ulong rate)
2245{
2246 struct rk3568_cru *cru = priv->cru;
2247 u32 reg, clk_src, uart_src, div;
2248 unsigned long m = 0, n = 0, val;
2249
2250 if (priv->gpll_hz % rate == 0) {
2251 clk_src = CLK_UART_SRC_SEL_GPLL;
2252 uart_src = CLK_UART_SEL_SRC;
2253 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2254 } else if (priv->cpll_hz % rate == 0) {
2255 clk_src = CLK_UART_SRC_SEL_CPLL;
2256 uart_src = CLK_UART_SEL_SRC;
2257 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2258 } else if (rate == OSC_HZ) {
2259 clk_src = CLK_UART_SRC_SEL_GPLL;
2260 uart_src = CLK_UART_SEL_XIN24M;
2261 div = 2;
2262 } else {
2263 clk_src = CLK_UART_SRC_SEL_GPLL;
2264 uart_src = CLK_UART_SEL_FRAC;
2265 div = 2;
2266 rational_best_approximation(rate, priv->gpll_hz / div,
2267 GENMASK(16 - 1, 0),
2268 GENMASK(16 - 1, 0),
2269 &m, &n);
2270 }
2271
2272 switch (clk_id) {
2273 case SCLK_UART1:
2274 reg = 52;
2275 break;
2276 case SCLK_UART2:
2277 reg = 54;
2278 break;
2279 case SCLK_UART3:
2280 reg = 56;
2281 break;
2282 case SCLK_UART4:
2283 reg = 58;
2284 break;
2285 case SCLK_UART5:
2286 reg = 60;
2287 break;
2288 case SCLK_UART6:
2289 reg = 62;
2290 break;
2291 case SCLK_UART7:
2292 reg = 64;
2293 break;
2294 case SCLK_UART8:
2295 reg = 66;
2296 break;
2297 case SCLK_UART9:
2298 reg = 68;
2299 break;
2300 default:
2301 return -ENOENT;
2302 }
2303 rk_clrsetreg(&cru->clksel_con[reg],
2304 CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2305 CLK_UART_SRC_DIV_MASK,
2306 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2307 (uart_src << CLK_UART_SEL_SHIFT) |
2308 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2309 if (m && n) {
2310 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2311 writel(val, &cru->clksel_con[reg + 1]);
2312 }
2313
2314 return rk3568_uart_get_rate(priv, clk_id);
2315}
2316#endif
2317
2318static ulong rk3568_clk_get_rate(struct clk *clk)
2319{
2320 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2321 ulong rate = 0;
2322
2323 if (!priv->gpll_hz) {
2324 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2325 return -ENOENT;
2326 }
2327
2328 switch (clk->id) {
2329 case PLL_APLL:
2330 case ARMCLK:
2331 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2332 APLL);
2333 break;
2334 case PLL_CPLL:
2335 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2336 CPLL);
2337 break;
2338 case PLL_GPLL:
2339 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2340 GPLL);
2341 break;
2342 case PLL_NPLL:
2343 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2344 NPLL);
2345 break;
2346 case PLL_VPLL:
2347 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2348 VPLL);
2349 break;
2350 case PLL_DPLL:
2351 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2352 DPLL);
2353 break;
2354 case ACLK_BUS:
2355 case PCLK_BUS:
2356 case PCLK_WDT_NS:
2357 rate = rk3568_bus_get_clk(priv, clk->id);
2358 break;
2359 case ACLK_PERIMID:
2360 case HCLK_PERIMID:
2361 rate = rk3568_perimid_get_clk(priv, clk->id);
2362 break;
2363 case ACLK_TOP_HIGH:
2364 case ACLK_TOP_LOW:
2365 case HCLK_TOP:
2366 case PCLK_TOP:
2367 rate = rk3568_top_get_clk(priv, clk->id);
2368 break;
2369 case CLK_I2C1:
2370 case CLK_I2C2:
2371 case CLK_I2C3:
2372 case CLK_I2C4:
2373 case CLK_I2C5:
2374 rate = rk3568_i2c_get_clk(priv, clk->id);
2375 break;
2376 case CLK_SPI0:
2377 case CLK_SPI1:
2378 case CLK_SPI2:
2379 case CLK_SPI3:
2380 rate = rk3568_spi_get_clk(priv, clk->id);
2381 break;
2382 case CLK_PWM1:
2383 case CLK_PWM2:
2384 case CLK_PWM3:
2385 rate = rk3568_pwm_get_clk(priv, clk->id);
2386 break;
2387 case CLK_SARADC:
2388 case CLK_TSADC_TSEN:
2389 case CLK_TSADC:
2390 rate = rk3568_adc_get_clk(priv, clk->id);
2391 break;
2392 case HCLK_SDMMC0:
2393 case CLK_SDMMC0:
2394 case CLK_SDMMC1:
2395 case CLK_SDMMC2:
2396 rate = rk3568_sdmmc_get_clk(priv, clk->id);
2397 break;
2398 case SCLK_SFC:
2399 rate = rk3568_sfc_get_clk(priv);
2400 break;
2401 case NCLK_NANDC:
2402 rate = rk3568_nand_get_clk(priv);
2403 break;
2404 case CCLK_EMMC:
2405 rate = rk3568_emmc_get_clk(priv);
2406 break;
2407 case BCLK_EMMC:
2408 rate = rk3568_emmc_get_bclk(priv);
2409 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002410 case TCLK_EMMC:
2411 rate = OSC_HZ;
2412 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002413#ifndef CONFIG_SPL_BUILD
2414 case ACLK_VOP:
2415 rate = rk3568_aclk_vop_get_clk(priv);
2416 break;
2417 case DCLK_VOP0:
2418 case DCLK_VOP1:
2419 case DCLK_VOP2:
2420 rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2421 break;
2422 case SCLK_GMAC0:
2423 case CLK_MAC0_2TOP:
2424 case CLK_MAC0_REFOUT:
2425 rate = rk3568_gmac_src_get_clk(priv, 0);
2426 break;
2427 case CLK_MAC0_OUT:
2428 rate = rk3568_gmac_out_get_clk(priv, 0);
2429 break;
2430 case CLK_GMAC0_PTP_REF:
2431 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2432 break;
2433 case SCLK_GMAC1:
2434 case CLK_MAC1_2TOP:
2435 case CLK_MAC1_REFOUT:
2436 rate = rk3568_gmac_src_get_clk(priv, 1);
2437 break;
2438 case CLK_MAC1_OUT:
2439 rate = rk3568_gmac_out_get_clk(priv, 1);
2440 break;
2441 case CLK_GMAC1_PTP_REF:
2442 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2443 break;
2444 case DCLK_EBC:
2445 rate = rk3568_ebc_get_clk(priv);
2446 break;
2447 case ACLK_RKVDEC_PRE:
2448 case ACLK_RKVDEC:
2449 case CLK_RKVDEC_CORE:
2450 rate = rk3568_rkvdec_get_clk(priv, clk->id);
2451 break;
2452 case TCLK_WDT_NS:
2453 rate = OSC_HZ;
2454 break;
2455 case SCLK_UART1:
2456 case SCLK_UART2:
2457 case SCLK_UART3:
2458 case SCLK_UART4:
2459 case SCLK_UART5:
2460 case SCLK_UART6:
2461 case SCLK_UART7:
2462 case SCLK_UART8:
2463 case SCLK_UART9:
2464 rate = rk3568_uart_get_rate(priv, clk->id);
2465 break;
2466#endif
2467 case ACLK_SECURE_FLASH:
2468 case ACLK_CRYPTO_NS:
2469 case HCLK_SECURE_FLASH:
2470 case HCLK_CRYPTO_NS:
2471 case CLK_CRYPTO_NS_RNG:
2472 case CLK_CRYPTO_NS_CORE:
2473 case CLK_CRYPTO_NS_PKA:
2474 rate = rk3568_crypto_get_rate(priv, clk->id);
2475 break;
2476 case CPLL_500M:
2477 case CPLL_333M:
2478 case CPLL_250M:
2479 case CPLL_125M:
2480 case CPLL_100M:
2481 case CPLL_62P5M:
2482 case CPLL_50M:
2483 case CPLL_25M:
2484 rate = rk3568_cpll_div_get_rate(priv, clk->id);
2485 break;
2486 default:
2487 return -ENOENT;
2488 }
2489
2490 return rate;
2491};
2492
2493static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2494{
2495 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2496 ulong ret = 0;
2497
2498 if (!priv->gpll_hz) {
2499 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2500 return -ENOENT;
2501 }
2502
2503 switch (clk->id) {
2504 case PLL_APLL:
2505 case ARMCLK:
2506 if (priv->armclk_hz)
2507 rk3568_armclk_set_clk(priv, rate);
2508 priv->armclk_hz = rate;
2509 break;
2510 case PLL_CPLL:
2511 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2512 CPLL, rate);
2513 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2514 priv->cru, CPLL);
2515 break;
2516 case PLL_GPLL:
2517 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2518 GPLL, rate);
2519 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2520 priv->cru, GPLL);
2521 break;
2522 case PLL_NPLL:
2523 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2524 NPLL, rate);
2525 break;
2526 case PLL_VPLL:
2527 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2528 VPLL, rate);
2529 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2530 priv->cru,
2531 VPLL);
2532 break;
2533 case ACLK_BUS:
2534 case PCLK_BUS:
2535 case PCLK_WDT_NS:
2536 ret = rk3568_bus_set_clk(priv, clk->id, rate);
2537 break;
2538 case ACLK_PERIMID:
2539 case HCLK_PERIMID:
2540 ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2541 break;
2542 case ACLK_TOP_HIGH:
2543 case ACLK_TOP_LOW:
2544 case HCLK_TOP:
2545 case PCLK_TOP:
2546 ret = rk3568_top_set_clk(priv, clk->id, rate);
2547 break;
2548 case CLK_I2C1:
2549 case CLK_I2C2:
2550 case CLK_I2C3:
2551 case CLK_I2C4:
2552 case CLK_I2C5:
2553 ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2554 break;
2555 case CLK_SPI0:
2556 case CLK_SPI1:
2557 case CLK_SPI2:
2558 case CLK_SPI3:
2559 ret = rk3568_spi_set_clk(priv, clk->id, rate);
2560 break;
2561 case CLK_PWM1:
2562 case CLK_PWM2:
2563 case CLK_PWM3:
2564 ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2565 break;
2566 case CLK_SARADC:
2567 case CLK_TSADC_TSEN:
2568 case CLK_TSADC:
2569 ret = rk3568_adc_set_clk(priv, clk->id, rate);
2570 break;
2571 case HCLK_SDMMC0:
2572 case CLK_SDMMC0:
2573 case CLK_SDMMC1:
2574 case CLK_SDMMC2:
2575 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2576 break;
2577 case SCLK_SFC:
2578 ret = rk3568_sfc_set_clk(priv, rate);
2579 break;
2580 case NCLK_NANDC:
2581 ret = rk3568_nand_set_clk(priv, rate);
2582 break;
2583 case CCLK_EMMC:
2584 ret = rk3568_emmc_set_clk(priv, rate);
2585 break;
2586 case BCLK_EMMC:
2587 ret = rk3568_emmc_set_bclk(priv, rate);
2588 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002589 case TCLK_EMMC:
2590 ret = OSC_HZ;
2591 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002592#ifndef CONFIG_SPL_BUILD
2593 case ACLK_VOP:
2594 ret = rk3568_aclk_vop_set_clk(priv, rate);
2595 break;
2596 case DCLK_VOP0:
2597 case DCLK_VOP1:
2598 case DCLK_VOP2:
2599 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2600 break;
2601 case SCLK_GMAC0:
2602 case CLK_MAC0_2TOP:
2603 case CLK_MAC0_REFOUT:
2604 ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2605 break;
2606 case CLK_MAC0_OUT:
2607 ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2608 break;
2609 case SCLK_GMAC0_RX_TX:
2610 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2611 break;
2612 case CLK_GMAC0_PTP_REF:
2613 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2614 break;
2615 case SCLK_GMAC1:
2616 case CLK_MAC1_2TOP:
2617 case CLK_MAC1_REFOUT:
2618 ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2619 break;
2620 case CLK_MAC1_OUT:
2621 ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2622 break;
2623 case SCLK_GMAC1_RX_TX:
2624 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2625 break;
2626 case CLK_GMAC1_PTP_REF:
2627 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2628 break;
2629 case DCLK_EBC:
2630 ret = rk3568_ebc_set_clk(priv, rate);
2631 break;
2632 case ACLK_RKVDEC_PRE:
2633 case ACLK_RKVDEC:
2634 case CLK_RKVDEC_CORE:
2635 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2636 break;
2637 case TCLK_WDT_NS:
2638 ret = OSC_HZ;
2639 break;
2640 case SCLK_UART1:
2641 case SCLK_UART2:
2642 case SCLK_UART3:
2643 case SCLK_UART4:
2644 case SCLK_UART5:
2645 case SCLK_UART6:
2646 case SCLK_UART7:
2647 case SCLK_UART8:
2648 case SCLK_UART9:
2649 ret = rk3568_uart_set_rate(priv, clk->id, rate);
2650 break;
2651#endif
2652 case ACLK_SECURE_FLASH:
2653 case ACLK_CRYPTO_NS:
2654 case HCLK_SECURE_FLASH:
2655 case HCLK_CRYPTO_NS:
2656 case CLK_CRYPTO_NS_RNG:
2657 case CLK_CRYPTO_NS_CORE:
2658 case CLK_CRYPTO_NS_PKA:
2659 ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2660 break;
2661 case CPLL_500M:
2662 case CPLL_333M:
2663 case CPLL_250M:
2664 case CPLL_125M:
2665 case CPLL_100M:
2666 case CPLL_62P5M:
2667 case CPLL_50M:
2668 case CPLL_25M:
2669 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2670 break;
2671 default:
2672 return -ENOENT;
2673 }
2674
2675 return ret;
2676};
2677
2678#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2679static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2680{
2681 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2682 struct rk3568_cru *cru = priv->cru;
2683
2684 if (parent->id == CLK_MAC0_2TOP)
2685 rk_clrsetreg(&cru->clksel_con[31],
2686 RMII0_EXTCLK_SEL_MASK,
2687 RMII0_EXTCLK_SEL_MAC0_TOP <<
2688 RMII0_EXTCLK_SEL_SHIFT);
2689 else
2690 rk_clrsetreg(&cru->clksel_con[31],
2691 RMII0_EXTCLK_SEL_MASK,
2692 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2693 return 0;
2694}
2695
2696static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2697{
2698 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2699 struct rk3568_cru *cru = priv->cru;
2700
2701 if (parent->id == CLK_MAC1_2TOP)
2702 rk_clrsetreg(&cru->clksel_con[33],
2703 RMII0_EXTCLK_SEL_MASK,
2704 RMII0_EXTCLK_SEL_MAC0_TOP <<
2705 RMII0_EXTCLK_SEL_SHIFT);
2706 else
2707 rk_clrsetreg(&cru->clksel_con[33],
2708 RMII0_EXTCLK_SEL_MASK,
2709 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2710 return 0;
2711}
2712
2713static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2714{
2715 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2716 struct rk3568_cru *cru = priv->cru;
2717
2718 if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2719 rk_clrsetreg(&cru->clksel_con[31],
2720 RMII0_MODE_MASK,
2721 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2722 else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2723 rk_clrsetreg(&cru->clksel_con[31],
2724 RMII0_MODE_MASK,
2725 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2726 else
2727 rk_clrsetreg(&cru->clksel_con[31],
2728 RMII0_MODE_MASK,
2729 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2730
2731 return 0;
2732}
2733
2734static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2735{
2736 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2737 struct rk3568_cru *cru = priv->cru;
2738
2739 if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2740 rk_clrsetreg(&cru->clksel_con[33],
2741 RMII0_MODE_MASK,
2742 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2743 else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2744 rk_clrsetreg(&cru->clksel_con[33],
2745 RMII0_MODE_MASK,
2746 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2747 else
2748 rk_clrsetreg(&cru->clksel_con[33],
2749 RMII0_MODE_MASK,
2750 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2751
2752 return 0;
2753}
2754
2755static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2756{
2757 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2758 struct rk3568_cru *cru = priv->cru;
2759 u32 con_id;
2760
2761 switch (clk->id) {
2762 case DCLK_VOP0:
2763 con_id = 39;
2764 break;
2765 case DCLK_VOP1:
2766 con_id = 40;
2767 break;
2768 case DCLK_VOP2:
2769 con_id = 41;
2770 break;
2771 default:
2772 return -EINVAL;
2773 }
2774 if (parent->id == PLL_VPLL) {
2775 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2776 DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
2777 } else {
2778 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2779 DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
2780 }
2781
2782 return 0;
2783}
2784
2785static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2786{
2787 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2788 struct rk3568_cru *cru = priv->cru;
2789 u32 con_id, mask, shift;
2790
2791 switch (clk->id) {
2792 case ACLK_RKVDEC_PRE:
2793 con_id = 47;
2794 mask = ACLK_RKVDEC_SEL_MASK;
2795 shift = ACLK_RKVDEC_SEL_SHIFT;
2796 break;
2797 case CLK_RKVDEC_CORE:
2798 con_id = 49;
2799 mask = CLK_RKVDEC_CORE_SEL_MASK;
2800 shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2801 break;
2802 default:
2803 return -EINVAL;
2804 }
2805 if (parent->id == PLL_CPLL) {
2806 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2807 ACLK_RKVDEC_SEL_CPLL << shift);
2808 } else {
2809 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2810 ACLK_RKVDEC_SEL_GPLL << shift);
2811 }
2812
2813 return 0;
2814}
2815
2816static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2817{
2818 switch (clk->id) {
2819 case SCLK_GMAC0:
2820 return rk3568_gmac0_src_set_parent(clk, parent);
2821 case SCLK_GMAC1:
2822 return rk3568_gmac1_src_set_parent(clk, parent);
2823 case SCLK_GMAC0_RX_TX:
2824 return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2825 case SCLK_GMAC1_RX_TX:
2826 return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2827 case DCLK_VOP0:
2828 case DCLK_VOP1:
2829 case DCLK_VOP2:
2830 return rk3568_dclk_vop_set_parent(clk, parent);
2831 case ACLK_RKVDEC_PRE:
2832 case CLK_RKVDEC_CORE:
2833 return rk3568_rkvdec_set_parent(clk, parent);
2834 default:
2835 return -ENOENT;
2836 }
2837
2838 return 0;
2839}
2840#endif
2841
2842static struct clk_ops rk3568_clk_ops = {
2843 .get_rate = rk3568_clk_get_rate,
2844 .set_rate = rk3568_clk_set_rate,
2845#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2846 .set_parent = rk3568_clk_set_parent,
2847#endif
2848};
2849
2850static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2851{
2852 int ret;
2853
2854 priv->sync_kernel = false;
2855 if (!priv->armclk_enter_hz) {
2856 priv->armclk_enter_hz =
2857 rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2858 priv->cru, APLL);
2859 priv->armclk_init_hz = priv->armclk_enter_hz;
2860 }
2861
2862 if (priv->armclk_init_hz != APLL_HZ) {
2863 ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2864 if (!ret)
2865 priv->armclk_init_hz = APLL_HZ;
2866 }
2867 if (priv->cpll_hz != CPLL_HZ) {
2868 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2869 CPLL, CPLL_HZ);
2870 if (!ret)
2871 priv->cpll_hz = CPLL_HZ;
2872 }
2873 if (priv->gpll_hz != GPLL_HZ) {
2874 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2875 GPLL, GPLL_HZ);
2876 if (!ret)
2877 priv->gpll_hz = GPLL_HZ;
2878 }
2879
2880#ifdef CONFIG_SPL_BUILD
2881 ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2882 if (ret < 0)
2883 printf("Fail to set the ACLK_BUS clock.\n");
2884#endif
2885
2886 priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2887 priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2888}
2889
2890static int rk3568_clk_probe(struct udevice *dev)
2891{
2892 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2893 int ret;
2894
2895 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2896 if (IS_ERR(priv->grf))
2897 return PTR_ERR(priv->grf);
2898
2899 rk3568_clk_init(priv);
2900
2901 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2902 ret = clk_set_defaults(dev, 1);
2903 if (ret)
2904 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2905 else
2906 priv->sync_kernel = true;
2907
2908 return 0;
2909}
2910
2911static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2912{
2913 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2914
2915 priv->cru = dev_read_addr_ptr(dev);
2916
2917 return 0;
2918}
2919
2920static int rk3568_clk_bind(struct udevice *dev)
2921{
2922 int ret;
2923 struct udevice *sys_child;
2924 struct sysreset_reg *priv;
2925
2926 /* The reset driver does not have a device node, so bind it here */
2927 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2928 &sys_child);
2929 if (ret) {
2930 debug("Warning: No sysreset driver: ret=%d\n", ret);
2931 } else {
2932 priv = malloc(sizeof(struct sysreset_reg));
2933 priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2934 glb_srst_fst);
2935 priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2936 glb_srsr_snd);
2937 }
2938
2939#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2940 ret = offsetof(struct rk3568_cru, softrst_con[0]);
2941 ret = rockchip_reset_bind(dev, ret, 30);
2942 if (ret)
2943 debug("Warning: software reset driver bind faile\n");
2944#endif
2945
2946 return 0;
2947}
2948
2949static const struct udevice_id rk3568_clk_ids[] = {
2950 { .compatible = "rockchip,rk3568-cru" },
2951 { }
2952};
2953
2954U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2955 .name = "rockchip_rk3568_cru",
2956 .id = UCLASS_CLK,
2957 .of_match = rk3568_clk_ids,
2958 .priv_auto = sizeof(struct rk3568_clk_priv),
2959 .of_to_plat = rk3568_clk_ofdata_to_platdata,
2960 .ops = &rk3568_clk_ops,
2961 .bind = rk3568_clk_bind,
2962 .probe = rk3568_clk_probe,
2963#if CONFIG_IS_ENABLED(OF_PLATDATA)
2964 .plat_auto = sizeof(struct rk3568_clk_plat),
2965#endif
2966};