]> Git Repo - J-u-boot.git/blob - drivers/clk/rockchip/clk_rk3568.c
treewide: Simply conditions with the new OF_REAL
[J-u-boot.git] / drivers / clk / rockchip / clk_rk3568.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021 Rockchip Electronics Co., Ltd
4  * Author: Elaine Zhang <[email protected]>
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
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #if CONFIG_IS_ENABLED(OF_PLATDATA)
23 struct rk3568_clk_plat {
24         struct dtd_rockchip_rk3568_cru dtd;
25 };
26
27 struct 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
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),
51         { /* sentinel */ },
52 };
53
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),
73         { /* sentinel */ },
74 };
75
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),
93 };
94
95 #ifndef CONFIG_SPL_BUILD
96 static ulong
97 rk3568_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
120 static 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  */
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)
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
191 static 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
206 static 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
225 static 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
243 static 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
264 static 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
287 static 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
317 static 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
333 static 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
350 static 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
390 static 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
434 static 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
449 static 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
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,
463 };
464
465 static 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
483 static 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
492 static 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
506 static const struct udevice_id rk3568_pmuclk_ids[] = {
507         { .compatible = "rockchip,rk3568-pmucru" },
508         { }
509 };
510
511 U_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
526 static 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
593 static 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
648 static 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
706 static 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
744 static 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
787 static 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
824 static 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
866 static 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
927 static 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
995 static 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
1025 static 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
1054 static 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
1090 static 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
1131 static 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
1164 static 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
1198 static 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
1227 static 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
1274 static 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
1332 static 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
1395 static 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
1436 static 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:
1444                 src_clk = CLK_SDMMC_SEL_24M;
1445                 break;
1446         case 400 * MHz:
1447                 src_clk = CLK_SDMMC_SEL_400M;
1448                 break;
1449         case 300 * MHz:
1450                 src_clk = CLK_SDMMC_SEL_300M;
1451                 break;
1452         case 100 * MHz:
1453                 src_clk = CLK_SDMMC_SEL_100M;
1454                 break;
1455         case 52 * MHz:
1456         case 50 * MHz:
1457                 src_clk = CLK_SDMMC_SEL_50M;
1458                 break;
1459         case 750 * KHz:
1460         case 400 * KHz:
1461                 src_clk = CLK_SDMMC_SEL_750K;
1462                 break;
1463         default:
1464                 return -ENOENT;
1465         }
1466
1467         switch (clk_id) {
1468         case HCLK_SDMMC0:
1469         case CLK_SDMMC0:
1470                 rk_clrsetreg(&cru->clksel_con[30],
1471                              CLK_SDMMC0_SEL_MASK,
1472                              src_clk << CLK_SDMMC0_SEL_SHIFT);
1473                 break;
1474         case CLK_SDMMC1:
1475                 rk_clrsetreg(&cru->clksel_con[30],
1476                              CLK_SDMMC1_SEL_MASK,
1477                              src_clk << CLK_SDMMC1_SEL_SHIFT);
1478                 break;
1479         case CLK_SDMMC2:
1480                 rk_clrsetreg(&cru->clksel_con[32],
1481                              CLK_SDMMC2_SEL_MASK,
1482                              src_clk << CLK_SDMMC2_SEL_SHIFT);
1483                 break;
1484         default:
1485                 return -ENOENT;
1486         }
1487
1488         return rk3568_sdmmc_get_clk(priv, clk_id);
1489 }
1490
1491 static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1492 {
1493         struct rk3568_cru *cru = priv->cru;
1494         u32 sel, con;
1495
1496         con = readl(&cru->clksel_con[28]);
1497         sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1498         switch (sel) {
1499         case SCLK_SFC_SEL_24M:
1500                 return OSC_HZ;
1501         case SCLK_SFC_SEL_50M:
1502                 return 50 * MHz;
1503         case SCLK_SFC_SEL_75M:
1504                 return 75 * MHz;
1505         case SCLK_SFC_SEL_100M:
1506                 return 100 * MHz;
1507         case SCLK_SFC_SEL_125M:
1508                 return 125 * MHz;
1509         case SCLK_SFC_SEL_150M:
1510                 return 150 * KHz;
1511         default:
1512                 return -ENOENT;
1513         }
1514 }
1515
1516 static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1517 {
1518         struct rk3568_cru *cru = priv->cru;
1519         int src_clk;
1520
1521         switch (rate) {
1522         case OSC_HZ:
1523                 src_clk = SCLK_SFC_SEL_24M;
1524                 break;
1525         case 50 * MHz:
1526                 src_clk = SCLK_SFC_SEL_50M;
1527                 break;
1528         case 75 * MHz:
1529                 src_clk = SCLK_SFC_SEL_75M;
1530                 break;
1531         case 100 * MHz:
1532                 src_clk = SCLK_SFC_SEL_100M;
1533                 break;
1534         case 125 * MHz:
1535                 src_clk = SCLK_SFC_SEL_125M;
1536                 break;
1537         case 150 * KHz:
1538                 src_clk = SCLK_SFC_SEL_150M;
1539                 break;
1540         default:
1541                 return -ENOENT;
1542         }
1543
1544         rk_clrsetreg(&cru->clksel_con[28],
1545                      SCLK_SFC_SEL_MASK,
1546                      src_clk << SCLK_SFC_SEL_SHIFT);
1547
1548         return rk3568_sfc_get_clk(priv);
1549 }
1550
1551 static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1552 {
1553         struct rk3568_cru *cru = priv->cru;
1554         u32 sel, con;
1555
1556         con = readl(&cru->clksel_con[28]);
1557         sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1558         switch (sel) {
1559         case NCLK_NANDC_SEL_200M:
1560                 return 200 * MHz;
1561         case NCLK_NANDC_SEL_150M:
1562                 return 150 * MHz;
1563         case NCLK_NANDC_SEL_100M:
1564                 return 100 * MHz;
1565         case NCLK_NANDC_SEL_24M:
1566                 return OSC_HZ;
1567         default:
1568                 return -ENOENT;
1569         }
1570 }
1571
1572 static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1573 {
1574         struct rk3568_cru *cru = priv->cru;
1575         int src_clk;
1576
1577         switch (rate) {
1578         case OSC_HZ:
1579                 src_clk = NCLK_NANDC_SEL_24M;
1580                 break;
1581         case 100 * MHz:
1582                 src_clk = NCLK_NANDC_SEL_100M;
1583                 break;
1584         case 150 * MHz:
1585                 src_clk = NCLK_NANDC_SEL_150M;
1586                 break;
1587         case 200 * MHz:
1588                 src_clk = NCLK_NANDC_SEL_200M;
1589                 break;
1590         default:
1591                 return -ENOENT;
1592         }
1593
1594         rk_clrsetreg(&cru->clksel_con[28],
1595                      NCLK_NANDC_SEL_MASK,
1596                      src_clk << NCLK_NANDC_SEL_SHIFT);
1597
1598         return rk3568_nand_get_clk(priv);
1599 }
1600
1601 static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1602 {
1603         struct rk3568_cru *cru = priv->cru;
1604         u32 sel, con;
1605
1606         con = readl(&cru->clksel_con[28]);
1607         sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1608         switch (sel) {
1609         case CCLK_EMMC_SEL_200M:
1610                 return 200 * MHz;
1611         case CCLK_EMMC_SEL_150M:
1612                 return 150 * MHz;
1613         case CCLK_EMMC_SEL_100M:
1614                 return 100 * MHz;
1615         case CCLK_EMMC_SEL_50M:
1616                 return 50 * MHz;
1617         case CCLK_EMMC_SEL_375K:
1618                 return 375 * KHz;
1619         case CCLK_EMMC_SEL_24M:
1620                 return OSC_HZ;
1621         default:
1622                 return -ENOENT;
1623         }
1624 }
1625
1626 static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1627 {
1628         struct rk3568_cru *cru = priv->cru;
1629         int src_clk;
1630
1631         switch (rate) {
1632         case OSC_HZ:
1633                 src_clk = CCLK_EMMC_SEL_24M;
1634                 break;
1635         case 52 * MHz:
1636         case 50 * MHz:
1637                 src_clk = CCLK_EMMC_SEL_50M;
1638                 break;
1639         case 100 * MHz:
1640                 src_clk = CCLK_EMMC_SEL_100M;
1641                 break;
1642         case 150 * MHz:
1643                 src_clk = CCLK_EMMC_SEL_150M;
1644                 break;
1645         case 200 * MHz:
1646                 src_clk = CCLK_EMMC_SEL_200M;
1647                 break;
1648         case 400 * KHz:
1649         case 375 * KHz:
1650                 src_clk = CCLK_EMMC_SEL_375K;
1651                 break;
1652         default:
1653                 return -ENOENT;
1654         }
1655
1656         rk_clrsetreg(&cru->clksel_con[28],
1657                      CCLK_EMMC_SEL_MASK,
1658                      src_clk << CCLK_EMMC_SEL_SHIFT);
1659
1660         return rk3568_emmc_get_clk(priv);
1661 }
1662
1663 static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1664 {
1665         struct rk3568_cru *cru = priv->cru;
1666         u32 sel, con;
1667
1668         con = readl(&cru->clksel_con[28]);
1669         sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1670         switch (sel) {
1671         case BCLK_EMMC_SEL_200M:
1672                 return 200 * MHz;
1673         case BCLK_EMMC_SEL_150M:
1674                 return 150 * MHz;
1675         case BCLK_EMMC_SEL_125M:
1676                 return 125 * MHz;
1677         default:
1678                 return -ENOENT;
1679         }
1680 }
1681
1682 static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1683 {
1684         struct rk3568_cru *cru = priv->cru;
1685         int src_clk;
1686
1687         switch (rate) {
1688         case 200 * MHz:
1689                 src_clk = BCLK_EMMC_SEL_200M;
1690                 break;
1691         case 150 * MHz:
1692                 src_clk = BCLK_EMMC_SEL_150M;
1693                 break;
1694         case 125 * MHz:
1695                 src_clk = BCLK_EMMC_SEL_125M;
1696                 break;
1697         default:
1698                 return -ENOENT;
1699         }
1700
1701         rk_clrsetreg(&cru->clksel_con[28],
1702                      BCLK_EMMC_SEL_MASK,
1703                      src_clk << BCLK_EMMC_SEL_SHIFT);
1704
1705         return rk3568_emmc_get_bclk(priv);
1706 }
1707
1708 #ifndef CONFIG_SPL_BUILD
1709 static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1710 {
1711         struct rk3568_cru *cru = priv->cru;
1712         u32 div, sel, con, parent;
1713
1714         con = readl(&cru->clksel_con[38]);
1715         div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1716         sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1717         if (sel == ACLK_VOP_PRE_SEL_GPLL)
1718                 parent = priv->gpll_hz;
1719         else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1720                 parent = priv->cpll_hz;
1721         else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1722                 parent = priv->vpll_hz;
1723         else
1724                 parent = priv->hpll_hz;
1725
1726         return DIV_TO_RATE(parent, div);
1727 }
1728
1729 static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1730 {
1731         struct rk3568_cru *cru = priv->cru;
1732         int src_clk_div, src_clk_mux;
1733
1734         if ((priv->cpll_hz % rate) == 0) {
1735                 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1736                 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1737         } else {
1738                 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1739                 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1740         }
1741         assert(src_clk_div - 1 <= 31);
1742         rk_clrsetreg(&cru->clksel_con[38],
1743                      ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1744                      src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1745                      (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1746
1747         return rk3568_aclk_vop_get_clk(priv);
1748 }
1749
1750 static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1751 {
1752         struct rk3568_cru *cru = priv->cru;
1753         u32 conid, div, sel, con, parent;
1754
1755         switch (clk_id) {
1756         case DCLK_VOP0:
1757                 conid = 39;
1758                 break;
1759         case DCLK_VOP1:
1760                 conid = 40;
1761                 break;
1762         case DCLK_VOP2:
1763                 conid = 41;
1764                 break;
1765         default:
1766                 return -ENOENT;
1767         }
1768
1769         con = readl(&cru->clksel_con[conid]);
1770         div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1771         sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1772         if (sel == DCLK_VOP_SEL_HPLL)
1773                 parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1774         else if (sel == DCLK_VOP_SEL_VPLL)
1775                 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1776                                                priv->cru, VPLL);
1777         else if (sel == DCLK_VOP_SEL_GPLL)
1778                 parent = priv->gpll_hz;
1779         else if (sel == DCLK_VOP_SEL_CPLL)
1780                 parent = priv->cpll_hz;
1781         else
1782                 return -ENOENT;
1783
1784         return DIV_TO_RATE(parent, div);
1785 }
1786
1787 #define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1788
1789 static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1790                                      ulong clk_id, ulong rate)
1791 {
1792         struct rk3568_cru *cru = priv->cru;
1793         ulong pll_rate, now, best_rate = 0;
1794         u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1795
1796         switch (clk_id) {
1797         case DCLK_VOP0:
1798                 conid = 39;
1799                 break;
1800         case DCLK_VOP1:
1801                 conid = 40;
1802                 break;
1803         case DCLK_VOP2:
1804                 conid = 41;
1805                 break;
1806         default:
1807                 return -ENOENT;
1808         }
1809
1810         con = readl(&cru->clksel_con[conid]);
1811         sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1812
1813         if (sel == DCLK_VOP_SEL_HPLL) {
1814                 div = 1;
1815                 rk_clrsetreg(&cru->clksel_con[conid],
1816                              DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1817                              (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1818                              ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1819                 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1820         } else if (sel == DCLK_VOP_SEL_VPLL) {
1821                 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1822                 rk_clrsetreg(&cru->clksel_con[conid],
1823                              DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1824                              (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1825                              ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1826                 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1827                                       priv->cru, VPLL, div * rate);
1828         } else {
1829                 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1830                         switch (i) {
1831                         case DCLK_VOP_SEL_GPLL:
1832                                 pll_rate = priv->gpll_hz;
1833                                 break;
1834                         case DCLK_VOP_SEL_CPLL:
1835                                 pll_rate = priv->cpll_hz;
1836                                 break;
1837                         default:
1838                                 printf("do not support this vop pll sel\n");
1839                                 return -EINVAL;
1840                         }
1841
1842                         div = DIV_ROUND_UP(pll_rate, rate);
1843                         if (div > 255)
1844                                 continue;
1845                         now = pll_rate / div;
1846                         if (abs(rate - now) < abs(rate - best_rate)) {
1847                                 best_rate = now;
1848                                 best_div = div;
1849                                 best_sel = i;
1850                         }
1851                         debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1852                               pll_rate, best_rate, best_div, best_sel);
1853                 }
1854
1855                 if (best_rate) {
1856                         rk_clrsetreg(&cru->clksel_con[conid],
1857                                      DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1858                                      best_sel << DCLK0_VOP_SEL_SHIFT |
1859                                      (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1860                 } else {
1861                         printf("do not support this vop freq %lu\n", rate);
1862                         return -EINVAL;
1863                 }
1864         }
1865         return rk3568_dclk_vop_get_clk(priv, clk_id);
1866 }
1867
1868 static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1869                                      ulong mac_id)
1870 {
1871         struct rk3568_cru *cru = priv->cru;
1872         u32 sel, con;
1873
1874         con = readl(&cru->clksel_con[31 + mac_id * 2]);
1875         sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1876
1877         switch (sel) {
1878         case CLK_MAC0_2TOP_SEL_125M:
1879                 return 125 * MHz;
1880         case CLK_MAC0_2TOP_SEL_50M:
1881                 return 50 * MHz;
1882         case CLK_MAC0_2TOP_SEL_25M:
1883                 return 25 * MHz;
1884         case CLK_MAC0_2TOP_SEL_PPLL:
1885                 return rk3568_pmu_pll_get_rate(priv, HPLL);
1886         default:
1887                 return -ENOENT;
1888         }
1889 }
1890
1891 static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1892                                      ulong mac_id, ulong rate)
1893 {
1894         struct rk3568_cru *cru = priv->cru;
1895         int src_clk;
1896
1897         switch (rate) {
1898         case 125 * MHz:
1899                 src_clk = CLK_MAC0_2TOP_SEL_125M;
1900                 break;
1901         case 50 * MHz:
1902                 src_clk = CLK_MAC0_2TOP_SEL_50M;
1903                 break;
1904         case 25 * MHz:
1905                 src_clk = CLK_MAC0_2TOP_SEL_25M;
1906                 break;
1907         default:
1908                 return -ENOENT;
1909         }
1910
1911         rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1912                      CLK_MAC0_2TOP_SEL_MASK,
1913                      src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1914
1915         return rk3568_gmac_src_get_clk(priv, mac_id);
1916 }
1917
1918 static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1919                                      ulong mac_id)
1920 {
1921         struct rk3568_cru *cru = priv->cru;
1922         u32 sel, con;
1923
1924         con = readl(&cru->clksel_con[31 + mac_id * 2]);
1925         sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1926
1927         switch (sel) {
1928         case CLK_MAC0_OUT_SEL_125M:
1929                 return 125 * MHz;
1930         case CLK_MAC0_OUT_SEL_50M:
1931                 return 50 * MHz;
1932         case CLK_MAC0_OUT_SEL_25M:
1933                 return 25 * MHz;
1934         case CLK_MAC0_OUT_SEL_24M:
1935                 return OSC_HZ;
1936         default:
1937                 return -ENOENT;
1938         }
1939 }
1940
1941 static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1942                                      ulong mac_id, ulong rate)
1943 {
1944         struct rk3568_cru *cru = priv->cru;
1945         int src_clk;
1946
1947         switch (rate) {
1948         case 125 * MHz:
1949                 src_clk = CLK_MAC0_OUT_SEL_125M;
1950                 break;
1951         case 50 * MHz:
1952                 src_clk = CLK_MAC0_OUT_SEL_50M;
1953                 break;
1954         case 25 * MHz:
1955                 src_clk = CLK_MAC0_OUT_SEL_25M;
1956                 break;
1957         case 24 * MHz:
1958                 src_clk = CLK_MAC0_OUT_SEL_24M;
1959                 break;
1960         default:
1961                 return -ENOENT;
1962         }
1963
1964         rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1965                      CLK_MAC0_OUT_SEL_MASK,
1966                      src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1967
1968         return rk3568_gmac_out_get_clk(priv, mac_id);
1969 }
1970
1971 static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1972                                          ulong mac_id)
1973 {
1974         struct rk3568_cru *cru = priv->cru;
1975         u32 sel, con;
1976
1977         con = readl(&cru->clksel_con[31 + mac_id * 2]);
1978         sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1979
1980         switch (sel) {
1981         case CLK_GMAC0_PTP_REF_SEL_62_5M:
1982                 return 62500 * KHz;
1983         case CLK_GMAC0_PTP_REF_SEL_100M:
1984                 return 100 * MHz;
1985         case CLK_GMAC0_PTP_REF_SEL_50M:
1986                 return 50 * MHz;
1987         case CLK_GMAC0_PTP_REF_SEL_24M:
1988                 return OSC_HZ;
1989         default:
1990                 return -ENOENT;
1991         }
1992 }
1993
1994 static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1995                                          ulong mac_id, ulong rate)
1996 {
1997         struct rk3568_cru *cru = priv->cru;
1998         int src_clk;
1999
2000         switch (rate) {
2001         case 62500 * KHz:
2002                 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2003                 break;
2004         case 100 * MHz:
2005                 src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2006                 break;
2007         case 50 * MHz:
2008                 src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2009                 break;
2010         case 24 * MHz:
2011                 src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2012                 break;
2013         default:
2014                 return -ENOENT;
2015         }
2016
2017         rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2018                      CLK_GMAC0_PTP_REF_SEL_MASK,
2019                      src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2020
2021         return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2022 }
2023
2024 static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2025                                        ulong mac_id, ulong rate)
2026 {
2027         struct rk3568_cru *cru = priv->cru;
2028         u32 con, sel, div_sel;
2029
2030         con = readl(&cru->clksel_con[31 + mac_id * 2]);
2031         sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2032
2033         if (sel == RMII0_MODE_SEL_RGMII) {
2034                 if (rate == 2500000)
2035                         div_sel = RGMII0_CLK_SEL_2_5M;
2036                 else if (rate == 25000000)
2037                         div_sel = RGMII0_CLK_SEL_25M;
2038                 else
2039                         div_sel = RGMII0_CLK_SEL_125M;
2040                 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2041                              RGMII0_CLK_SEL_MASK,
2042                              div_sel << RGMII0_CLK_SEL_SHIFT);
2043         } else if (sel == RMII0_MODE_SEL_RMII) {
2044                 if (rate == 2500000)
2045                         div_sel = RMII0_CLK_SEL_2_5M;
2046                 else
2047                         div_sel = RMII0_CLK_SEL_25M;
2048                 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2049                              RMII0_CLK_SEL_MASK,
2050                              div_sel << RMII0_CLK_SEL_SHIFT);
2051         }
2052
2053         return 0;
2054 }
2055
2056 static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2057 {
2058         struct rk3568_cru *cru = priv->cru;
2059         u32 con, div, p_rate;
2060
2061         con = readl(&cru->clksel_con[79]);
2062         div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2063         p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2064
2065         con = readl(&cru->clksel_con[43]);
2066         div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2067         switch (div) {
2068         case DCLK_EBC_SEL_GPLL_400M:
2069                 return 400 * MHz;
2070         case DCLK_EBC_SEL_CPLL_333M:
2071                 return p_rate;
2072         case DCLK_EBC_SEL_GPLL_200M:
2073                 return 200 * MHz;
2074         default:
2075                 return -ENOENT;
2076         }
2077 }
2078
2079 static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2080 {
2081         struct rk3568_cru *cru = priv->cru;
2082         int src_clk_div;
2083
2084         src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2085         assert(src_clk_div - 1 <= 31);
2086         rk_clrsetreg(&cru->clksel_con[79],
2087                      CPLL_333M_DIV_MASK,
2088                      (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2089         rk_clrsetreg(&cru->clksel_con[43],
2090                      DCLK_EBC_SEL_MASK,
2091                      DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2092
2093         return rk3568_ebc_get_clk(priv);
2094 }
2095
2096 static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2097 {
2098         struct rk3568_cru *cru = priv->cru;
2099         u32 con, div, src, p_rate;
2100
2101         switch (clk_id) {
2102         case ACLK_RKVDEC_PRE:
2103         case ACLK_RKVDEC:
2104                 con = readl(&cru->clksel_con[47]);
2105                 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2106                 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2107                 if (src == ACLK_RKVDEC_SEL_CPLL)
2108                         p_rate = priv->cpll_hz;
2109                 else
2110                         p_rate = priv->gpll_hz;
2111                 return DIV_TO_RATE(p_rate, div);
2112         case CLK_RKVDEC_CORE:
2113                 con = readl(&cru->clksel_con[49]);
2114                 src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2115                       >> CLK_RKVDEC_CORE_SEL_SHIFT;
2116                 div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2117                       >> CLK_RKVDEC_CORE_DIV_SHIFT;
2118                 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2119                         p_rate = priv->cpll_hz;
2120                 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2121                         p_rate = priv->npll_hz;
2122                 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2123                         p_rate = priv->vpll_hz;
2124                 else
2125                         p_rate = priv->gpll_hz;
2126                 return DIV_TO_RATE(p_rate, div);
2127         default:
2128                 return -ENOENT;
2129         }
2130 }
2131
2132 static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2133                                    ulong clk_id, ulong rate)
2134 {
2135         struct rk3568_cru *cru = priv->cru;
2136         int src_clk_div, src, p_rate;
2137
2138         switch (clk_id) {
2139         case ACLK_RKVDEC_PRE:
2140         case ACLK_RKVDEC:
2141                 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2142                       >> ACLK_RKVDEC_SEL_SHIFT;
2143                 if (src == ACLK_RKVDEC_SEL_CPLL)
2144                         p_rate = priv->cpll_hz;
2145                 else
2146                         p_rate = priv->gpll_hz;
2147                 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2148                 assert(src_clk_div - 1 <= 31);
2149                 rk_clrsetreg(&cru->clksel_con[47],
2150                              ACLK_RKVDEC_SEL_MASK |
2151                              ACLK_RKVDEC_DIV_MASK,
2152                              (src << ACLK_RKVDEC_SEL_SHIFT) |
2153                              (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2154                 break;
2155         case CLK_RKVDEC_CORE:
2156                 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2157                       >> CLK_RKVDEC_CORE_SEL_SHIFT;
2158                 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2159                         p_rate = priv->cpll_hz;
2160                 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2161                         p_rate = priv->npll_hz;
2162                 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2163                         p_rate = priv->vpll_hz;
2164                 else
2165                         p_rate = priv->gpll_hz;
2166                 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2167                 assert(src_clk_div - 1 <= 31);
2168                 rk_clrsetreg(&cru->clksel_con[49],
2169                              CLK_RKVDEC_CORE_SEL_MASK |
2170                              CLK_RKVDEC_CORE_DIV_MASK,
2171                              (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2172                              (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2173                 break;
2174         default:
2175                 return -ENOENT;
2176         }
2177
2178         return rk3568_rkvdec_get_clk(priv, clk_id);
2179 }
2180
2181 static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2182 {
2183         struct rk3568_cru *cru = priv->cru;
2184         u32 reg, con, fracdiv, div, src, p_src, p_rate;
2185         unsigned long m, n;
2186
2187         switch (clk_id) {
2188         case SCLK_UART1:
2189                 reg = 52;
2190                 break;
2191         case SCLK_UART2:
2192                 reg = 54;
2193                 break;
2194         case SCLK_UART3:
2195                 reg = 56;
2196                 break;
2197         case SCLK_UART4:
2198                 reg = 58;
2199                 break;
2200         case SCLK_UART5:
2201                 reg = 60;
2202                 break;
2203         case SCLK_UART6:
2204                 reg = 62;
2205                 break;
2206         case SCLK_UART7:
2207                 reg = 64;
2208                 break;
2209         case SCLK_UART8:
2210                 reg = 66;
2211                 break;
2212         case SCLK_UART9:
2213                 reg = 68;
2214                 break;
2215         default:
2216                 return -ENOENT;
2217         }
2218         con = readl(&cru->clksel_con[reg]);
2219         src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2220         div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2221         p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2222         if (p_src == CLK_UART_SRC_SEL_GPLL)
2223                 p_rate = priv->gpll_hz;
2224         else if (p_src == CLK_UART_SRC_SEL_CPLL)
2225                 p_rate = priv->cpll_hz;
2226         else
2227                 p_rate = 480000000;
2228         if (src == CLK_UART_SEL_SRC) {
2229                 return DIV_TO_RATE(p_rate, div);
2230         } else if (src == CLK_UART_SEL_FRAC) {
2231                 fracdiv = readl(&cru->clksel_con[reg + 1]);
2232                 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2233                 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2234                 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2235                 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2236                 return DIV_TO_RATE(p_rate, div) * n / m;
2237         } else {
2238                 return OSC_HZ;
2239         }
2240 }
2241
2242 static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2243                                   ulong clk_id, ulong rate)
2244 {
2245         struct rk3568_cru *cru = priv->cru;
2246         u32 reg, clk_src, uart_src, div;
2247         unsigned long m = 0, n = 0, val;
2248
2249         if (priv->gpll_hz % rate == 0) {
2250                 clk_src = CLK_UART_SRC_SEL_GPLL;
2251                 uart_src = CLK_UART_SEL_SRC;
2252                 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2253         } else if (priv->cpll_hz % rate == 0) {
2254                 clk_src = CLK_UART_SRC_SEL_CPLL;
2255                 uart_src = CLK_UART_SEL_SRC;
2256                 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2257         } else if (rate == OSC_HZ) {
2258                 clk_src = CLK_UART_SRC_SEL_GPLL;
2259                 uart_src = CLK_UART_SEL_XIN24M;
2260                 div = 2;
2261         } else {
2262                 clk_src = CLK_UART_SRC_SEL_GPLL;
2263                 uart_src = CLK_UART_SEL_FRAC;
2264                 div = 2;
2265                 rational_best_approximation(rate, priv->gpll_hz / div,
2266                                             GENMASK(16 - 1, 0),
2267                                             GENMASK(16 - 1, 0),
2268                                             &m, &n);
2269         }
2270
2271         switch (clk_id) {
2272         case SCLK_UART1:
2273                 reg = 52;
2274                 break;
2275         case SCLK_UART2:
2276                 reg = 54;
2277                 break;
2278         case SCLK_UART3:
2279                 reg = 56;
2280                 break;
2281         case SCLK_UART4:
2282                 reg = 58;
2283                 break;
2284         case SCLK_UART5:
2285                 reg = 60;
2286                 break;
2287         case SCLK_UART6:
2288                 reg = 62;
2289                 break;
2290         case SCLK_UART7:
2291                 reg = 64;
2292                 break;
2293         case SCLK_UART8:
2294                 reg = 66;
2295                 break;
2296         case SCLK_UART9:
2297                 reg = 68;
2298                 break;
2299         default:
2300                 return -ENOENT;
2301         }
2302         rk_clrsetreg(&cru->clksel_con[reg],
2303                      CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2304                      CLK_UART_SRC_DIV_MASK,
2305                      (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2306                      (uart_src << CLK_UART_SEL_SHIFT) |
2307                      ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2308         if (m && n) {
2309                 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2310                 writel(val, &cru->clksel_con[reg + 1]);
2311         }
2312
2313         return rk3568_uart_get_rate(priv, clk_id);
2314 }
2315 #endif
2316
2317 static ulong rk3568_clk_get_rate(struct clk *clk)
2318 {
2319         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2320         ulong rate = 0;
2321
2322         if (!priv->gpll_hz) {
2323                 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2324                 return -ENOENT;
2325         }
2326
2327         switch (clk->id) {
2328         case PLL_APLL:
2329         case ARMCLK:
2330                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2331                                              APLL);
2332                 break;
2333         case PLL_CPLL:
2334                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2335                                              CPLL);
2336                 break;
2337         case PLL_GPLL:
2338                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2339                                              GPLL);
2340                 break;
2341         case PLL_NPLL:
2342                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2343                                              NPLL);
2344                 break;
2345         case PLL_VPLL:
2346                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2347                                              VPLL);
2348                 break;
2349         case PLL_DPLL:
2350                 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2351                                              DPLL);
2352                 break;
2353         case ACLK_BUS:
2354         case PCLK_BUS:
2355         case PCLK_WDT_NS:
2356                 rate = rk3568_bus_get_clk(priv, clk->id);
2357                 break;
2358         case ACLK_PERIMID:
2359         case HCLK_PERIMID:
2360                 rate = rk3568_perimid_get_clk(priv, clk->id);
2361                 break;
2362         case ACLK_TOP_HIGH:
2363         case ACLK_TOP_LOW:
2364         case HCLK_TOP:
2365         case PCLK_TOP:
2366                 rate = rk3568_top_get_clk(priv, clk->id);
2367                 break;
2368         case CLK_I2C1:
2369         case CLK_I2C2:
2370         case CLK_I2C3:
2371         case CLK_I2C4:
2372         case CLK_I2C5:
2373                 rate = rk3568_i2c_get_clk(priv, clk->id);
2374                 break;
2375         case CLK_SPI0:
2376         case CLK_SPI1:
2377         case CLK_SPI2:
2378         case CLK_SPI3:
2379                 rate = rk3568_spi_get_clk(priv, clk->id);
2380                 break;
2381         case CLK_PWM1:
2382         case CLK_PWM2:
2383         case CLK_PWM3:
2384                 rate = rk3568_pwm_get_clk(priv, clk->id);
2385                 break;
2386         case CLK_SARADC:
2387         case CLK_TSADC_TSEN:
2388         case CLK_TSADC:
2389                 rate = rk3568_adc_get_clk(priv, clk->id);
2390                 break;
2391         case HCLK_SDMMC0:
2392         case CLK_SDMMC0:
2393         case CLK_SDMMC1:
2394         case CLK_SDMMC2:
2395                 rate = rk3568_sdmmc_get_clk(priv, clk->id);
2396                 break;
2397         case SCLK_SFC:
2398                 rate = rk3568_sfc_get_clk(priv);
2399                 break;
2400         case NCLK_NANDC:
2401                 rate = rk3568_nand_get_clk(priv);
2402                 break;
2403         case CCLK_EMMC:
2404                 rate = rk3568_emmc_get_clk(priv);
2405                 break;
2406         case BCLK_EMMC:
2407                 rate = rk3568_emmc_get_bclk(priv);
2408                 break;
2409 #ifndef CONFIG_SPL_BUILD
2410         case ACLK_VOP:
2411                 rate = rk3568_aclk_vop_get_clk(priv);
2412                 break;
2413         case DCLK_VOP0:
2414         case DCLK_VOP1:
2415         case DCLK_VOP2:
2416                 rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2417                 break;
2418         case SCLK_GMAC0:
2419         case CLK_MAC0_2TOP:
2420         case CLK_MAC0_REFOUT:
2421                 rate = rk3568_gmac_src_get_clk(priv, 0);
2422                 break;
2423         case CLK_MAC0_OUT:
2424                 rate = rk3568_gmac_out_get_clk(priv, 0);
2425                 break;
2426         case CLK_GMAC0_PTP_REF:
2427                 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2428                 break;
2429         case SCLK_GMAC1:
2430         case CLK_MAC1_2TOP:
2431         case CLK_MAC1_REFOUT:
2432                 rate = rk3568_gmac_src_get_clk(priv, 1);
2433                 break;
2434         case CLK_MAC1_OUT:
2435                 rate = rk3568_gmac_out_get_clk(priv, 1);
2436                 break;
2437         case CLK_GMAC1_PTP_REF:
2438                 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2439                 break;
2440         case DCLK_EBC:
2441                 rate = rk3568_ebc_get_clk(priv);
2442                 break;
2443         case ACLK_RKVDEC_PRE:
2444         case ACLK_RKVDEC:
2445         case CLK_RKVDEC_CORE:
2446                 rate = rk3568_rkvdec_get_clk(priv, clk->id);
2447                 break;
2448         case TCLK_WDT_NS:
2449                 rate = OSC_HZ;
2450                 break;
2451         case SCLK_UART1:
2452         case SCLK_UART2:
2453         case SCLK_UART3:
2454         case SCLK_UART4:
2455         case SCLK_UART5:
2456         case SCLK_UART6:
2457         case SCLK_UART7:
2458         case SCLK_UART8:
2459         case SCLK_UART9:
2460                 rate = rk3568_uart_get_rate(priv, clk->id);
2461                 break;
2462 #endif
2463         case ACLK_SECURE_FLASH:
2464         case ACLK_CRYPTO_NS:
2465         case HCLK_SECURE_FLASH:
2466         case HCLK_CRYPTO_NS:
2467         case CLK_CRYPTO_NS_RNG:
2468         case CLK_CRYPTO_NS_CORE:
2469         case CLK_CRYPTO_NS_PKA:
2470                 rate = rk3568_crypto_get_rate(priv, clk->id);
2471                 break;
2472         case CPLL_500M:
2473         case CPLL_333M:
2474         case CPLL_250M:
2475         case CPLL_125M:
2476         case CPLL_100M:
2477         case CPLL_62P5M:
2478         case CPLL_50M:
2479         case CPLL_25M:
2480                 rate = rk3568_cpll_div_get_rate(priv, clk->id);
2481                 break;
2482         default:
2483                 return -ENOENT;
2484         }
2485
2486         return rate;
2487 };
2488
2489 static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2490 {
2491         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2492         ulong ret = 0;
2493
2494         if (!priv->gpll_hz) {
2495                 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2496                 return -ENOENT;
2497         }
2498
2499         switch (clk->id) {
2500         case PLL_APLL:
2501         case ARMCLK:
2502                 if (priv->armclk_hz)
2503                         rk3568_armclk_set_clk(priv, rate);
2504                 priv->armclk_hz = rate;
2505                 break;
2506         case PLL_CPLL:
2507                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2508                                             CPLL, rate);
2509                 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2510                                                       priv->cru, CPLL);
2511                 break;
2512         case PLL_GPLL:
2513                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2514                                             GPLL, rate);
2515                 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2516                                                       priv->cru, GPLL);
2517                 break;
2518         case PLL_NPLL:
2519                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2520                                             NPLL, rate);
2521                 break;
2522         case PLL_VPLL:
2523                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2524                                             VPLL, rate);
2525                 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2526                                                       priv->cru,
2527                                                       VPLL);
2528                 break;
2529         case ACLK_BUS:
2530         case PCLK_BUS:
2531         case PCLK_WDT_NS:
2532                 ret = rk3568_bus_set_clk(priv, clk->id, rate);
2533                 break;
2534         case ACLK_PERIMID:
2535         case HCLK_PERIMID:
2536                 ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2537                 break;
2538         case ACLK_TOP_HIGH:
2539         case ACLK_TOP_LOW:
2540         case HCLK_TOP:
2541         case PCLK_TOP:
2542                 ret = rk3568_top_set_clk(priv, clk->id, rate);
2543                 break;
2544         case CLK_I2C1:
2545         case CLK_I2C2:
2546         case CLK_I2C3:
2547         case CLK_I2C4:
2548         case CLK_I2C5:
2549                 ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2550                 break;
2551         case CLK_SPI0:
2552         case CLK_SPI1:
2553         case CLK_SPI2:
2554         case CLK_SPI3:
2555                 ret = rk3568_spi_set_clk(priv, clk->id, rate);
2556                 break;
2557         case CLK_PWM1:
2558         case CLK_PWM2:
2559         case CLK_PWM3:
2560                 ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2561                 break;
2562         case CLK_SARADC:
2563         case CLK_TSADC_TSEN:
2564         case CLK_TSADC:
2565                 ret = rk3568_adc_set_clk(priv, clk->id, rate);
2566                 break;
2567         case HCLK_SDMMC0:
2568         case CLK_SDMMC0:
2569         case CLK_SDMMC1:
2570         case CLK_SDMMC2:
2571                 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2572                 break;
2573         case SCLK_SFC:
2574                 ret = rk3568_sfc_set_clk(priv, rate);
2575                 break;
2576         case NCLK_NANDC:
2577                 ret = rk3568_nand_set_clk(priv, rate);
2578                 break;
2579         case CCLK_EMMC:
2580                 ret = rk3568_emmc_set_clk(priv, rate);
2581                 break;
2582         case BCLK_EMMC:
2583                 ret = rk3568_emmc_set_bclk(priv, rate);
2584                 break;
2585 #ifndef CONFIG_SPL_BUILD
2586         case ACLK_VOP:
2587                 ret = rk3568_aclk_vop_set_clk(priv, rate);
2588                 break;
2589         case DCLK_VOP0:
2590         case DCLK_VOP1:
2591         case DCLK_VOP2:
2592                 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2593                 break;
2594         case SCLK_GMAC0:
2595         case CLK_MAC0_2TOP:
2596         case CLK_MAC0_REFOUT:
2597                 ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2598                 break;
2599         case CLK_MAC0_OUT:
2600                 ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2601                 break;
2602         case SCLK_GMAC0_RX_TX:
2603                 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2604                 break;
2605         case CLK_GMAC0_PTP_REF:
2606                 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2607                 break;
2608         case SCLK_GMAC1:
2609         case CLK_MAC1_2TOP:
2610         case CLK_MAC1_REFOUT:
2611                 ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2612                 break;
2613         case CLK_MAC1_OUT:
2614                 ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2615                 break;
2616         case SCLK_GMAC1_RX_TX:
2617                 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2618                 break;
2619         case CLK_GMAC1_PTP_REF:
2620                 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2621                 break;
2622         case DCLK_EBC:
2623                 ret = rk3568_ebc_set_clk(priv, rate);
2624                 break;
2625         case ACLK_RKVDEC_PRE:
2626         case ACLK_RKVDEC:
2627         case CLK_RKVDEC_CORE:
2628                 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2629                 break;
2630         case TCLK_WDT_NS:
2631                 ret = OSC_HZ;
2632                 break;
2633         case SCLK_UART1:
2634         case SCLK_UART2:
2635         case SCLK_UART3:
2636         case SCLK_UART4:
2637         case SCLK_UART5:
2638         case SCLK_UART6:
2639         case SCLK_UART7:
2640         case SCLK_UART8:
2641         case SCLK_UART9:
2642                 ret = rk3568_uart_set_rate(priv, clk->id, rate);
2643                 break;
2644 #endif
2645         case ACLK_SECURE_FLASH:
2646         case ACLK_CRYPTO_NS:
2647         case HCLK_SECURE_FLASH:
2648         case HCLK_CRYPTO_NS:
2649         case CLK_CRYPTO_NS_RNG:
2650         case CLK_CRYPTO_NS_CORE:
2651         case CLK_CRYPTO_NS_PKA:
2652                 ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2653                 break;
2654         case CPLL_500M:
2655         case CPLL_333M:
2656         case CPLL_250M:
2657         case CPLL_125M:
2658         case CPLL_100M:
2659         case CPLL_62P5M:
2660         case CPLL_50M:
2661         case CPLL_25M:
2662                 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2663                 break;
2664         default:
2665                 return -ENOENT;
2666         }
2667
2668         return ret;
2669 };
2670
2671 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2672 static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2673 {
2674         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2675         struct rk3568_cru *cru = priv->cru;
2676
2677         if (parent->id == CLK_MAC0_2TOP)
2678                 rk_clrsetreg(&cru->clksel_con[31],
2679                              RMII0_EXTCLK_SEL_MASK,
2680                              RMII0_EXTCLK_SEL_MAC0_TOP <<
2681                              RMII0_EXTCLK_SEL_SHIFT);
2682         else
2683                 rk_clrsetreg(&cru->clksel_con[31],
2684                              RMII0_EXTCLK_SEL_MASK,
2685                              RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2686         return 0;
2687 }
2688
2689 static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2690 {
2691         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2692         struct rk3568_cru *cru = priv->cru;
2693
2694         if (parent->id == CLK_MAC1_2TOP)
2695                 rk_clrsetreg(&cru->clksel_con[33],
2696                              RMII0_EXTCLK_SEL_MASK,
2697                              RMII0_EXTCLK_SEL_MAC0_TOP <<
2698                              RMII0_EXTCLK_SEL_SHIFT);
2699         else
2700                 rk_clrsetreg(&cru->clksel_con[33],
2701                              RMII0_EXTCLK_SEL_MASK,
2702                              RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2703         return 0;
2704 }
2705
2706 static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2707 {
2708         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2709         struct rk3568_cru *cru = priv->cru;
2710
2711         if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2712                 rk_clrsetreg(&cru->clksel_con[31],
2713                              RMII0_MODE_MASK,
2714                              RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2715         else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2716                 rk_clrsetreg(&cru->clksel_con[31],
2717                              RMII0_MODE_MASK,
2718                              RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2719         else
2720                 rk_clrsetreg(&cru->clksel_con[31],
2721                              RMII0_MODE_MASK,
2722                              RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2723
2724         return 0;
2725 }
2726
2727 static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2728 {
2729         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2730         struct rk3568_cru *cru = priv->cru;
2731
2732         if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2733                 rk_clrsetreg(&cru->clksel_con[33],
2734                              RMII0_MODE_MASK,
2735                              RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2736         else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2737                 rk_clrsetreg(&cru->clksel_con[33],
2738                              RMII0_MODE_MASK,
2739                              RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2740         else
2741                 rk_clrsetreg(&cru->clksel_con[33],
2742                              RMII0_MODE_MASK,
2743                              RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2744
2745         return 0;
2746 }
2747
2748 static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2749 {
2750         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2751         struct rk3568_cru *cru = priv->cru;
2752         u32 con_id;
2753
2754         switch (clk->id) {
2755         case DCLK_VOP0:
2756                 con_id = 39;
2757                 break;
2758         case DCLK_VOP1:
2759                 con_id = 40;
2760                 break;
2761         case DCLK_VOP2:
2762                 con_id = 41;
2763                 break;
2764         default:
2765                 return -EINVAL;
2766         }
2767         if (parent->id == PLL_VPLL) {
2768                 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2769                              DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
2770         } else {
2771                 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2772                              DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
2773         }
2774
2775         return 0;
2776 }
2777
2778 static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2779 {
2780         struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2781         struct rk3568_cru *cru = priv->cru;
2782         u32 con_id, mask, shift;
2783
2784         switch (clk->id) {
2785         case ACLK_RKVDEC_PRE:
2786                 con_id = 47;
2787                 mask = ACLK_RKVDEC_SEL_MASK;
2788                 shift = ACLK_RKVDEC_SEL_SHIFT;
2789                 break;
2790         case CLK_RKVDEC_CORE:
2791                 con_id = 49;
2792                 mask = CLK_RKVDEC_CORE_SEL_MASK;
2793                 shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2794                 break;
2795         default:
2796                 return -EINVAL;
2797         }
2798         if (parent->id == PLL_CPLL) {
2799                 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2800                              ACLK_RKVDEC_SEL_CPLL << shift);
2801         } else {
2802                 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2803                              ACLK_RKVDEC_SEL_GPLL << shift);
2804         }
2805
2806         return 0;
2807 }
2808
2809 static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2810 {
2811         switch (clk->id) {
2812         case SCLK_GMAC0:
2813                 return rk3568_gmac0_src_set_parent(clk, parent);
2814         case SCLK_GMAC1:
2815                 return rk3568_gmac1_src_set_parent(clk, parent);
2816         case SCLK_GMAC0_RX_TX:
2817                 return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2818         case SCLK_GMAC1_RX_TX:
2819                 return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2820         case DCLK_VOP0:
2821         case DCLK_VOP1:
2822         case DCLK_VOP2:
2823                 return rk3568_dclk_vop_set_parent(clk, parent);
2824         case ACLK_RKVDEC_PRE:
2825         case CLK_RKVDEC_CORE:
2826                 return rk3568_rkvdec_set_parent(clk, parent);
2827         default:
2828                 return -ENOENT;
2829         }
2830
2831         return 0;
2832 }
2833 #endif
2834
2835 static struct clk_ops rk3568_clk_ops = {
2836         .get_rate = rk3568_clk_get_rate,
2837         .set_rate = rk3568_clk_set_rate,
2838 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2839         .set_parent = rk3568_clk_set_parent,
2840 #endif
2841 };
2842
2843 static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2844 {
2845         int ret;
2846
2847         priv->sync_kernel = false;
2848         if (!priv->armclk_enter_hz) {
2849                 priv->armclk_enter_hz =
2850                         rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2851                                               priv->cru, APLL);
2852                 priv->armclk_init_hz = priv->armclk_enter_hz;
2853         }
2854
2855         if (priv->armclk_init_hz != APLL_HZ) {
2856                 ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2857                 if (!ret)
2858                         priv->armclk_init_hz = APLL_HZ;
2859         }
2860         if (priv->cpll_hz != CPLL_HZ) {
2861                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2862                                             CPLL, CPLL_HZ);
2863                 if (!ret)
2864                         priv->cpll_hz = CPLL_HZ;
2865         }
2866         if (priv->gpll_hz != GPLL_HZ) {
2867                 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2868                                             GPLL, GPLL_HZ);
2869                 if (!ret)
2870                         priv->gpll_hz = GPLL_HZ;
2871         }
2872
2873 #ifdef CONFIG_SPL_BUILD
2874         ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2875         if (ret < 0)
2876                 printf("Fail to set the ACLK_BUS clock.\n");
2877 #endif
2878
2879         priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2880         priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2881 }
2882
2883 static int rk3568_clk_probe(struct udevice *dev)
2884 {
2885         struct rk3568_clk_priv *priv = dev_get_priv(dev);
2886         int ret;
2887
2888         priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2889         if (IS_ERR(priv->grf))
2890                 return PTR_ERR(priv->grf);
2891
2892         rk3568_clk_init(priv);
2893
2894         /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2895         ret = clk_set_defaults(dev, 1);
2896         if (ret)
2897                 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2898         else
2899                 priv->sync_kernel = true;
2900
2901         return 0;
2902 }
2903
2904 static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2905 {
2906         struct rk3568_clk_priv *priv = dev_get_priv(dev);
2907
2908         priv->cru = dev_read_addr_ptr(dev);
2909
2910         return 0;
2911 }
2912
2913 static int rk3568_clk_bind(struct udevice *dev)
2914 {
2915         int ret;
2916         struct udevice *sys_child;
2917         struct sysreset_reg *priv;
2918
2919         /* The reset driver does not have a device node, so bind it here */
2920         ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2921                                  &sys_child);
2922         if (ret) {
2923                 debug("Warning: No sysreset driver: ret=%d\n", ret);
2924         } else {
2925                 priv = malloc(sizeof(struct sysreset_reg));
2926                 priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2927                                                     glb_srst_fst);
2928                 priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2929                                                     glb_srsr_snd);
2930         }
2931
2932 #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2933         ret = offsetof(struct rk3568_cru, softrst_con[0]);
2934         ret = rockchip_reset_bind(dev, ret, 30);
2935         if (ret)
2936                 debug("Warning: software reset driver bind faile\n");
2937 #endif
2938
2939         return 0;
2940 }
2941
2942 static const struct udevice_id rk3568_clk_ids[] = {
2943         { .compatible = "rockchip,rk3568-cru" },
2944         { }
2945 };
2946
2947 U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2948         .name           = "rockchip_rk3568_cru",
2949         .id             = UCLASS_CLK,
2950         .of_match       = rk3568_clk_ids,
2951         .priv_auto = sizeof(struct rk3568_clk_priv),
2952         .of_to_plat = rk3568_clk_ofdata_to_platdata,
2953         .ops            = &rk3568_clk_ops,
2954         .bind           = rk3568_clk_bind,
2955         .probe          = rk3568_clk_probe,
2956 #if CONFIG_IS_ENABLED(OF_PLATDATA)
2957         .plat_auto      = sizeof(struct rk3568_clk_plat),
2958 #endif
2959 };
This page took 0.200455 seconds and 4 git commands to generate.