1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2021 Rockchip Electronics Co., Ltd
4 * Author: Elaine Zhang <zhangqing@rock-chips.com>
9 #include <clk-uclass.h>
13 #include <asm/arch-rockchip/cru_rk3568.h>
14 #include <asm/arch-rockchip/clock.h>
15 #include <asm/arch-rockchip/hardware.h>
18 #include <dt-bindings/clock/rk3568-cru.h>
20 DECLARE_GLOBAL_DATA_PTR;
22 #if CONFIG_IS_ENABLED(OF_PLATDATA)
23 struct rk3568_clk_plat {
24 struct dtd_rockchip_rk3568_cru dtd;
27 struct rk3568_pmuclk_plat {
28 struct dtd_rockchip_rk3568_pmucru dtd;
32 #define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
35 .aclk_div = _aclk_div, \
36 .pclk_div = _pclk_div, \
39 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
41 static 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),
54 static 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),
76 static 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),
95 #ifndef CONFIG_SPL_BUILD
97 rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
98 ulong pll_id, ulong rate)
100 struct udevice *pmucru_dev;
101 struct rk3568_pmuclk_priv *pmu_priv;
104 ret = uclass_get_device_by_driver(UCLASS_CLK,
105 DM_DRIVER_GET(rockchip_rk3568_pmucru),
108 printf("%s: could not find pmucru device\n", __func__);
111 pmu_priv = dev_get_priv(pmucru_dev);
113 rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
114 pmu_priv->pmucru, pll_id, rate);
120 static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
123 struct udevice *pmucru_dev;
124 struct rk3568_pmuclk_priv *pmu_priv;
127 ret = uclass_get_device_by_driver(UCLASS_CLK,
128 DM_DRIVER_GET(rockchip_rk3568_pmucru),
131 printf("%s: could not find pmucru device\n", __func__);
134 pmu_priv = dev_get_priv(pmucru_dev);
136 return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
137 pmu_priv->pmucru, pll_id);
142 * rational_best_approximation(31415, 10000,
143 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
145 * you may look at given_numerator as a fixed point number,
146 * with the fractional part size described in given_denominator.
148 * for theoretical background, see:
149 * http://en.wikipedia.org/wiki/Continued_fraction
151 static 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)
158 unsigned long n, d, n0, d0, n1, d1;
161 d = given_denominator;
169 if (n1 > max_numerator || d1 > max_denominator) {
187 *best_numerator = n1;
188 *best_denominator = d1;
191 static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
193 struct rk3568_pmucru *pmucru = priv->pmucru;
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;
203 return OSC_HZ * m / n;
206 static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
209 struct rk3568_pmucru *pmucru = priv->pmucru;
210 unsigned long m, n, val;
212 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
213 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
215 rational_best_approximation(rate, OSC_HZ,
219 val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
220 writel(val, &pmucru->pmu_clksel_con[1]);
222 return rk3568_rtc32k_get_pmuclk(priv);
225 static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
228 struct rk3568_pmucru *pmucru = priv->pmucru;
233 con = readl(&pmucru->pmu_clksel_con[3]);
234 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
240 return DIV_TO_RATE(priv->ppll_hz, div);
243 static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
244 ulong clk_id, ulong rate)
246 struct rk3568_pmucru *pmucru = priv->pmucru;
249 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
250 assert(src_clk_div - 1 <= 127);
254 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
255 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
261 return rk3568_i2c_get_pmuclk(priv, clk_id);
264 static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
267 struct rk3568_pmucru *pmucru = priv->pmucru;
268 u32 div, sel, con, parent;
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)
278 parent = priv->ppll_hz;
284 return DIV_TO_RATE(parent, div);
287 static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
288 ulong clk_id, ulong rate)
290 struct rk3568_pmucru *pmucru = priv->pmucru;
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);
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);
314 return rk3568_pwm_get_pmuclk(priv, clk_id);
317 static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
319 struct rk3568_pmucru *pmucru = priv->pmucru;
320 u32 div, con, sel, parent;
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;
328 parent = priv->ppll_hz;
330 return DIV_TO_RATE(parent, div);
333 static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
336 struct rk3568_pmucru *pmucru = priv->pmucru;
339 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
340 assert(src_clk_div - 1 <= 31);
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));
347 return rk3568_pmu_get_pmuclk(priv);
350 static ulong rk3568_pmuclk_get_rate(struct clk *clk)
352 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
355 if (!priv->ppll_hz) {
356 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
360 debug("%s %ld\n", __func__, clk->id);
363 rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
367 rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
371 case CLK_RTC32K_FRAC:
372 rate = rk3568_rtc32k_get_pmuclk(priv);
375 rate = rk3568_i2c_get_pmuclk(priv, clk->id);
378 rate = rk3568_pwm_get_pmuclk(priv, clk->id);
381 rate = rk3568_pmu_get_pmuclk(priv);
390 static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
392 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
395 if (!priv->ppll_hz) {
396 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
400 debug("%s %ld %ld\n", __func__, clk->id, rate);
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],
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],
415 case CLK_RTC32K_FRAC:
416 ret = rk3568_rtc32k_set_pmuclk(priv, rate);
419 ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
422 ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
425 ret = rk3568_pmu_set_pmuclk(priv, rate);
434 static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
436 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
437 struct rk3568_pmucru *pmucru = priv->pmucru;
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);
443 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
444 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
449 static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
453 return rk3568_rtc32k_set_parent(clk, parent);
459 static 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,
465 static int rk3568_pmuclk_probe(struct udevice *dev)
467 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
470 if (priv->ppll_hz != PPLL_HZ) {
471 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
475 priv->ppll_hz = PPLL_HZ;
478 /* Ungate PCIe30phy refclk_m and refclk_n */
479 rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
483 static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
485 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
487 priv->pmucru = dev_read_addr_ptr(dev);
492 static int rk3568_pmuclk_bind(struct udevice *dev)
494 #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
497 ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]);
498 ret = rockchip_reset_bind(dev, ret, 1);
500 debug("Warning: pmucru software reset driver bind faile\n");
506 static const struct udevice_id rk3568_pmuclk_ids[] = {
507 { .compatible = "rockchip,rk3568-pmucru" },
511 U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
512 .name = "rockchip_rk3568_pmucru",
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),
526 static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
528 struct rk3568_cru *cru = priv->cru;
529 const struct rockchip_cpu_rate_table *rate;
532 rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
534 printf("%s unsupported rate\n", __func__);
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));
552 * set up dependent divisors for DBG and ACLK clocks.
554 old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
557 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
558 priv->cru, APLL, hz))
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))
593 static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
596 struct rk3568_cru *cru = priv->cru;
597 int div, mask, shift, con;
602 mask = CPLL_500M_DIV_MASK;
603 shift = CPLL_500M_DIV_SHIFT;
607 mask = CPLL_333M_DIV_MASK;
608 shift = CPLL_333M_DIV_SHIFT;
612 mask = CPLL_250M_DIV_MASK;
613 shift = CPLL_250M_DIV_SHIFT;
617 mask = CPLL_125M_DIV_MASK;
618 shift = CPLL_125M_DIV_SHIFT;
622 mask = CPLL_100M_DIV_MASK;
623 shift = CPLL_100M_DIV_SHIFT;
627 mask = CPLL_62P5M_DIV_MASK;
628 shift = CPLL_62P5M_DIV_SHIFT;
632 mask = CPLL_50M_DIV_MASK;
633 shift = CPLL_50M_DIV_SHIFT;
637 mask = CPLL_25M_DIV_MASK;
638 shift = CPLL_25M_DIV_SHIFT;
644 div = (readl(&cru->clksel_con[con]) & mask) >> shift;
645 return DIV_TO_RATE(priv->cpll_hz, div);
648 static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
649 ulong clk_id, ulong rate)
651 struct rk3568_cru *cru = priv->cru;
652 int div, mask, shift, con;
657 mask = CPLL_500M_DIV_MASK;
658 shift = CPLL_500M_DIV_SHIFT;
662 mask = CPLL_333M_DIV_MASK;
663 shift = CPLL_333M_DIV_SHIFT;
667 mask = CPLL_250M_DIV_MASK;
668 shift = CPLL_250M_DIV_SHIFT;
672 mask = CPLL_125M_DIV_MASK;
673 shift = CPLL_125M_DIV_SHIFT;
677 mask = CPLL_100M_DIV_MASK;
678 shift = CPLL_100M_DIV_SHIFT;
682 mask = CPLL_62P5M_DIV_MASK;
683 shift = CPLL_62P5M_DIV_SHIFT;
687 mask = CPLL_50M_DIV_MASK;
688 shift = CPLL_50M_DIV_SHIFT;
692 mask = CPLL_25M_DIV_MASK;
693 shift = CPLL_25M_DIV_SHIFT;
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);
706 static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
708 struct rk3568_cru *cru = priv->cru;
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)
717 else if (sel == ACLK_BUS_SEL_150M)
719 else if (sel == ACLK_BUS_SEL_100M)
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)
730 else if (sel == PCLK_BUS_SEL_75M)
732 else if (sel == PCLK_BUS_SEL_50M)
744 static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
745 ulong clk_id, ulong rate)
747 struct rk3568_cru *cru = priv->cru;
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;
759 src_clk = ACLK_BUS_SEL_24M;
760 rk_clrsetreg(&cru->clksel_con[50],
762 src_clk << ACLK_BUS_SEL_SHIFT);
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;
773 src_clk = PCLK_BUS_SEL_24M;
774 rk_clrsetreg(&cru->clksel_con[50],
776 src_clk << PCLK_BUS_SEL_SHIFT);
780 printf("do not support this bus freq\n");
784 return rk3568_bus_get_clk(priv, clk_id);
787 static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
789 struct rk3568_cru *cru = priv->cru;
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)
798 else if (sel == ACLK_PERIMID_SEL_200M)
800 else if (sel == ACLK_PERIMID_SEL_100M)
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)
810 else if (sel == HCLK_PERIMID_SEL_100M)
812 else if (sel == HCLK_PERIMID_SEL_75M)
824 static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
825 ulong clk_id, ulong rate)
827 struct rk3568_cru *cru = priv->cru;
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;
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);
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;
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);
859 printf("do not support this permid freq\n");
863 return rk3568_perimid_get_clk(priv, clk_id);
866 static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
868 struct rk3568_cru *cru = priv->cru;
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)
877 else if (sel == ACLK_TOP_HIGH_SEL_400M)
879 else if (sel == ACLK_TOP_HIGH_SEL_300M)
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)
889 else if (sel == ACLK_TOP_LOW_SEL_300M)
891 else if (sel == ACLK_TOP_LOW_SEL_200M)
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)
901 else if (sel == HCLK_TOP_SEL_100M)
903 else if (sel == HCLK_TOP_SEL_75M)
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)
913 else if (sel == PCLK_TOP_SEL_75M)
915 else if (sel == PCLK_TOP_SEL_50M)
927 static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
928 ulong clk_id, ulong rate)
930 struct rk3568_cru *cru = priv->cru;
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;
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);
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;
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);
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;
968 src_clk = HCLK_TOP_SEL_24M;
969 rk_clrsetreg(&cru->clksel_con[73],
971 src_clk << HCLK_TOP_SEL_SHIFT);
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;
981 src_clk = PCLK_TOP_SEL_24M;
982 rk_clrsetreg(&cru->clksel_con[73],
984 src_clk << PCLK_TOP_SEL_SHIFT);
988 printf("do not support this permid freq\n");
992 return rk3568_top_get_clk(priv, clk_id);
995 static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
997 struct rk3568_cru *cru = priv->cru;
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)
1011 else if (sel == CLK_I2C_SEL_100M)
1013 else if (sel == CLK_I2C_SEL_CPLL_100M)
1025 static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1028 struct rk3568_cru *cru = priv->cru;
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;
1036 src_clk = CLK_I2C_SEL_24M;
1044 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1045 src_clk << CLK_I2C_SEL_SHIFT);
1051 return rk3568_i2c_get_clk(priv, clk_id);
1054 static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1056 struct rk3568_cru *cru = priv->cru;
1059 con = readl(&cru->clksel_con[72]);
1063 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1066 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1069 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1072 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1079 case CLK_SPI_SEL_200M:
1081 case CLK_SPI_SEL_24M:
1083 case CLK_SPI_SEL_CPLL_100M:
1090 static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1091 ulong clk_id, ulong rate)
1093 struct rk3568_cru *cru = priv->cru;
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;
1101 src_clk = CLK_SPI_SEL_24M;
1105 rk_clrsetreg(&cru->clksel_con[72],
1107 src_clk << CLK_SPI0_SEL_SHIFT);
1110 rk_clrsetreg(&cru->clksel_con[72],
1112 src_clk << CLK_SPI1_SEL_SHIFT);
1115 rk_clrsetreg(&cru->clksel_con[72],
1117 src_clk << CLK_SPI2_SEL_SHIFT);
1120 rk_clrsetreg(&cru->clksel_con[72],
1122 src_clk << CLK_SPI3_SEL_SHIFT);
1128 return rk3568_spi_get_clk(priv, clk_id);
1131 static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1133 struct rk3568_cru *cru = priv->cru;
1136 con = readl(&cru->clksel_con[72]);
1140 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1143 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1146 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1153 case CLK_PWM_SEL_100M:
1155 case CLK_PWM_SEL_24M:
1157 case CLK_PWM_SEL_CPLL_100M:
1164 static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1165 ulong clk_id, ulong rate)
1167 struct rk3568_cru *cru = priv->cru;
1170 if (rate == 100 * MHz)
1171 src_clk = CLK_PWM_SEL_100M;
1173 src_clk = CLK_PWM_SEL_24M;
1177 rk_clrsetreg(&cru->clksel_con[72],
1179 src_clk << CLK_PWM1_SEL_SHIFT);
1182 rk_clrsetreg(&cru->clksel_con[72],
1184 src_clk << CLK_PWM2_SEL_SHIFT);
1187 rk_clrsetreg(&cru->clksel_con[72],
1189 src_clk << CLK_PWM3_SEL_SHIFT);
1195 return rk3568_pwm_get_clk(priv, clk_id);
1198 static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1200 struct rk3568_cru *cru = priv->cru;
1201 u32 div, sel, con, prate;
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)
1216 return DIV_TO_RATE(prate, div);
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);
1227 static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1228 ulong clk_id, ulong rate)
1230 struct rk3568_cru *cru = priv->cru;
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);
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);
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],
1266 (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1271 return rk3568_adc_get_clk(priv, clk_id);
1274 static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1276 struct rk3568_cru *cru = priv->cru;
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)
1287 else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1289 else if (sel == ACLK_SECURE_FLASH_SEL_100M)
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)
1301 else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1303 else if (sel == HCLK_SECURE_FLASH_SEL_75M)
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)
1313 else if (sel == CLK_CRYPTO_CORE_SEL_150M)
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)
1323 else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1332 static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1333 ulong clk_id, ulong rate)
1335 struct rk3568_cru *cru = priv->cru;
1336 u32 src_clk, mask, shift;
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;
1350 src_clk = ACLK_SECURE_FLASH_SEL_24M;
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;
1364 src_clk = HCLK_SECURE_FLASH_SEL_24M;
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;
1374 src_clk = CLK_CRYPTO_CORE_SEL_100M;
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;
1384 src_clk = CLK_CRYPTO_PKA_SEL_100M;
1390 rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1392 return rk3568_crypto_get_rate(priv, clk_id);
1395 static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1397 struct rk3568_cru *cru = priv->cru;
1403 con = readl(&cru->clksel_con[30]);
1404 sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1407 con = readl(&cru->clksel_con[30]);
1408 sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1411 con = readl(&cru->clksel_con[32]);
1412 sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1419 case CLK_SDMMC_SEL_24M:
1421 case CLK_SDMMC_SEL_400M:
1423 case CLK_SDMMC_SEL_300M:
1425 case CLK_SDMMC_SEL_100M:
1427 case CLK_SDMMC_SEL_50M:
1429 case CLK_SDMMC_SEL_750K:
1436 static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1437 ulong clk_id, ulong rate)
1439 struct rk3568_cru *cru = priv->cru;
1446 src_clk = CLK_SDMMC_SEL_24M;
1449 src_clk = CLK_SDMMC_SEL_400M;
1452 src_clk = CLK_SDMMC_SEL_300M;
1455 src_clk = CLK_SDMMC_SEL_100M;
1459 src_clk = CLK_SDMMC_SEL_50M;
1463 src_clk = CLK_SDMMC_SEL_750K;
1472 rk_clrsetreg(&cru->clksel_con[30],
1473 CLK_SDMMC0_SEL_MASK,
1474 src_clk << CLK_SDMMC0_SEL_SHIFT);
1477 rk_clrsetreg(&cru->clksel_con[30],
1478 CLK_SDMMC1_SEL_MASK,
1479 src_clk << CLK_SDMMC1_SEL_SHIFT);
1482 rk_clrsetreg(&cru->clksel_con[32],
1483 CLK_SDMMC2_SEL_MASK,
1484 src_clk << CLK_SDMMC2_SEL_SHIFT);
1490 return rk3568_sdmmc_get_clk(priv, clk_id);
1493 static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1495 struct rk3568_cru *cru = priv->cru;
1498 con = readl(&cru->clksel_con[28]);
1499 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1501 case SCLK_SFC_SEL_24M:
1503 case SCLK_SFC_SEL_50M:
1505 case SCLK_SFC_SEL_75M:
1507 case SCLK_SFC_SEL_100M:
1509 case SCLK_SFC_SEL_125M:
1511 case SCLK_SFC_SEL_150M:
1518 static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1520 struct rk3568_cru *cru = priv->cru;
1525 src_clk = SCLK_SFC_SEL_24M;
1528 src_clk = SCLK_SFC_SEL_50M;
1531 src_clk = SCLK_SFC_SEL_75M;
1534 src_clk = SCLK_SFC_SEL_100M;
1537 src_clk = SCLK_SFC_SEL_125M;
1540 src_clk = SCLK_SFC_SEL_150M;
1546 rk_clrsetreg(&cru->clksel_con[28],
1548 src_clk << SCLK_SFC_SEL_SHIFT);
1550 return rk3568_sfc_get_clk(priv);
1553 static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1555 struct rk3568_cru *cru = priv->cru;
1558 con = readl(&cru->clksel_con[28]);
1559 sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1561 case NCLK_NANDC_SEL_200M:
1563 case NCLK_NANDC_SEL_150M:
1565 case NCLK_NANDC_SEL_100M:
1567 case NCLK_NANDC_SEL_24M:
1574 static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1576 struct rk3568_cru *cru = priv->cru;
1581 src_clk = NCLK_NANDC_SEL_24M;
1584 src_clk = NCLK_NANDC_SEL_100M;
1587 src_clk = NCLK_NANDC_SEL_150M;
1590 src_clk = NCLK_NANDC_SEL_200M;
1596 rk_clrsetreg(&cru->clksel_con[28],
1597 NCLK_NANDC_SEL_MASK,
1598 src_clk << NCLK_NANDC_SEL_SHIFT);
1600 return rk3568_nand_get_clk(priv);
1603 static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1605 struct rk3568_cru *cru = priv->cru;
1608 con = readl(&cru->clksel_con[28]);
1609 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1611 case CCLK_EMMC_SEL_200M:
1613 case CCLK_EMMC_SEL_150M:
1615 case CCLK_EMMC_SEL_100M:
1617 case CCLK_EMMC_SEL_50M:
1619 case CCLK_EMMC_SEL_375K:
1621 case CCLK_EMMC_SEL_24M:
1628 static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1630 struct rk3568_cru *cru = priv->cru;
1637 src_clk = CCLK_EMMC_SEL_24M;
1641 src_clk = CCLK_EMMC_SEL_50M;
1644 src_clk = CCLK_EMMC_SEL_100M;
1647 src_clk = CCLK_EMMC_SEL_150M;
1650 src_clk = CCLK_EMMC_SEL_200M;
1654 src_clk = CCLK_EMMC_SEL_375K;
1660 rk_clrsetreg(&cru->clksel_con[28],
1662 src_clk << CCLK_EMMC_SEL_SHIFT);
1664 return rk3568_emmc_get_clk(priv);
1667 static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1669 struct rk3568_cru *cru = priv->cru;
1672 con = readl(&cru->clksel_con[28]);
1673 sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1675 case BCLK_EMMC_SEL_200M:
1677 case BCLK_EMMC_SEL_150M:
1679 case BCLK_EMMC_SEL_125M:
1686 static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1688 struct rk3568_cru *cru = priv->cru;
1693 src_clk = BCLK_EMMC_SEL_200M;
1696 src_clk = BCLK_EMMC_SEL_150M;
1699 src_clk = BCLK_EMMC_SEL_125M;
1705 rk_clrsetreg(&cru->clksel_con[28],
1707 src_clk << BCLK_EMMC_SEL_SHIFT);
1709 return rk3568_emmc_get_bclk(priv);
1712 #ifndef CONFIG_SPL_BUILD
1713 static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1715 struct rk3568_cru *cru = priv->cru;
1716 u32 div, sel, con, parent;
1718 con = readl(&cru->clksel_con[38]);
1719 div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1720 sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1721 if (sel == ACLK_VOP_PRE_SEL_GPLL)
1722 parent = priv->gpll_hz;
1723 else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1724 parent = priv->cpll_hz;
1725 else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1726 parent = priv->vpll_hz;
1728 parent = priv->hpll_hz;
1730 return DIV_TO_RATE(parent, div);
1733 static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1735 struct rk3568_cru *cru = priv->cru;
1736 int src_clk_div, src_clk_mux;
1738 if ((priv->cpll_hz % rate) == 0) {
1739 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1740 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1742 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1743 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1745 assert(src_clk_div - 1 <= 31);
1746 rk_clrsetreg(&cru->clksel_con[38],
1747 ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1748 src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1749 (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1751 return rk3568_aclk_vop_get_clk(priv);
1754 static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1756 struct rk3568_cru *cru = priv->cru;
1757 u32 conid, div, sel, con, parent;
1773 con = readl(&cru->clksel_con[conid]);
1774 div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1775 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1776 if (sel == DCLK_VOP_SEL_HPLL)
1777 parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1778 else if (sel == DCLK_VOP_SEL_VPLL)
1779 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1781 else if (sel == DCLK_VOP_SEL_GPLL)
1782 parent = priv->gpll_hz;
1783 else if (sel == DCLK_VOP_SEL_CPLL)
1784 parent = priv->cpll_hz;
1788 return DIV_TO_RATE(parent, div);
1791 #define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1793 static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1794 ulong clk_id, ulong rate)
1796 struct rk3568_cru *cru = priv->cru;
1797 ulong pll_rate, now, best_rate = 0;
1798 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1814 con = readl(&cru->clksel_con[conid]);
1815 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1817 if (sel == DCLK_VOP_SEL_HPLL) {
1819 rk_clrsetreg(&cru->clksel_con[conid],
1820 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1821 (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1822 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1823 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1824 } else if (sel == DCLK_VOP_SEL_VPLL) {
1825 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1826 rk_clrsetreg(&cru->clksel_con[conid],
1827 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1828 (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1829 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1830 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1831 priv->cru, VPLL, div * rate);
1833 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1835 case DCLK_VOP_SEL_GPLL:
1836 pll_rate = priv->gpll_hz;
1838 case DCLK_VOP_SEL_CPLL:
1839 pll_rate = priv->cpll_hz;
1842 printf("do not support this vop pll sel\n");
1846 div = DIV_ROUND_UP(pll_rate, rate);
1849 now = pll_rate / div;
1850 if (abs(rate - now) < abs(rate - best_rate)) {
1855 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1856 pll_rate, best_rate, best_div, best_sel);
1860 rk_clrsetreg(&cru->clksel_con[conid],
1861 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1862 best_sel << DCLK0_VOP_SEL_SHIFT |
1863 (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1865 printf("do not support this vop freq %lu\n", rate);
1869 return rk3568_dclk_vop_get_clk(priv, clk_id);
1872 static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1875 struct rk3568_cru *cru = priv->cru;
1878 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1879 sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1882 case CLK_MAC0_2TOP_SEL_125M:
1884 case CLK_MAC0_2TOP_SEL_50M:
1886 case CLK_MAC0_2TOP_SEL_25M:
1888 case CLK_MAC0_2TOP_SEL_PPLL:
1889 return rk3568_pmu_pll_get_rate(priv, HPLL);
1895 static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1896 ulong mac_id, ulong rate)
1898 struct rk3568_cru *cru = priv->cru;
1903 src_clk = CLK_MAC0_2TOP_SEL_125M;
1906 src_clk = CLK_MAC0_2TOP_SEL_50M;
1909 src_clk = CLK_MAC0_2TOP_SEL_25M;
1915 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1916 CLK_MAC0_2TOP_SEL_MASK,
1917 src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1919 return rk3568_gmac_src_get_clk(priv, mac_id);
1922 static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1925 struct rk3568_cru *cru = priv->cru;
1928 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1929 sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1932 case CLK_MAC0_OUT_SEL_125M:
1934 case CLK_MAC0_OUT_SEL_50M:
1936 case CLK_MAC0_OUT_SEL_25M:
1938 case CLK_MAC0_OUT_SEL_24M:
1945 static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1946 ulong mac_id, ulong rate)
1948 struct rk3568_cru *cru = priv->cru;
1953 src_clk = CLK_MAC0_OUT_SEL_125M;
1956 src_clk = CLK_MAC0_OUT_SEL_50M;
1959 src_clk = CLK_MAC0_OUT_SEL_25M;
1962 src_clk = CLK_MAC0_OUT_SEL_24M;
1968 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1969 CLK_MAC0_OUT_SEL_MASK,
1970 src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1972 return rk3568_gmac_out_get_clk(priv, mac_id);
1975 static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1978 struct rk3568_cru *cru = priv->cru;
1981 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1982 sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1985 case CLK_GMAC0_PTP_REF_SEL_62_5M:
1987 case CLK_GMAC0_PTP_REF_SEL_100M:
1989 case CLK_GMAC0_PTP_REF_SEL_50M:
1991 case CLK_GMAC0_PTP_REF_SEL_24M:
1998 static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1999 ulong mac_id, ulong rate)
2001 struct rk3568_cru *cru = priv->cru;
2006 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2009 src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2012 src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2015 src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2021 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2022 CLK_GMAC0_PTP_REF_SEL_MASK,
2023 src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2025 return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2028 static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2029 ulong mac_id, ulong rate)
2031 struct rk3568_cru *cru = priv->cru;
2032 u32 con, sel, div_sel;
2034 con = readl(&cru->clksel_con[31 + mac_id * 2]);
2035 sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2037 if (sel == RMII0_MODE_SEL_RGMII) {
2038 if (rate == 2500000)
2039 div_sel = RGMII0_CLK_SEL_2_5M;
2040 else if (rate == 25000000)
2041 div_sel = RGMII0_CLK_SEL_25M;
2043 div_sel = RGMII0_CLK_SEL_125M;
2044 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2045 RGMII0_CLK_SEL_MASK,
2046 div_sel << RGMII0_CLK_SEL_SHIFT);
2047 } else if (sel == RMII0_MODE_SEL_RMII) {
2048 if (rate == 2500000)
2049 div_sel = RMII0_CLK_SEL_2_5M;
2051 div_sel = RMII0_CLK_SEL_25M;
2052 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2054 div_sel << RMII0_CLK_SEL_SHIFT);
2060 static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2062 struct rk3568_cru *cru = priv->cru;
2063 u32 con, div, p_rate;
2065 con = readl(&cru->clksel_con[79]);
2066 div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2067 p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2069 con = readl(&cru->clksel_con[43]);
2070 div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2072 case DCLK_EBC_SEL_GPLL_400M:
2074 case DCLK_EBC_SEL_CPLL_333M:
2076 case DCLK_EBC_SEL_GPLL_200M:
2083 static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2085 struct rk3568_cru *cru = priv->cru;
2088 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2089 assert(src_clk_div - 1 <= 31);
2090 rk_clrsetreg(&cru->clksel_con[79],
2092 (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2093 rk_clrsetreg(&cru->clksel_con[43],
2095 DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2097 return rk3568_ebc_get_clk(priv);
2100 static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2102 struct rk3568_cru *cru = priv->cru;
2103 u32 con, div, src, p_rate;
2106 case ACLK_RKVDEC_PRE:
2108 con = readl(&cru->clksel_con[47]);
2109 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2110 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2111 if (src == ACLK_RKVDEC_SEL_CPLL)
2112 p_rate = priv->cpll_hz;
2114 p_rate = priv->gpll_hz;
2115 return DIV_TO_RATE(p_rate, div);
2116 case CLK_RKVDEC_CORE:
2117 con = readl(&cru->clksel_con[49]);
2118 src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2119 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2120 div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2121 >> CLK_RKVDEC_CORE_DIV_SHIFT;
2122 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2123 p_rate = priv->cpll_hz;
2124 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2125 p_rate = priv->npll_hz;
2126 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2127 p_rate = priv->vpll_hz;
2129 p_rate = priv->gpll_hz;
2130 return DIV_TO_RATE(p_rate, div);
2136 static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2137 ulong clk_id, ulong rate)
2139 struct rk3568_cru *cru = priv->cru;
2140 int src_clk_div, src, p_rate;
2143 case ACLK_RKVDEC_PRE:
2145 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2146 >> ACLK_RKVDEC_SEL_SHIFT;
2147 if (src == ACLK_RKVDEC_SEL_CPLL)
2148 p_rate = priv->cpll_hz;
2150 p_rate = priv->gpll_hz;
2151 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2152 assert(src_clk_div - 1 <= 31);
2153 rk_clrsetreg(&cru->clksel_con[47],
2154 ACLK_RKVDEC_SEL_MASK |
2155 ACLK_RKVDEC_DIV_MASK,
2156 (src << ACLK_RKVDEC_SEL_SHIFT) |
2157 (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2159 case CLK_RKVDEC_CORE:
2160 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2161 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2162 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2163 p_rate = priv->cpll_hz;
2164 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2165 p_rate = priv->npll_hz;
2166 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2167 p_rate = priv->vpll_hz;
2169 p_rate = priv->gpll_hz;
2170 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2171 assert(src_clk_div - 1 <= 31);
2172 rk_clrsetreg(&cru->clksel_con[49],
2173 CLK_RKVDEC_CORE_SEL_MASK |
2174 CLK_RKVDEC_CORE_DIV_MASK,
2175 (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2176 (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2182 return rk3568_rkvdec_get_clk(priv, clk_id);
2185 static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2187 struct rk3568_cru *cru = priv->cru;
2188 u32 reg, con, fracdiv, div, src, p_src, p_rate;
2222 con = readl(&cru->clksel_con[reg]);
2223 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2224 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2225 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2226 if (p_src == CLK_UART_SRC_SEL_GPLL)
2227 p_rate = priv->gpll_hz;
2228 else if (p_src == CLK_UART_SRC_SEL_CPLL)
2229 p_rate = priv->cpll_hz;
2232 if (src == CLK_UART_SEL_SRC) {
2233 return DIV_TO_RATE(p_rate, div);
2234 } else if (src == CLK_UART_SEL_FRAC) {
2235 fracdiv = readl(&cru->clksel_con[reg + 1]);
2236 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2237 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2238 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2239 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2240 return DIV_TO_RATE(p_rate, div) * n / m;
2246 static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2247 ulong clk_id, ulong rate)
2249 struct rk3568_cru *cru = priv->cru;
2250 u32 reg, clk_src, uart_src, div;
2251 unsigned long m = 0, n = 0, val;
2253 if (priv->gpll_hz % rate == 0) {
2254 clk_src = CLK_UART_SRC_SEL_GPLL;
2255 uart_src = CLK_UART_SEL_SRC;
2256 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2257 } else if (priv->cpll_hz % rate == 0) {
2258 clk_src = CLK_UART_SRC_SEL_CPLL;
2259 uart_src = CLK_UART_SEL_SRC;
2260 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2261 } else if (rate == OSC_HZ) {
2262 clk_src = CLK_UART_SRC_SEL_GPLL;
2263 uart_src = CLK_UART_SEL_XIN24M;
2266 clk_src = CLK_UART_SRC_SEL_GPLL;
2267 uart_src = CLK_UART_SEL_FRAC;
2269 rational_best_approximation(rate, priv->gpll_hz / div,
2306 rk_clrsetreg(&cru->clksel_con[reg],
2307 CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2308 CLK_UART_SRC_DIV_MASK,
2309 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2310 (uart_src << CLK_UART_SEL_SHIFT) |
2311 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2313 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2314 writel(val, &cru->clksel_con[reg + 1]);
2317 return rk3568_uart_get_rate(priv, clk_id);
2321 static ulong rk3568_clk_get_rate(struct clk *clk)
2323 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2326 if (!priv->gpll_hz) {
2327 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2334 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2338 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2342 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2346 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2350 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2354 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2360 rate = rk3568_bus_get_clk(priv, clk->id);
2364 rate = rk3568_perimid_get_clk(priv, clk->id);
2370 rate = rk3568_top_get_clk(priv, clk->id);
2377 rate = rk3568_i2c_get_clk(priv, clk->id);
2383 rate = rk3568_spi_get_clk(priv, clk->id);
2388 rate = rk3568_pwm_get_clk(priv, clk->id);
2391 case CLK_TSADC_TSEN:
2393 rate = rk3568_adc_get_clk(priv, clk->id);
2399 rate = rk3568_sdmmc_get_clk(priv, clk->id);
2402 rate = rk3568_sfc_get_clk(priv);
2405 rate = rk3568_nand_get_clk(priv);
2408 rate = rk3568_emmc_get_clk(priv);
2411 rate = rk3568_emmc_get_bclk(priv);
2416 #ifndef CONFIG_SPL_BUILD
2418 rate = rk3568_aclk_vop_get_clk(priv);
2423 rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2427 case CLK_MAC0_REFOUT:
2428 rate = rk3568_gmac_src_get_clk(priv, 0);
2431 rate = rk3568_gmac_out_get_clk(priv, 0);
2433 case CLK_GMAC0_PTP_REF:
2434 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2438 case CLK_MAC1_REFOUT:
2439 rate = rk3568_gmac_src_get_clk(priv, 1);
2442 rate = rk3568_gmac_out_get_clk(priv, 1);
2444 case CLK_GMAC1_PTP_REF:
2445 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2448 rate = rk3568_ebc_get_clk(priv);
2450 case ACLK_RKVDEC_PRE:
2452 case CLK_RKVDEC_CORE:
2453 rate = rk3568_rkvdec_get_clk(priv, clk->id);
2467 rate = rk3568_uart_get_rate(priv, clk->id);
2470 case ACLK_SECURE_FLASH:
2471 case ACLK_CRYPTO_NS:
2472 case HCLK_SECURE_FLASH:
2473 case HCLK_CRYPTO_NS:
2474 case CLK_CRYPTO_NS_RNG:
2475 case CLK_CRYPTO_NS_CORE:
2476 case CLK_CRYPTO_NS_PKA:
2477 rate = rk3568_crypto_get_rate(priv, clk->id);
2487 rate = rk3568_cpll_div_get_rate(priv, clk->id);
2496 static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2498 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2501 if (!priv->gpll_hz) {
2502 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2509 if (priv->armclk_hz)
2510 rk3568_armclk_set_clk(priv, rate);
2511 priv->armclk_hz = rate;
2514 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2516 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2520 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2522 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2526 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2530 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2532 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2539 ret = rk3568_bus_set_clk(priv, clk->id, rate);
2543 ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2549 ret = rk3568_top_set_clk(priv, clk->id, rate);
2556 ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2562 ret = rk3568_spi_set_clk(priv, clk->id, rate);
2567 ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2570 case CLK_TSADC_TSEN:
2572 ret = rk3568_adc_set_clk(priv, clk->id, rate);
2578 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2581 ret = rk3568_sfc_set_clk(priv, rate);
2584 ret = rk3568_nand_set_clk(priv, rate);
2587 ret = rk3568_emmc_set_clk(priv, rate);
2590 ret = rk3568_emmc_set_bclk(priv, rate);
2595 #ifndef CONFIG_SPL_BUILD
2597 ret = rk3568_aclk_vop_set_clk(priv, rate);
2602 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2606 case CLK_MAC0_REFOUT:
2607 ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2610 ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2612 case SCLK_GMAC0_RX_TX:
2613 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2615 case CLK_GMAC0_PTP_REF:
2616 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2620 case CLK_MAC1_REFOUT:
2621 ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2624 ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2626 case SCLK_GMAC1_RX_TX:
2627 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2629 case CLK_GMAC1_PTP_REF:
2630 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2633 ret = rk3568_ebc_set_clk(priv, rate);
2635 case ACLK_RKVDEC_PRE:
2637 case CLK_RKVDEC_CORE:
2638 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2652 ret = rk3568_uart_set_rate(priv, clk->id, rate);
2655 case ACLK_SECURE_FLASH:
2656 case ACLK_CRYPTO_NS:
2657 case HCLK_SECURE_FLASH:
2658 case HCLK_CRYPTO_NS:
2659 case CLK_CRYPTO_NS_RNG:
2660 case CLK_CRYPTO_NS_CORE:
2661 case CLK_CRYPTO_NS_PKA:
2662 ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2672 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2681 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2682 static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2684 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2685 struct rk3568_cru *cru = priv->cru;
2687 if (parent->id == CLK_MAC0_2TOP)
2688 rk_clrsetreg(&cru->clksel_con[31],
2689 RMII0_EXTCLK_SEL_MASK,
2690 RMII0_EXTCLK_SEL_MAC0_TOP <<
2691 RMII0_EXTCLK_SEL_SHIFT);
2693 rk_clrsetreg(&cru->clksel_con[31],
2694 RMII0_EXTCLK_SEL_MASK,
2695 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2699 static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2701 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2702 struct rk3568_cru *cru = priv->cru;
2704 if (parent->id == CLK_MAC1_2TOP)
2705 rk_clrsetreg(&cru->clksel_con[33],
2706 RMII0_EXTCLK_SEL_MASK,
2707 RMII0_EXTCLK_SEL_MAC0_TOP <<
2708 RMII0_EXTCLK_SEL_SHIFT);
2710 rk_clrsetreg(&cru->clksel_con[33],
2711 RMII0_EXTCLK_SEL_MASK,
2712 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2716 static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2718 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2719 struct rk3568_cru *cru = priv->cru;
2721 if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2722 rk_clrsetreg(&cru->clksel_con[31],
2724 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2725 else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2726 rk_clrsetreg(&cru->clksel_con[31],
2728 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2730 rk_clrsetreg(&cru->clksel_con[31],
2732 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2737 static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2739 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2740 struct rk3568_cru *cru = priv->cru;
2742 if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2743 rk_clrsetreg(&cru->clksel_con[33],
2745 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2746 else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2747 rk_clrsetreg(&cru->clksel_con[33],
2749 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2751 rk_clrsetreg(&cru->clksel_con[33],
2753 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2758 static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2760 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2761 struct rk3568_cru *cru = priv->cru;
2777 if (parent->id == PLL_VPLL) {
2778 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2779 DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
2781 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2782 DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
2788 static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2790 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2791 struct rk3568_cru *cru = priv->cru;
2792 u32 con_id, mask, shift;
2795 case ACLK_RKVDEC_PRE:
2797 mask = ACLK_RKVDEC_SEL_MASK;
2798 shift = ACLK_RKVDEC_SEL_SHIFT;
2800 case CLK_RKVDEC_CORE:
2802 mask = CLK_RKVDEC_CORE_SEL_MASK;
2803 shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2808 if (parent->id == PLL_CPLL) {
2809 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2810 ACLK_RKVDEC_SEL_CPLL << shift);
2812 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2813 ACLK_RKVDEC_SEL_GPLL << shift);
2819 static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2823 return rk3568_gmac0_src_set_parent(clk, parent);
2825 return rk3568_gmac1_src_set_parent(clk, parent);
2826 case SCLK_GMAC0_RX_TX:
2827 return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2828 case SCLK_GMAC1_RX_TX:
2829 return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2833 return rk3568_dclk_vop_set_parent(clk, parent);
2834 case ACLK_RKVDEC_PRE:
2835 case CLK_RKVDEC_CORE:
2836 return rk3568_rkvdec_set_parent(clk, parent);
2845 static struct clk_ops rk3568_clk_ops = {
2846 .get_rate = rk3568_clk_get_rate,
2847 .set_rate = rk3568_clk_set_rate,
2848 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2849 .set_parent = rk3568_clk_set_parent,
2853 static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2857 priv->sync_kernel = false;
2858 if (!priv->armclk_enter_hz) {
2859 priv->armclk_enter_hz =
2860 rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2862 priv->armclk_init_hz = priv->armclk_enter_hz;
2865 if (priv->armclk_init_hz != APLL_HZ) {
2866 ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2868 priv->armclk_init_hz = APLL_HZ;
2870 if (priv->cpll_hz != CPLL_HZ) {
2871 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2874 priv->cpll_hz = CPLL_HZ;
2876 if (priv->gpll_hz != GPLL_HZ) {
2877 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2880 priv->gpll_hz = GPLL_HZ;
2883 #ifdef CONFIG_SPL_BUILD
2884 ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2886 printf("Fail to set the ACLK_BUS clock.\n");
2889 priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2890 priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2893 static int rk3568_clk_probe(struct udevice *dev)
2895 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2898 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2899 if (IS_ERR(priv->grf))
2900 return PTR_ERR(priv->grf);
2902 rk3568_clk_init(priv);
2904 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2905 ret = clk_set_defaults(dev, 1);
2907 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2909 priv->sync_kernel = true;
2914 static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2916 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2918 priv->cru = dev_read_addr_ptr(dev);
2923 static int rk3568_clk_bind(struct udevice *dev)
2926 struct udevice *sys_child;
2927 struct sysreset_reg *priv;
2929 /* The reset driver does not have a device node, so bind it here */
2930 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2933 debug("Warning: No sysreset driver: ret=%d\n", ret);
2935 priv = malloc(sizeof(struct sysreset_reg));
2936 priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2938 priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2942 #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2943 ret = offsetof(struct rk3568_cru, softrst_con[0]);
2944 ret = rockchip_reset_bind(dev, ret, 30);
2946 debug("Warning: software reset driver bind faile\n");
2952 static const struct udevice_id rk3568_clk_ids[] = {
2953 { .compatible = "rockchip,rk3568-cru" },
2957 U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2958 .name = "rockchip_rk3568_cru",
2960 .of_match = rk3568_clk_ids,
2961 .priv_auto = sizeof(struct rk3568_clk_priv),
2962 .of_to_plat = rk3568_clk_ofdata_to_platdata,
2963 .ops = &rk3568_clk_ops,
2964 .bind = rk3568_clk_bind,
2965 .probe = rk3568_clk_probe,
2966 #if CONFIG_IS_ENABLED(OF_PLATDATA)
2967 .plat_auto = sizeof(struct rk3568_clk_plat),