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