1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
4 * Author: Elaine Zhang <zhangqing@rock-chips.com>
5 */
6
7 #include <common.h>
8 #include <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk3576.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rockchip,rk3576-cru.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
23
24 #if 1
25 static struct rockchip_pll_rate_table rk3576_24m_pll_rates[] = {
26 /* _mhz, _p, _m, _s, _k */
27 RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
28 RK3588_PLL_RATE(1200000000, 1, 100, 1, 0),
29 RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
30 RK3588_PLL_RATE(1150000000, 3, 575, 2, 0),
31 RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
32 RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
33 RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
34 RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
35 RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
36 RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
37 RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
38 RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
39 RK3588_PLL_RATE(742500000, 4, 495, 2, 0),
40 RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
41 RK3588_PLL_RATE(610400000, 3, 305, 2, 13107),
42 RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
43 RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
44 RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
45 RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
46 { /* sentinel */ },
47 };
48 #else
49 static struct rockchip_pll_rate_table rk3576_26m_pll_rates[] = {
50 /* _mhz, _p, _m, _s, _k */
51 RK3588_PLL_RATE(1188000000, 2, 183, 1, 50412),
52 RK3588_PLL_RATE(1100000000, 2, 338, 2, 30247),
53 RK3588_PLL_RATE(1014000000, 1, 156, 2, 0),
54 RK3588_PLL_RATE(1000000000, 2, 308, 2, 45371),
55 RK3588_PLL_RATE(858000000, 1, 132, 2, 0),
56 RK3588_PLL_RATE(806000000, 1, 124, 2, 0),
57 RK3588_PLL_RATE(786432000, 2, 242, 2, 64165),
58 RK3588_PLL_RATE(594000000, 2, 183, 2, 50412),
59 RK3588_PLL_RATE(297000000, 2, 183, 3, 50412),
60 RK3588_PLL_RATE(148500000, 2, 183, 4, 50412),
61 { /* sentinel */ },
62 };
63 #endif
64
65 static struct rockchip_pll_clock rk3576_pll_clks[] = {
66 [BPLL] = PLL(pll_rk3588, PLL_BPLL, RK3576_PLL_CON(0),
67 RK3576_BPLL_MODE_CON0, 0, 15, 0,
68 rk3576_24m_pll_rates),
69 [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3576_LPLL_CON(16),
70 RK3576_LPLL_MODE_CON0, 0, 15, 0, rk3576_24m_pll_rates),
71 [VPLL] = PLL(pll_rk3588, PLL_VPLL, RK3576_PLL_CON(88),
72 RK3576_LPLL_MODE_CON0, 4, 15, 0, rk3576_24m_pll_rates),
73 [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3576_PLL_CON(96),
74 RK3576_MODE_CON0, 6, 15, 0, rk3576_24m_pll_rates),
75 [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3576_PLL_CON(104),
76 RK3576_MODE_CON0, 8, 15, 0, rk3576_24m_pll_rates),
77 [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3576_PLL_CON(112),
78 RK3576_MODE_CON0, 2, 15, 0, rk3576_24m_pll_rates),
79 [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3576_PMU_PLL_CON(128),
80 RK3576_MODE_CON0, 10, 15, 0, rk3576_24m_pll_rates),
81 };
82
83 #ifndef CONFIG_SPL_BUILD
84 #define RK3576_CLK_DUMP(_id, _name, _iscru) \
85 { \
86 .id = _id, \
87 .name = _name, \
88 .is_cru = _iscru, \
89 }
90
91 static const struct rk3576_clk_info clks_dump[] = {
92 RK3576_CLK_DUMP(PLL_BPLL, "bpll", true),
93 RK3576_CLK_DUMP(PLL_LPLL, "lpll", true),
94 RK3576_CLK_DUMP(PLL_VPLL, "vpll", true),
95 RK3576_CLK_DUMP(PLL_AUPLL, "aupll", true),
96 RK3576_CLK_DUMP(PLL_CPLL, "cpll", true),
97 RK3576_CLK_DUMP(PLL_GPLL, "gpll", true),
98 RK3576_CLK_DUMP(PLL_PPLL, "ppll", true),
99 RK3576_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
100 RK3576_CLK_DUMP(PCLK_BUS_ROOT, "pclk_bus_root", true),
101 RK3576_CLK_DUMP(HCLK_BUS_ROOT, "hclk_bus_root", true),
102 RK3576_CLK_DUMP(ACLK_TOP, "aclk_top", true),
103 RK3576_CLK_DUMP(ACLK_TOP_MID, "aclk_top_mid", true),
104 RK3576_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top", true),
105 RK3576_CLK_DUMP(HCLK_TOP, "hclk_top", true),
106 };
107 #endif
108
109 #ifdef CONFIG_SPL_BUILD
110 #ifndef BITS_WITH_WMASK
111 #define BITS_WITH_WMASK(bits, msk, shift) \
112 ((bits) << (shift)) | ((msk) << ((shift) + 16))
113 #endif
114 #endif
115
116 #ifndef CONFIG_SPL_BUILD
117 /*
118 *
119 * rational_best_approximation(31415, 10000,
120 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
121 *
122 * you may look at given_numerator as a fixed point number,
123 * with the fractional part size described in given_denominator.
124 *
125 * for theoretical background, see:
126 * http://en.wikipedia.org/wiki/Continued_fraction
127 */
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)128 static void rational_best_approximation(unsigned long given_numerator,
129 unsigned long given_denominator,
130 unsigned long max_numerator,
131 unsigned long max_denominator,
132 unsigned long *best_numerator,
133 unsigned long *best_denominator)
134 {
135 unsigned long n, d, n0, d0, n1, d1;
136
137 n = given_numerator;
138 d = given_denominator;
139 n0 = 0;
140 d1 = 0;
141 n1 = 1;
142 d0 = 1;
143 for (;;) {
144 unsigned long t, a;
145
146 if (n1 > max_numerator || d1 > max_denominator) {
147 n1 = n0;
148 d1 = d0;
149 break;
150 }
151 if (d == 0)
152 break;
153 t = d;
154 a = n / d;
155 d = n % d;
156 n = t;
157 t = n0 + a * n1;
158 n0 = n1;
159 n1 = t;
160 t = d0 + a * d1;
161 d0 = d1;
162 d1 = t;
163 }
164 *best_numerator = n1;
165 *best_denominator = d1;
166 }
167 #endif
168
rk3576_bus_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)169 static ulong rk3576_bus_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
170 {
171 struct rk3576_cru *cru = priv->cru;
172 u32 con, sel, div, rate;
173
174 switch (clk_id) {
175 case ACLK_BUS_ROOT:
176 con = readl(&cru->clksel_con[55]);
177 sel = (con & ACLK_BUS_ROOT_SEL_MASK) >>
178 ACLK_BUS_ROOT_SEL_SHIFT;
179 div = (con & ACLK_BUS_ROOT_DIV_MASK) >>
180 ACLK_BUS_ROOT_DIV_SHIFT;
181 if (sel == ACLK_BUS_ROOT_SEL_CPLL)
182 rate = DIV_TO_RATE(priv->cpll_hz , div);
183 else
184 rate = DIV_TO_RATE(priv->gpll_hz, div);
185 break;
186 case HCLK_BUS_ROOT:
187 con = readl(&cru->clksel_con[55]);
188 sel = (con & HCLK_BUS_ROOT_SEL_MASK) >>
189 HCLK_BUS_ROOT_SEL_SHIFT;
190 if (sel == HCLK_BUS_ROOT_SEL_200M)
191 rate = 198 * MHz;
192 else if (sel == HCLK_BUS_ROOT_SEL_100M)
193 rate = 100 * MHz;
194 else if (sel == HCLK_BUS_ROOT_SEL_50M)
195 rate = 50 * MHz;
196 else
197 rate = OSC_HZ;
198 break;
199 case PCLK_BUS_ROOT:
200 con = readl(&cru->clksel_con[55]);
201 sel = (con & PCLK_BUS_ROOT_SEL_MASK) >>
202 PCLK_BUS_ROOT_SEL_SHIFT;
203 if (sel == PCLK_BUS_ROOT_SEL_100M)
204 rate = 100 * MHz;
205 else if (sel == PCLK_BUS_ROOT_SEL_50M)
206 rate = 50 * MHz;
207 else
208 rate = OSC_HZ;
209 break;
210 default:
211 return -ENOENT;
212 }
213
214 return rate;
215 }
216
rk3576_bus_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)217 static ulong rk3576_bus_set_clk(struct rk3576_clk_priv *priv,
218 ulong clk_id, ulong rate)
219 {
220 struct rk3576_cru *cru = priv->cru;
221 int src_clk, src_clk_div;
222
223 switch (clk_id) {
224 case ACLK_BUS_ROOT:
225 if (!(priv->cpll_hz % rate)) {
226 src_clk = ACLK_BUS_ROOT_SEL_CPLL;
227 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
228 } else {
229 src_clk = ACLK_BUS_ROOT_SEL_GPLL;
230 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
231 }
232 rk_clrsetreg(&cru->clksel_con[55],
233 ACLK_BUS_ROOT_SEL_MASK,
234 src_clk << ACLK_BUS_ROOT_SEL_SHIFT);
235 assert(src_clk_div - 1 <= 31);
236 rk_clrsetreg(&cru->clksel_con[55],
237 ACLK_BUS_ROOT_DIV_MASK |
238 ACLK_BUS_ROOT_SEL_MASK,
239 (src_clk <<
240 ACLK_BUS_ROOT_SEL_SHIFT) |
241 (src_clk_div - 1) << ACLK_BUS_ROOT_DIV_SHIFT);
242 break;
243 case HCLK_BUS_ROOT:
244 if (rate >= 198 * MHz)
245 src_clk = HCLK_BUS_ROOT_SEL_200M;
246 else if (rate >= 99 * MHz)
247 src_clk = HCLK_BUS_ROOT_SEL_100M;
248 else if (rate >= 50 * MHz)
249 src_clk = HCLK_BUS_ROOT_SEL_50M;
250 else
251 src_clk = HCLK_BUS_ROOT_SEL_OSC;
252 rk_clrsetreg(&cru->clksel_con[55],
253 HCLK_BUS_ROOT_SEL_MASK,
254 src_clk << HCLK_BUS_ROOT_SEL_SHIFT);
255 break;
256 case PCLK_BUS_ROOT:
257 if (rate >= 99 * MHz)
258 src_clk = PCLK_BUS_ROOT_SEL_100M;
259 else if (rate >= 50 * MHz)
260 src_clk = PCLK_BUS_ROOT_SEL_50M;
261 else
262 src_clk = PCLK_BUS_ROOT_SEL_OSC;
263 rk_clrsetreg(&cru->clksel_con[55],
264 PCLK_BUS_ROOT_SEL_MASK,
265 src_clk << PCLK_BUS_ROOT_SEL_SHIFT);
266 break;
267 default:
268 printf("do not support this center freq\n");
269 return -EINVAL;
270 }
271
272 return rk3576_bus_get_clk(priv, clk_id);
273 }
274
rk3576_top_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)275 static ulong rk3576_top_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
276 {
277 struct rk3576_cru *cru = priv->cru;
278 u32 con, sel, div, rate, prate;
279
280 switch (clk_id) {
281 case ACLK_TOP:
282 con = readl(&cru->clksel_con[9]);
283 div = (con & ACLK_TOP_DIV_MASK) >>
284 ACLK_TOP_DIV_SHIFT;
285 sel = (con & ACLK_TOP_SEL_MASK) >>
286 ACLK_TOP_SEL_SHIFT;
287 if (sel == ACLK_TOP_SEL_CPLL)
288 prate = priv->cpll_hz;
289 else if (sel == ACLK_TOP_SEL_AUPLL)
290 prate = priv->aupll_hz;
291 else
292 prate = priv->gpll_hz;
293 return DIV_TO_RATE(prate, div);
294 case ACLK_TOP_MID:
295 con = readl(&cru->clksel_con[10]);
296 div = (con & ACLK_TOP_MID_DIV_MASK) >>
297 ACLK_TOP_MID_DIV_SHIFT;
298 sel = (con & ACLK_TOP_MID_SEL_MASK) >>
299 ACLK_TOP_MID_SEL_SHIFT;
300 if (sel == ACLK_TOP_MID_SEL_CPLL)
301 prate = priv->cpll_hz;
302 else
303 prate = priv->gpll_hz;
304 return DIV_TO_RATE(prate, div);
305 case PCLK_TOP_ROOT:
306 con = readl(&cru->clksel_con[8]);
307 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
308 if (sel == PCLK_TOP_SEL_100M)
309 rate = 100 * MHz;
310 else if (sel == PCLK_TOP_SEL_50M)
311 rate = 50 * MHz;
312 else
313 rate = OSC_HZ;
314 break;
315 case HCLK_TOP:
316 con = readl(&cru->clksel_con[19]);
317 sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
318 if (sel == HCLK_TOP_SEL_200M)
319 rate = 200 * MHz;
320 else if (sel == HCLK_TOP_SEL_100M)
321 rate = 100 * MHz;
322 else if (sel == HCLK_TOP_SEL_50M)
323 rate = 50 * MHz;
324 else
325 rate = OSC_HZ;
326 break;
327 default:
328 return -ENOENT;
329 }
330
331 return rate;
332 }
333
rk3576_top_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)334 static ulong rk3576_top_set_clk(struct rk3576_clk_priv *priv,
335 ulong clk_id, ulong rate)
336 {
337 struct rk3576_cru *cru = priv->cru;
338 int src_clk, src_clk_div;
339
340 switch (clk_id) {
341 case ACLK_TOP:
342 if (!(priv->cpll_hz % rate)) {
343 src_clk = ACLK_TOP_SEL_CPLL;
344 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
345 } else {
346 src_clk = ACLK_TOP_SEL_GPLL;
347 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
348 }
349 assert(src_clk_div - 1 <= 31);
350 rk_clrsetreg(&cru->clksel_con[9],
351 ACLK_TOP_DIV_MASK |
352 ACLK_TOP_SEL_MASK,
353 (src_clk <<
354 ACLK_TOP_SEL_SHIFT) |
355 (src_clk_div - 1) << ACLK_TOP_SEL_SHIFT);
356 break;
357 case ACLK_TOP_MID:
358 if (!(priv->cpll_hz % rate)) {
359 src_clk = ACLK_TOP_MID_SEL_CPLL;
360 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
361 } else {
362 src_clk = ACLK_TOP_MID_SEL_GPLL;
363 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
364 }
365 rk_clrsetreg(&cru->clksel_con[10],
366 ACLK_TOP_MID_DIV_MASK |
367 ACLK_TOP_MID_SEL_MASK,
368 (ACLK_TOP_MID_SEL_GPLL <<
369 ACLK_TOP_MID_SEL_SHIFT) |
370 (src_clk_div - 1) << ACLK_TOP_MID_DIV_SHIFT);
371 break;
372 case PCLK_TOP_ROOT:
373 if (rate >= 99 * MHz)
374 src_clk = PCLK_TOP_SEL_100M;
375 else if (rate >= 50 * MHz)
376 src_clk = PCLK_TOP_SEL_50M;
377 else
378 src_clk = PCLK_TOP_SEL_OSC;
379 rk_clrsetreg(&cru->clksel_con[8],
380 PCLK_TOP_SEL_MASK,
381 src_clk << PCLK_TOP_SEL_SHIFT);
382 break;
383 case HCLK_TOP:
384 if (rate >= 198 * MHz)
385 src_clk = HCLK_TOP_SEL_200M;
386 else if (rate >= 99 * MHz)
387 src_clk = HCLK_TOP_SEL_100M;
388 else if (rate >= 50 * MHz)
389 src_clk = HCLK_TOP_SEL_50M;
390 else
391 src_clk = HCLK_TOP_SEL_OSC;
392 rk_clrsetreg(&cru->clksel_con[19],
393 HCLK_TOP_SEL_MASK,
394 src_clk << HCLK_TOP_SEL_SHIFT);
395 break;
396 default:
397 printf("do not support this top freq\n");
398 return -EINVAL;
399 }
400
401 return rk3576_top_get_clk(priv, clk_id);
402 }
403
rk3576_i2c_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)404 static ulong rk3576_i2c_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
405 {
406 struct rk3576_cru *cru = priv->cru;
407 u32 sel, con;
408 ulong rate;
409
410 switch (clk_id) {
411 case CLK_I2C0:
412 con = readl(&cru->pmuclksel_con[6]);
413 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
414 break;
415 case CLK_I2C1:
416 con = readl(&cru->clksel_con[57]);
417 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
418 break;
419 case CLK_I2C2:
420 con = readl(&cru->clksel_con[57]);
421 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
422 break;
423 case CLK_I2C3:
424 con = readl(&cru->clksel_con[57]);
425 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
426 break;
427 case CLK_I2C4:
428 con = readl(&cru->clksel_con[57]);
429 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
430 break;
431 case CLK_I2C5:
432 con = readl(&cru->clksel_con[57]);
433 sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
434 break;
435 case CLK_I2C6:
436 con = readl(&cru->clksel_con[57]);
437 sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
438 break;
439 case CLK_I2C7:
440 con = readl(&cru->clksel_con[57]);
441 sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
442 break;
443 case CLK_I2C8:
444 con = readl(&cru->clksel_con[57]);
445 sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
446 break;
447 case CLK_I2C9:
448 con = readl(&cru->clksel_con[58]);
449 sel = (con & CLK_I2C9_SEL_MASK) >> CLK_I2C9_SEL_SHIFT;
450 break;
451
452 default:
453 return -ENOENT;
454 }
455 if (sel == CLK_I2C_SEL_200M)
456 rate = 200 * MHz;
457 else if (sel == CLK_I2C_SEL_100M)
458 rate = 100 * MHz;
459 else if (sel == CLK_I2C_SEL_50M)
460 rate = 50 * MHz;
461 else
462 rate = OSC_HZ;
463
464 return rate;
465 }
466
rk3576_i2c_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)467 static ulong rk3576_i2c_set_clk(struct rk3576_clk_priv *priv, ulong clk_id,
468 ulong rate)
469 {
470 struct rk3576_cru *cru = priv->cru;
471 int src_clk;
472
473 if (rate >= 198 * MHz)
474 src_clk = CLK_I2C_SEL_200M;
475 else if (rate >= 99 * MHz)
476 src_clk = CLK_I2C_SEL_100M;
477 if (rate >= 50 * MHz)
478 src_clk = CLK_I2C_SEL_50M;
479 else
480 src_clk = CLK_I2C_SEL_OSC;
481
482 switch (clk_id) {
483 case CLK_I2C0:
484 rk_clrsetreg(&cru->pmuclksel_con[6], CLK_I2C0_SEL_MASK,
485 src_clk << CLK_I2C0_SEL_SHIFT);
486 break;
487 case CLK_I2C1:
488 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C1_SEL_MASK,
489 src_clk << CLK_I2C1_SEL_SHIFT);
490 break;
491 case CLK_I2C2:
492 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C2_SEL_MASK,
493 src_clk << CLK_I2C2_SEL_SHIFT);
494 break;
495 case CLK_I2C3:
496 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C3_SEL_MASK,
497 src_clk << CLK_I2C3_SEL_SHIFT);
498 break;
499 case CLK_I2C4:
500 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C4_SEL_MASK,
501 src_clk << CLK_I2C4_SEL_SHIFT);
502 break;
503 case CLK_I2C5:
504 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C5_SEL_MASK,
505 src_clk << CLK_I2C5_SEL_SHIFT);
506 break;
507 case CLK_I2C6:
508 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C6_SEL_MASK,
509 src_clk << CLK_I2C6_SEL_SHIFT);
510 break;
511 case CLK_I2C7:
512 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C7_SEL_MASK,
513 src_clk << CLK_I2C7_SEL_SHIFT);
514 break;
515 case CLK_I2C8:
516 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C8_SEL_MASK,
517 src_clk << CLK_I2C8_SEL_SHIFT);
518 case CLK_I2C9:
519 rk_clrsetreg(&cru->clksel_con[58], CLK_I2C9_SEL_MASK,
520 src_clk << CLK_I2C9_SEL_SHIFT);
521 break;
522 default:
523 return -ENOENT;
524 }
525
526 return rk3576_i2c_get_clk(priv, clk_id);
527 }
528
rk3576_spi_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)529 static ulong rk3576_spi_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
530 {
531 struct rk3576_cru *cru = priv->cru;
532 u32 sel, con;
533
534 switch (clk_id) {
535 case CLK_SPI0:
536 con = readl(&cru->clksel_con[70]);
537 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
538 break;
539 case CLK_SPI1:
540 con = readl(&cru->clksel_con[71]);
541 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
542 break;
543 case CLK_SPI2:
544 con = readl(&cru->clksel_con[71]);
545 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
546 break;
547 case CLK_SPI3:
548 con = readl(&cru->clksel_con[71]);
549 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
550 break;
551 case CLK_SPI4:
552 con = readl(&cru->clksel_con[71]);
553 sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
554 break;
555 default:
556 return -ENOENT;
557 }
558
559 switch (sel) {
560 case CLK_SPI_SEL_200M:
561 return 200 * MHz;
562 case CLK_SPI_SEL_100M:
563 return 100 * MHz;
564 case CLK_SPI_SEL_50M:
565 return 50 * MHz;
566 case CLK_SPI_SEL_OSC:
567 return OSC_HZ;
568 default:
569 return -ENOENT;
570 }
571 }
572
rk3576_spi_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)573 static ulong rk3576_spi_set_clk(struct rk3576_clk_priv *priv,
574 ulong clk_id, ulong rate)
575 {
576 struct rk3576_cru *cru = priv->cru;
577 int src_clk;
578
579 if (rate >= 198 * MHz)
580 src_clk = CLK_SPI_SEL_200M;
581 else if (rate >= 99 * MHz)
582 src_clk = CLK_SPI_SEL_100M;
583 else if (rate >= 50 * MHz)
584 src_clk = CLK_SPI_SEL_50M;
585 else
586 src_clk = CLK_SPI_SEL_OSC;
587
588 switch (clk_id) {
589 case CLK_SPI0:
590 rk_clrsetreg(&cru->clksel_con[70],
591 CLK_SPI0_SEL_MASK,
592 src_clk << CLK_SPI0_SEL_SHIFT);
593 break;
594 case CLK_SPI1:
595 rk_clrsetreg(&cru->clksel_con[71],
596 CLK_SPI1_SEL_MASK,
597 src_clk << CLK_SPI1_SEL_SHIFT);
598 break;
599 case CLK_SPI2:
600 rk_clrsetreg(&cru->clksel_con[71],
601 CLK_SPI2_SEL_MASK,
602 src_clk << CLK_SPI2_SEL_SHIFT);
603 break;
604 case CLK_SPI3:
605 rk_clrsetreg(&cru->clksel_con[71],
606 CLK_SPI3_SEL_MASK,
607 src_clk << CLK_SPI3_SEL_SHIFT);
608 break;
609 case CLK_SPI4:
610 rk_clrsetreg(&cru->clksel_con[71],
611 CLK_SPI4_SEL_MASK,
612 src_clk << CLK_SPI4_SEL_SHIFT);
613 break;
614 default:
615 return -ENOENT;
616 }
617
618 return rk3576_spi_get_clk(priv, clk_id);
619 }
620
rk3576_pwm_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)621 static ulong rk3576_pwm_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
622 {
623 struct rk3576_cru *cru = priv->cru;
624 u32 sel, con;
625
626 switch (clk_id) {
627 case CLK_PWM1:
628 con = readl(&cru->clksel_con[71]);
629 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
630 break;
631 case CLK_PWM2:
632 con = readl(&cru->clksel_con[74]);
633 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
634 break;
635 case CLK_PMU1PWM:
636 con = readl(&cru->pmuclksel_con[5]);
637 sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
638 break;
639 default:
640 return -ENOENT;
641 }
642
643 switch (sel) {
644 case CLK_PWM_SEL_100M:
645 return 100 * MHz;
646 case CLK_PWM_SEL_50M:
647 return 50 * MHz;
648 case CLK_PWM_SEL_OSC:
649 return OSC_HZ;
650 default:
651 return -ENOENT;
652 }
653 }
654
rk3576_pwm_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)655 static ulong rk3576_pwm_set_clk(struct rk3576_clk_priv *priv,
656 ulong clk_id, ulong rate)
657 {
658 struct rk3576_cru *cru = priv->cru;
659 int src_clk;
660
661 if (rate >= 99 * MHz)
662 src_clk = CLK_PWM_SEL_100M;
663 else if (rate >= 50 * MHz)
664 src_clk = CLK_PWM_SEL_50M;
665 else
666 src_clk = CLK_PWM_SEL_OSC;
667
668 switch (clk_id) {
669 case CLK_PWM1:
670 rk_clrsetreg(&cru->clksel_con[71],
671 CLK_PWM1_SEL_MASK,
672 src_clk << CLK_PWM1_SEL_SHIFT);
673 break;
674 case CLK_PWM2:
675 rk_clrsetreg(&cru->clksel_con[74],
676 CLK_PWM2_SEL_MASK,
677 src_clk << CLK_PWM2_SEL_SHIFT);
678 break;
679 case CLK_PMU1PWM:
680 rk_clrsetreg(&cru->pmuclksel_con[5],
681 CLK_PMU1PWM_SEL_MASK,
682 src_clk << CLK_PMU1PWM_SEL_SHIFT);
683 break;
684 default:
685 return -ENOENT;
686 }
687
688 return rk3576_pwm_get_clk(priv, clk_id);
689 }
690
rk3576_adc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)691 static ulong rk3576_adc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
692 {
693 struct rk3576_cru *cru = priv->cru;
694 u32 div, sel, con, prate;
695
696 switch (clk_id) {
697 case CLK_SARADC:
698 con = readl(&cru->clksel_con[58]);
699 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
700 sel = (con & CLK_SARADC_SEL_MASK) >>
701 CLK_SARADC_SEL_SHIFT;
702 if (sel == CLK_SARADC_SEL_OSC)
703 prate = OSC_HZ;
704 else
705 prate = priv->gpll_hz;
706 return DIV_TO_RATE(prate, div);
707 case CLK_TSADC:
708 con = readl(&cru->clksel_con[59]);
709 div = (con & CLK_TSADC_DIV_MASK) >>
710 CLK_TSADC_DIV_SHIFT;
711 prate = OSC_HZ;
712 return DIV_TO_RATE(prate, div);
713 default:
714 return -ENOENT;
715 }
716 }
717
rk3576_adc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)718 static ulong rk3576_adc_set_clk(struct rk3576_clk_priv *priv,
719 ulong clk_id, ulong rate)
720 {
721 struct rk3576_cru *cru = priv->cru;
722 int src_clk_div;
723
724 switch (clk_id) {
725 case CLK_SARADC:
726 if (!(OSC_HZ % rate)) {
727 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
728 assert(src_clk_div - 1 <= 255);
729 rk_clrsetreg(&cru->clksel_con[58],
730 CLK_SARADC_SEL_MASK |
731 CLK_SARADC_DIV_MASK,
732 (CLK_SARADC_SEL_OSC <<
733 CLK_SARADC_SEL_SHIFT) |
734 (src_clk_div - 1) <<
735 CLK_SARADC_DIV_SHIFT);
736 } else {
737 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
738 assert(src_clk_div - 1 <= 255);
739 rk_clrsetreg(&cru->clksel_con[59],
740 CLK_SARADC_SEL_MASK |
741 CLK_SARADC_DIV_MASK,
742 (CLK_SARADC_SEL_GPLL <<
743 CLK_SARADC_SEL_SHIFT) |
744 (src_clk_div - 1) <<
745 CLK_SARADC_DIV_SHIFT);
746 }
747 break;
748 case CLK_TSADC:
749 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
750 assert(src_clk_div - 1 <= 255);
751 rk_clrsetreg(&cru->clksel_con[58],
752 CLK_TSADC_DIV_MASK,
753 (src_clk_div - 1) <<
754 CLK_TSADC_DIV_SHIFT);
755 break;
756 default:
757 return -ENOENT;
758 }
759 return rk3576_adc_get_clk(priv, clk_id);
760 }
761
rk3576_mmc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)762 static ulong rk3576_mmc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
763 {
764 struct rk3576_cru *cru = priv->cru;
765 u32 sel, con, prate, div = 0;
766
767 switch (clk_id) {
768 case CCLK_SRC_SDIO:
769 case HCLK_SDIO:
770 con = readl(&cru->clksel_con[104]);
771 div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
772 sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
773 CCLK_SDIO_SRC_SEL_SHIFT;
774 if (sel == CCLK_SDIO_SRC_SEL_GPLL)
775 prate = priv->gpll_hz;
776 else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
777 prate = priv->cpll_hz;
778 else
779 prate = OSC_HZ;
780 return DIV_TO_RATE(prate, div);
781 case CCLK_SRC_SDMMC0:
782 case HCLK_SDMMC0:
783 con = readl(&cru->clksel_con[105]);
784 div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT;
785 sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >>
786 CCLK_SDMMC0_SRC_SEL_SHIFT;
787 if (sel == CCLK_SDMMC0_SRC_SEL_GPLL)
788 prate = priv->gpll_hz;
789 else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL)
790 prate = priv->cpll_hz;
791 else
792 prate = OSC_HZ;
793 return DIV_TO_RATE(prate, div);
794 case CCLK_SRC_EMMC:
795 case HCLK_EMMC:
796 con = readl(&cru->clksel_con[89]);
797 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
798 sel = (con & CCLK_EMMC_SEL_MASK) >>
799 CCLK_EMMC_SEL_SHIFT;
800 if (sel == CCLK_EMMC_SEL_GPLL)
801 prate = priv->gpll_hz;
802 else if (sel == CCLK_EMMC_SEL_CPLL)
803 prate = priv->cpll_hz;
804 else
805 prate = OSC_HZ;
806 return DIV_TO_RATE(prate, div);
807 case BCLK_EMMC:
808 con = readl(&cru->clksel_con[90]);
809 sel = (con & BCLK_EMMC_SEL_MASK) >>
810 BCLK_EMMC_SEL_SHIFT;
811 if (sel == BCLK_EMMC_SEL_200M)
812 prate = 200 * MHz;
813 else if (sel == BCLK_EMMC_SEL_100M)
814 prate = 100 * MHz;
815 else if (sel == BCLK_EMMC_SEL_50M)
816 prate = 50 * MHz;
817 else
818 prate = OSC_HZ;
819 return DIV_TO_RATE(prate, div);
820 case SCLK_FSPI_X2:
821 con = readl(&cru->clksel_con[89]);
822 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
823 sel = (con & SCLK_FSPI_SEL_MASK) >>
824 SCLK_FSPI_SEL_SHIFT;
825 if (sel == SCLK_FSPI_SEL_GPLL)
826 prate = priv->gpll_hz;
827 else if (sel == SCLK_FSPI_SEL_CPLL)
828 prate = priv->cpll_hz;
829 else
830 prate = OSC_HZ;
831 return DIV_TO_RATE(prate, div);
832 case SCLK_FSPI1_X2:
833 con = readl(&cru->clksel_con[106]);
834 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
835 sel = (con & SCLK_FSPI_SEL_MASK) >>
836 SCLK_FSPI_SEL_SHIFT;
837 if (sel == SCLK_FSPI_SEL_GPLL)
838 prate = priv->gpll_hz;
839 else if (sel == SCLK_FSPI_SEL_CPLL)
840 prate = priv->cpll_hz;
841 else
842 prate = OSC_HZ;
843 return DIV_TO_RATE(prate, div);
844 case DCLK_DECOM:
845 con = readl(&cru->clksel_con[72]);
846 div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
847 sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
848 if (sel == DCLK_DECOM_SEL_SPLL)
849 prate = priv->spll_hz;
850 else
851 prate = priv->gpll_hz;
852 return DIV_TO_RATE(prate, div);
853
854 default:
855 return -ENOENT;
856 }
857 }
858
rk3576_mmc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)859 static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv,
860 ulong clk_id, ulong rate)
861 {
862 struct rk3576_cru *cru = priv->cru;
863 int src_clk, div = 0;
864
865 switch (clk_id) {
866 case CCLK_SRC_SDIO:
867 case CCLK_SRC_SDMMC0:
868 case CCLK_SRC_EMMC:
869 case SCLK_FSPI_X2:
870 case SCLK_FSPI1_X2:
871 case HCLK_SDMMC0:
872 case HCLK_EMMC:
873 case HCLK_SDIO:
874 if (!(OSC_HZ % rate)) {
875 src_clk = SCLK_FSPI_SEL_OSC;
876 div = DIV_ROUND_UP(OSC_HZ, rate);
877 } else if (!(priv->cpll_hz % rate)) {
878 src_clk = SCLK_FSPI_SEL_CPLL;
879 div = DIV_ROUND_UP(priv->cpll_hz, rate);
880 } else {
881 src_clk = SCLK_FSPI_SEL_GPLL;
882 div = DIV_ROUND_UP(priv->gpll_hz, rate);
883 }
884 break;
885 case BCLK_EMMC:
886 if (rate >= 198 * MHz)
887 src_clk = BCLK_EMMC_SEL_200M;
888 else if (rate >= 99 * MHz)
889 src_clk = BCLK_EMMC_SEL_100M;
890 else if (rate >= 50 * MHz)
891 src_clk = BCLK_EMMC_SEL_50M;
892 else
893 src_clk = BCLK_EMMC_SEL_OSC;
894 break;
895 case DCLK_DECOM:
896 if (!(priv->spll_hz % rate)) {
897 src_clk = DCLK_DECOM_SEL_SPLL;
898 div = DIV_ROUND_UP(priv->spll_hz, rate);
899 } else {
900 src_clk = DCLK_DECOM_SEL_GPLL;
901 div = DIV_ROUND_UP(priv->gpll_hz, rate);
902 }
903 break;
904 default:
905 return -ENOENT;
906 }
907
908 switch (clk_id) {
909 case CCLK_SRC_SDIO:
910 case HCLK_SDIO:
911 rk_clrsetreg(&cru->clksel_con[104],
912 CCLK_SDIO_SRC_SEL_MASK |
913 CCLK_SDIO_SRC_DIV_MASK,
914 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
915 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
916 break;
917 case CCLK_SRC_SDMMC0:
918 case HCLK_SDMMC0:
919 rk_clrsetreg(&cru->clksel_con[105],
920 CCLK_SDMMC0_SRC_SEL_MASK |
921 CCLK_SDMMC0_SRC_DIV_MASK,
922 (src_clk << CCLK_SDMMC0_SRC_SEL_SHIFT) |
923 (div - 1) << CCLK_SDMMC0_SRC_DIV_SHIFT);
924 break;
925 case CCLK_SRC_EMMC:
926 case HCLK_EMMC:
927 rk_clrsetreg(&cru->clksel_con[89],
928 CCLK_EMMC_DIV_MASK |
929 CCLK_EMMC_SEL_MASK,
930 (src_clk << CCLK_EMMC_SEL_SHIFT) |
931 (div - 1) << CCLK_EMMC_DIV_SHIFT);
932 break;
933 case SCLK_FSPI_X2:
934 rk_clrsetreg(&cru->clksel_con[89],
935 SCLK_FSPI_DIV_MASK |
936 SCLK_FSPI_SEL_MASK,
937 (src_clk << SCLK_FSPI_SEL_SHIFT) |
938 (div - 1) << SCLK_FSPI_DIV_SHIFT);
939 break;
940 case SCLK_FSPI1_X2:
941 rk_clrsetreg(&cru->clksel_con[106],
942 SCLK_FSPI_DIV_MASK |
943 SCLK_FSPI_SEL_MASK,
944 (src_clk << SCLK_FSPI_SEL_SHIFT) |
945 (div - 1) << SCLK_FSPI_DIV_SHIFT);
946 break;
947 case BCLK_EMMC:
948 rk_clrsetreg(&cru->clksel_con[90],
949 BCLK_EMMC_SEL_MASK,
950 src_clk << BCLK_EMMC_SEL_SHIFT);
951 break;
952 case DCLK_DECOM:
953 rk_clrsetreg(&cru->clksel_con[72],
954 DCLK_DECOM_DIV_MASK |
955 DCLK_DECOM_SEL_MASK,
956 (src_clk << DCLK_DECOM_SEL_SHIFT) |
957 (div - 1) << DCLK_DECOM_DIV_SHIFT);
958 break;
959
960 default:
961 return -ENOENT;
962 }
963
964 return rk3576_mmc_get_clk(priv, clk_id);
965 }
966
967 #ifndef CONFIG_SPL_BUILD
968
rk3576_aclk_vop_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)969 static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
970 {
971 struct rk3576_cru *cru = priv->cru;
972 u32 div, sel, con, parent = 0;
973
974 switch (clk_id) {
975 case ACLK_VOP_ROOT:
976 case ACLK_VOP:
977 con = readl(&cru->clksel_con[144]);
978 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
979 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
980 if (sel == ACLK_VOP_ROOT_SEL_GPLL)
981 parent = priv->gpll_hz;
982 else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
983 parent = priv->cpll_hz;
984 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
985 parent = priv->aupll_hz;
986 else if (sel == ACLK_VOP_ROOT_SEL_SPLL)
987 parent = priv->spll_hz;
988 else if (sel == ACLK_VOP_ROOT_SEL_LPLL)
989 parent = priv->lpll_hz / 2;
990 return DIV_TO_RATE(parent, div);
991 case ACLK_VO0_ROOT:
992 con = readl(&cru->clksel_con[149]);
993 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
994 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
995 if (sel == ACLK_VO0_ROOT_SEL_GPLL)
996 parent = priv->gpll_hz;
997 else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
998 parent = priv->cpll_hz;
999 else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
1000 parent = priv->lpll_hz / 2;
1001 else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
1002 parent = priv->bpll_hz / 4;
1003 return DIV_TO_RATE(parent, div);
1004 case ACLK_VO1_ROOT:
1005 con = readl(&cru->clksel_con[158]);
1006 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
1007 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
1008 if (sel == ACLK_VO0_ROOT_SEL_GPLL)
1009 parent = priv->gpll_hz;
1010 else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
1011 parent = priv->cpll_hz;
1012 else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
1013 parent = priv->lpll_hz / 2;
1014 else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
1015 parent = priv->bpll_hz / 4;
1016 return DIV_TO_RATE(parent, div);
1017 case HCLK_VOP_ROOT:
1018 con = readl(&cru->clksel_con[144]);
1019 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
1020 if (sel == HCLK_VOP_ROOT_SEL_200M)
1021 return 200 * MHz;
1022 else if (sel == HCLK_VOP_ROOT_SEL_100M)
1023 return 100 * MHz;
1024 else if (sel == HCLK_VOP_ROOT_SEL_50M)
1025 return 50 * MHz;
1026 else
1027 return OSC_HZ;
1028 case PCLK_VOP_ROOT:
1029 con = readl(&cru->clksel_con[144]);
1030 sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT;
1031 if (sel == PCLK_VOP_ROOT_SEL_100M)
1032 return 100 * MHz;
1033 else if (sel == PCLK_VOP_ROOT_SEL_50M)
1034 return 50 * MHz;
1035 else
1036 return OSC_HZ;
1037
1038 default:
1039 return -ENOENT;
1040 }
1041 }
1042
rk3576_aclk_vop_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1043 static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv,
1044 ulong clk_id, ulong rate)
1045 {
1046 struct rk3576_cru *cru = priv->cru;
1047 int src_clk, div;
1048
1049 switch (clk_id) {
1050 case ACLK_VOP_ROOT:
1051 case ACLK_VOP:
1052 if (rate == 700 * MHz) {
1053 src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1054 div = 1;
1055 } else if (!(priv->cpll_hz % rate)) {
1056 src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1057 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1058 } else {
1059 src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1060 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1061 }
1062 rk_clrsetreg(&cru->clksel_con[144],
1063 ACLK_VOP_ROOT_DIV_MASK |
1064 ACLK_VOP_ROOT_SEL_MASK,
1065 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1066 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1067 break;
1068 case ACLK_VO0_ROOT:
1069 if (!(priv->cpll_hz % rate)) {
1070 src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1071 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1072 } else {
1073 src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1074 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1075 }
1076 rk_clrsetreg(&cru->clksel_con[149],
1077 ACLK_VO0_ROOT_DIV_MASK |
1078 ACLK_VO0_ROOT_SEL_MASK,
1079 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1080 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1081 break;
1082 case ACLK_VO1_ROOT:
1083 if (!(priv->cpll_hz % rate)) {
1084 src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1085 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1086 } else {
1087 src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1088 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1089 }
1090 rk_clrsetreg(&cru->clksel_con[158],
1091 ACLK_VO0_ROOT_DIV_MASK |
1092 ACLK_VO0_ROOT_SEL_MASK,
1093 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1094 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1095 break;
1096 case HCLK_VOP_ROOT:
1097 if (rate == 200 * MHz)
1098 src_clk = HCLK_VOP_ROOT_SEL_200M;
1099 else if (rate == 100 * MHz)
1100 src_clk = HCLK_VOP_ROOT_SEL_100M;
1101 else if (rate == 50 * MHz)
1102 src_clk = HCLK_VOP_ROOT_SEL_50M;
1103 else
1104 src_clk = HCLK_VOP_ROOT_SEL_OSC;
1105 rk_clrsetreg(&cru->clksel_con[144],
1106 HCLK_VOP_ROOT_SEL_MASK,
1107 src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1108 break;
1109 case PCLK_VOP_ROOT:
1110 if (rate == 100 * MHz)
1111 src_clk = PCLK_VOP_ROOT_SEL_100M;
1112 else if (rate == 50 * MHz)
1113 src_clk = PCLK_VOP_ROOT_SEL_50M;
1114 else
1115 src_clk = PCLK_VOP_ROOT_SEL_OSC;
1116 rk_clrsetreg(&cru->clksel_con[144],
1117 PCLK_VOP_ROOT_SEL_MASK,
1118 src_clk << PCLK_VOP_ROOT_SEL_SHIFT);
1119 break;
1120
1121 default:
1122 return -ENOENT;
1123 }
1124
1125 return rk3576_aclk_vop_get_clk(priv, clk_id);
1126 }
1127
rk3576_dclk_vop_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1128 static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1129 {
1130 struct rk3576_cru *cru = priv->cru;
1131 u32 div, sel, con, parent;
1132
1133 switch (clk_id) {
1134 case DCLK_VP0:
1135 case DCLK_VP0_SRC:
1136 con = readl(&cru->clksel_con[145]);
1137 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1138 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1139 break;
1140 case DCLK_VP1:
1141 case DCLK_VP1_SRC:
1142 con = readl(&cru->clksel_con[146]);
1143 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1144 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1145 break;
1146 case DCLK_VP2:
1147 case DCLK_VP2_SRC:
1148 con = readl(&cru->clksel_con[147]);
1149 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1150 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1151 break;
1152 default:
1153 return -ENOENT;
1154 }
1155
1156 if (sel == DCLK_VOP_SRC_SEL_VPLL)
1157 parent = priv->vpll_hz;
1158 else if (sel == DCLK_VOP_SRC_SEL_BPLL)
1159 parent = priv->bpll_hz / 4;
1160 else if (sel == DCLK_VOP_SRC_SEL_LPLL)
1161 parent = priv->lpll_hz / 2;
1162 else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1163 parent = priv->gpll_hz;
1164 else
1165 parent = priv->cpll_hz;
1166
1167 return DIV_TO_RATE(parent, div);
1168 }
1169
1170 #define RK3576_VOP_PLL_LIMIT_FREQ 594000000
1171
rk3576_dclk_vop_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1172 static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv,
1173 ulong clk_id, ulong rate)
1174 {
1175 struct rk3576_cru *cru = priv->cru;
1176 ulong pll_rate, now, best_rate = 0;
1177 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1178 u32 mask, div_shift, sel_shift;
1179
1180 switch (clk_id) {
1181 case DCLK_VP0:
1182 case DCLK_VP0_SRC:
1183 conid = 145;
1184 con = readl(&cru->clksel_con[conid]);
1185 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1186 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1187 div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1188 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1189 break;
1190 case DCLK_VP1:
1191 case DCLK_VP1_SRC:
1192 conid = 146;
1193 con = readl(&cru->clksel_con[conid]);
1194 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1195 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1196 div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1197 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1198 break;
1199 case DCLK_VP2:
1200 case DCLK_VP2_SRC:
1201 conid = 147;
1202 con = readl(&cru->clksel_con[conid]);
1203 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1204 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1205 div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1206 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1207 break;
1208 default:
1209 return -ENOENT;
1210 }
1211
1212 if (sel == DCLK_VOP_SRC_SEL_VPLL) {
1213 pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1214 priv->cru, VPLL);
1215 if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
1216 div = DIV_ROUND_UP(pll_rate, rate);
1217 rk_clrsetreg(&cru->clksel_con[conid],
1218 mask,
1219 DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1220 ((div - 1) << div_shift));
1221 } else {
1222 div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate);
1223 if (div % 2)
1224 div = div + 1;
1225 rk_clrsetreg(&cru->clksel_con[conid],
1226 mask,
1227 DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1228 ((div - 1) << div_shift));
1229 rockchip_pll_set_rate(&rk3576_pll_clks[VPLL],
1230 priv->cru, VPLL, div * rate);
1231 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1232 priv->cru, VPLL);
1233 }
1234 } else {
1235 for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) {
1236 switch (i) {
1237 case DCLK_VOP_SRC_SEL_GPLL:
1238 pll_rate = priv->gpll_hz;
1239 break;
1240 case DCLK_VOP_SRC_SEL_CPLL:
1241 pll_rate = priv->cpll_hz;
1242 break;
1243 case DCLK_VOP_SRC_SEL_BPLL:
1244 pll_rate = 0;
1245 break;
1246 case DCLK_VOP_SRC_SEL_LPLL:
1247 pll_rate = 0;
1248 break;
1249 case DCLK_VOP_SRC_SEL_VPLL:
1250 pll_rate = 0;
1251 break;
1252 default:
1253 printf("do not support this vop pll sel\n");
1254 return -EINVAL;
1255 }
1256
1257 div = DIV_ROUND_UP(pll_rate, rate);
1258 if (div > 255)
1259 continue;
1260 now = pll_rate / div;
1261 if (abs(rate - now) < abs(rate - best_rate)) {
1262 best_rate = now;
1263 best_div = div;
1264 best_sel = i;
1265 }
1266 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1267 pll_rate, best_rate, best_div, best_sel);
1268 }
1269
1270 if (best_rate) {
1271 rk_clrsetreg(&cru->clksel_con[conid],
1272 mask,
1273 best_sel << sel_shift |
1274 (best_div - 1) << div_shift);
1275 } else {
1276 printf("do not support this vop freq %lu\n", rate);
1277 return -EINVAL;
1278 }
1279 }
1280 return rk3576_dclk_vop_get_clk(priv, clk_id);
1281 }
1282
rk3576_clk_csihost_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1283 static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1284 {
1285 struct rk3576_cru *cru = priv->cru;
1286 u32 div, sel, con, parent;
1287
1288 switch (clk_id) {
1289 case CLK_DSIHOST0:
1290 con = readl(&cru->clksel_con[151]);
1291 div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT;
1292 sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT;
1293 break;
1294 default:
1295 return -ENOENT;
1296 }
1297
1298 if (sel == CLK_DSIHOST0_SEL_VPLL)
1299 parent = priv->vpll_hz;
1300 else if (sel == CLK_DSIHOST0_SEL_BPLL)
1301 parent = priv->bpll_hz / 4;
1302 else if (sel == CLK_DSIHOST0_SEL_LPLL)
1303 parent = priv->lpll_hz / 2;
1304 else if (sel == CLK_DSIHOST0_SEL_GPLL)
1305 parent = priv->gpll_hz;
1306 else if (sel == CLK_DSIHOST0_SEL_SPLL)
1307 parent = priv->spll_hz;
1308 else
1309 parent = priv->cpll_hz;
1310
1311 return DIV_TO_RATE(parent, div);
1312 }
1313
rk3576_clk_csihost_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1314 static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv,
1315 ulong clk_id, ulong rate)
1316 {
1317 struct rk3576_cru *cru = priv->cru;
1318 ulong pll_rate, now, best_rate = 0;
1319 u32 i, con, div, best_div = 0, best_sel = 0;
1320 u32 mask, div_shift, sel_shift;
1321
1322 switch (clk_id) {
1323 case CLK_DSIHOST0:
1324 con = 151;
1325 mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK;
1326 div_shift = CLK_DSIHOST0_DIV_SHIFT;
1327 sel_shift = CLK_DSIHOST0_SEL_SHIFT;
1328 break;
1329 default:
1330 return -ENOENT;
1331 }
1332 for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) {
1333 switch (i) {
1334 case CLK_DSIHOST0_SEL_GPLL:
1335 pll_rate = priv->gpll_hz;
1336 break;
1337 case CLK_DSIHOST0_SEL_CPLL:
1338 pll_rate = priv->cpll_hz;
1339 break;
1340 case CLK_DSIHOST0_SEL_BPLL:
1341 pll_rate = 0;
1342 break;
1343 case CLK_DSIHOST0_SEL_LPLL:
1344 pll_rate = 0;
1345 break;
1346 case CLK_DSIHOST0_SEL_VPLL:
1347 pll_rate = 0;
1348 break;
1349 case CLK_DSIHOST0_SEL_SPLL:
1350 pll_rate = priv->spll_hz;
1351 break;
1352 default:
1353 printf("do not support this vop pll sel\n");
1354 return -EINVAL;
1355 }
1356
1357 div = DIV_ROUND_UP(pll_rate, rate);
1358 if (div > 255)
1359 continue;
1360 now = pll_rate / div;
1361 if (abs(rate - now) < abs(rate - best_rate)) {
1362 best_rate = now;
1363 best_div = div;
1364 best_sel = i;
1365 }
1366 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1367 pll_rate, best_rate, best_div, best_sel);
1368 }
1369 if (best_rate) {
1370 rk_clrsetreg(&cru->clksel_con[con],
1371 mask,
1372 best_sel << sel_shift |
1373 (best_div - 1) << div_shift);
1374 } else {
1375 printf("do not support this vop freq %lu\n", rate);
1376 return -EINVAL;
1377 }
1378 return rk3576_clk_csihost_get_clk(priv, clk_id);
1379 }
1380
rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1381 static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1382 {
1383 struct rk3576_cru *cru = priv->cru;
1384 u32 div, sel, con, parent;
1385 unsigned long m = 0, n = 0;
1386
1387 switch (clk_id) {
1388 case DCLK_EBC:
1389 con = readl(&cru->clksel_con[123]);
1390 div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT;
1391 sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
1392 if (sel == DCLK_EBC_SEL_CPLL)
1393 parent = priv->cpll_hz;
1394 else if (sel == DCLK_EBC_SEL_VPLL)
1395 parent = priv->vpll_hz;
1396 else if (sel == DCLK_EBC_SEL_AUPLL)
1397 parent = priv->aupll_hz;
1398 else if (sel == DCLK_EBC_SEL_LPLL)
1399 parent = priv->lpll_hz / 2;
1400 else if (sel == DCLK_EBC_SEL_GPLL)
1401 parent = priv->gpll_hz;
1402 else if (sel == DCLK_EBC_SEL_FRAC_SRC)
1403 parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC);
1404 else
1405 parent = OSC_HZ;
1406 return DIV_TO_RATE(parent, div);
1407 case DCLK_EBC_FRAC_SRC:
1408 con = readl(&cru->clksel_con[123]);
1409 div = readl(&cru->clksel_con[122]);
1410 sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT;
1411 if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL)
1412 parent = priv->gpll_hz;
1413 else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL)
1414 parent = priv->cpll_hz;
1415 else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL)
1416 parent = priv->vpll_hz;
1417 else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL)
1418 parent = priv->aupll_hz;
1419 else
1420 parent = OSC_HZ;
1421
1422 n = div & CLK_UART_FRAC_NUMERATOR_MASK;
1423 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1424 m = div & CLK_UART_FRAC_DENOMINATOR_MASK;
1425 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1426 return parent * n / m;
1427 default:
1428 return -ENOENT;
1429 }
1430 }
1431
rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1432 static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv,
1433 ulong clk_id, ulong rate)
1434 {
1435 struct rk3576_cru *cru = priv->cru;
1436 ulong pll_rate, now, best_rate = 0;
1437 u32 i, con, sel, div, best_div = 0, best_sel = 0;
1438 unsigned long m = 0, n = 0, val;
1439
1440 switch (clk_id) {
1441 case DCLK_EBC:
1442 con = readl(&cru->clksel_con[123]);
1443 sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
1444 if (sel == DCLK_EBC_SEL_VPLL) {
1445 pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1446 priv->cru, VPLL);
1447 if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ &&
1448 pll_rate % rate == 0) {
1449 div = DIV_ROUND_UP(pll_rate, rate);
1450 rk_clrsetreg(&cru->clksel_con[123],
1451 DCLK_EBC_DIV_MASK,
1452 (div - 1) << DCLK_EBC_DIV_SHIFT);
1453 } else {
1454 div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ,
1455 rate);
1456 if (div % 2)
1457 div = div + 1;
1458 rk_clrsetreg(&cru->clksel_con[123],
1459 DCLK_EBC_DIV_MASK,
1460 (div - 1) << DCLK_EBC_DIV_SHIFT);
1461 rockchip_pll_set_rate(&rk3576_pll_clks[VPLL],
1462 priv->cru,
1463 VPLL, div * rate);
1464 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1465 priv->cru,
1466 VPLL);
1467 }
1468 } else if (sel == DCLK_EBC_SEL_FRAC_SRC) {
1469 rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate);
1470 div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate;
1471 rk_clrsetreg(&cru->clksel_con[123],
1472 DCLK_EBC_DIV_MASK,
1473 (div - 1) << DCLK_EBC_DIV_SHIFT);
1474 } else {
1475 for (i = 0; i <= DCLK_EBC_SEL_LPLL; i++) {
1476 switch (i) {
1477 case DCLK_EBC_SEL_GPLL:
1478 pll_rate = priv->gpll_hz;
1479 break;
1480 case DCLK_EBC_SEL_CPLL:
1481 pll_rate = priv->cpll_hz;
1482 break;
1483 case DCLK_EBC_SEL_VPLL:
1484 pll_rate = 0;
1485 break;
1486 case DCLK_EBC_SEL_AUPLL:
1487 pll_rate = priv->aupll_hz;
1488 break;
1489 case DCLK_EBC_SEL_LPLL:
1490 pll_rate = 0;
1491 break;
1492 default:
1493 printf("not support ebc pll sel\n");
1494 return -EINVAL;
1495 }
1496
1497 div = DIV_ROUND_UP(pll_rate, rate);
1498 if (div > 255)
1499 continue;
1500 now = pll_rate / div;
1501 if (abs(rate - now) < abs(rate - best_rate)) {
1502 best_rate = now;
1503 best_div = div;
1504 best_sel = i;
1505 }
1506 }
1507
1508 if (best_rate) {
1509 rk_clrsetreg(&cru->clksel_con[123],
1510 DCLK_EBC_DIV_MASK |
1511 DCLK_EBC_SEL_MASK,
1512 best_sel <<
1513 DCLK_EBC_SEL_SHIFT |
1514 (best_div - 1) <<
1515 DCLK_EBC_DIV_SHIFT);
1516 } else {
1517 printf("do not support this vop freq %lu\n",
1518 rate);
1519 return -EINVAL;
1520 }
1521 }
1522 break;
1523 case DCLK_EBC_FRAC_SRC:
1524 sel = DCLK_EBC_FRAC_SRC_SEL_GPLL;
1525 div = 1;
1526 rational_best_approximation(rate, priv->gpll_hz,
1527 GENMASK(16 - 1, 0),
1528 GENMASK(16 - 1, 0),
1529 &m, &n);
1530
1531 if (m < 4 && m != 0) {
1532 if (n % 2 == 0)
1533 val = 1;
1534 else
1535 val = DIV_ROUND_UP(4, m);
1536
1537 n *= val;
1538 m *= val;
1539 if (n > 0xffff) {
1540 n = 0xffff;
1541 }
1542 }
1543
1544 rk_clrsetreg(&cru->clksel_con[123],
1545 DCLK_EBC_FRAC_SRC_SEL_MASK,
1546 (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT));
1547 if (m && n) {
1548 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1549 writel(val, &cru->clksel_con[122]);
1550 }
1551 break;
1552 default:
1553 return -ENOENT;
1554 }
1555 return rk3576_dclk_ebc_get_clk(priv, clk_id);
1556 }
1557
rk3576_gmac_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1558 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1559 {
1560 struct rk3576_cru *cru = priv->cru;
1561 u32 con, div, src, p_rate;
1562
1563 switch (clk_id) {
1564 case CLK_GMAC0_PTP_REF_SRC:
1565 case CLK_GMAC0_PTP_REF:
1566 con = readl(&cru->clksel_con[105]);
1567 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1568 src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT;
1569 if (src == CLK_GMAC0_PTP_SEL_GPLL)
1570 p_rate = priv->gpll_hz;
1571 else if (src == CLK_GMAC0_PTP_SEL_CPLL)
1572 p_rate = priv->cpll_hz;
1573 else
1574 p_rate = GMAC0_PTP_REFCLK_IN;
1575 return DIV_TO_RATE(p_rate, div);
1576 case CLK_GMAC1_PTP_REF_SRC:
1577 case CLK_GMAC1_PTP_REF:
1578 con = readl(&cru->clksel_con[104]);
1579 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1580 src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT;
1581 if (src == CLK_GMAC1_PTP_SEL_GPLL)
1582 p_rate = priv->gpll_hz;
1583 else if (src == CLK_GMAC1_PTP_SEL_CPLL)
1584 p_rate = priv->cpll_hz;
1585 else
1586 p_rate = GMAC1_PTP_REFCLK_IN;
1587 return DIV_TO_RATE(p_rate, div);
1588 case CLK_GMAC0_125M_SRC:
1589 con = readl(&cru->clksel_con[30]);
1590 div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT;
1591 return DIV_TO_RATE(priv->cpll_hz, div);
1592 case CLK_GMAC1_125M_SRC:
1593 con = readl(&cru->clksel_con[31]);
1594 div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT;
1595 return DIV_TO_RATE(priv->cpll_hz, div);
1596 default:
1597 return -ENOENT;
1598 }
1599 }
1600
rk3576_gmac_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1601 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv,
1602 ulong clk_id, ulong rate)
1603 {
1604 struct rk3576_cru *cru = priv->cru;
1605 int div, src;
1606
1607 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1608
1609 switch (clk_id) {
1610 case CLK_GMAC0_PTP_REF_SRC:
1611 case CLK_GMAC0_PTP_REF:
1612 if (rate == GMAC0_PTP_REFCLK_IN) {
1613 src = CLK_GMAC0_PTP_SEL_REFIN;
1614 div = 1;
1615 } else if (!(priv->gpll_hz % rate)) {
1616 src = CLK_GMAC0_PTP_SEL_GPLL;
1617 div = priv->gpll_hz / rate;
1618 } else {
1619 src = CLK_GMAC0_PTP_SEL_CPLL;
1620 div = priv->cpll_hz / rate;
1621 }
1622 rk_clrsetreg(&cru->clksel_con[105],
1623 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1624 src << CLK_GMAC0_PTP_SEL_SHIFT |
1625 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1626 break;
1627 case CLK_GMAC1_PTP_REF_SRC:
1628 case CLK_GMAC1_PTP_REF:
1629 if (rate == GMAC1_PTP_REFCLK_IN) {
1630 src = CLK_GMAC1_PTP_SEL_REFIN;
1631 div = 1;
1632 } else if (!(priv->gpll_hz % rate)) {
1633 src = CLK_GMAC1_PTP_SEL_GPLL;
1634 div = priv->gpll_hz / rate;
1635 } else {
1636 src = CLK_GMAC1_PTP_SEL_CPLL;
1637 div = priv->cpll_hz / rate;
1638 }
1639 rk_clrsetreg(&cru->clksel_con[104],
1640 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1641 src << CLK_GMAC1_PTP_SEL_SHIFT |
1642 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1643 break;
1644
1645 case CLK_GMAC0_125M_SRC:
1646 rk_clrsetreg(&cru->clksel_con[30],
1647 CLK_GMAC0_125M_DIV_MASK,
1648 (div - 1) << CLK_GMAC0_125M_DIV_SHIFT);
1649 break;
1650 case CLK_GMAC1_125M_SRC:
1651 rk_clrsetreg(&cru->clksel_con[31],
1652 CLK_GMAC1_125M_DIV_MASK,
1653 (div - 1) << CLK_GMAC1_125M_DIV_SHIFT);
1654 break;
1655 default:
1656 return -ENOENT;
1657 }
1658
1659 return rk3576_gmac_get_clk(priv, clk_id);
1660 }
1661
rk3576_uart_frac_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)1662 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1663 {
1664 struct rk3576_cru *cru = priv->cru;
1665 u32 reg, con, fracdiv, p_src, p_rate;
1666 unsigned long m, n;
1667
1668 switch (clk_id) {
1669 case CLK_UART_FRAC_0:
1670 reg = 21;
1671 break;
1672 case CLK_UART_FRAC_1:
1673 reg = 23;
1674 break;
1675 case CLK_UART_FRAC_2:
1676 reg = 25;
1677 break;
1678 default:
1679 return -ENOENT;
1680 }
1681 con = readl(&cru->clksel_con[reg + 1]);
1682 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1683 if (p_src == CLK_UART_SRC_SEL_GPLL)
1684 p_rate = priv->gpll_hz;
1685 else if (p_src == CLK_UART_SRC_SEL_CPLL)
1686 p_rate = priv->cpll_hz;
1687 else if (p_src == CLK_UART_SRC_SEL_AUPLL)
1688 p_rate = priv->aupll_hz;
1689 else
1690 p_rate = OSC_HZ;
1691
1692 fracdiv = readl(&cru->clksel_con[reg]);
1693 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1694 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1695 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1696 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1697 return p_rate * n / m;
1698 }
1699
rk3576_uart_frac_set_rate(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1700 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv,
1701 ulong clk_id, ulong rate)
1702 {
1703 struct rk3576_cru *cru = priv->cru;
1704 u32 reg, clk_src, p_rate;
1705 unsigned long m = 0, n = 0, val;
1706
1707 if (priv->cpll_hz % rate == 0) {
1708 clk_src = CLK_UART_SRC_SEL_CPLL;
1709 p_rate = priv->cpll_hz;
1710 } else if (rate == OSC_HZ) {
1711 clk_src = CLK_UART_SRC_SEL_OSC;
1712 p_rate = OSC_HZ;
1713 } else {
1714 clk_src = CLK_UART_SRC_SEL_GPLL;
1715 p_rate = priv->cpll_hz;
1716 }
1717 rational_best_approximation(rate, p_rate,
1718 GENMASK(16 - 1, 0),
1719 GENMASK(16 - 1, 0),
1720 &m, &n);
1721
1722 if (m < 4 && m != 0) {
1723 if (n % 2 == 0)
1724 val = 1;
1725 else
1726 val = DIV_ROUND_UP(4, m);
1727
1728 n *= val;
1729 m *= val;
1730 if (n > 0xffff) {
1731 n = 0xffff;
1732 }
1733 }
1734
1735
1736 switch (clk_id) {
1737 case CLK_UART_FRAC_0:
1738 reg = 21;
1739 break;
1740 case CLK_UART_FRAC_1:
1741 reg = 23;
1742 break;
1743 case CLK_UART_FRAC_2:
1744 reg = 25;
1745 break;
1746 default:
1747 return -ENOENT;
1748 }
1749 rk_clrsetreg(&cru->clksel_con[reg +1],
1750 CLK_UART_SRC_SEL_MASK,
1751 (clk_src << CLK_UART_SRC_SEL_SHIFT));
1752 if (m && n) {
1753 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1754 writel(val, &cru->clksel_con[reg]);
1755 }
1756
1757 return rk3576_uart_frac_get_rate(priv, clk_id);
1758 }
1759
1760
rk3576_uart_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)1761 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1762 {
1763 struct rk3576_cru *cru = priv->cru;
1764 u32 con, div, src, p_rate;
1765
1766 switch (clk_id) {
1767 case SCLK_UART0:
1768 con = readl(&cru->clksel_con[60]);
1769 break;
1770 case SCLK_UART1:
1771 con = readl(&cru->pmuclksel_con[8]);
1772 src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
1773 if (src == CLK_UART1_SEL_OSC)
1774 return OSC_HZ;
1775 con = readl(&cru->clksel_con[27]);
1776 break;
1777 case SCLK_UART2:
1778 con = readl(&cru->clksel_con[61]);
1779 break;
1780 case SCLK_UART3:
1781 con = readl(&cru->clksel_con[62]);
1782 break;
1783 case SCLK_UART4:
1784 con = readl(&cru->clksel_con[63]);
1785 break;
1786 case SCLK_UART5:
1787 con = readl(&cru->clksel_con[64]);
1788 break;
1789 case SCLK_UART6:
1790 con = readl(&cru->clksel_con[65]);
1791 break;
1792 case SCLK_UART7:
1793 con = readl(&cru->clksel_con[66]);
1794 break;
1795 case SCLK_UART8:
1796 con = readl(&cru->clksel_con[67]);
1797 break;
1798 case SCLK_UART9:
1799 con = readl(&cru->clksel_con[68]);
1800 break;
1801 case SCLK_UART10:
1802 con = readl(&cru->clksel_con[69]);
1803 break;
1804 case SCLK_UART11:
1805 con = readl(&cru->clksel_con[70]);
1806 break;
1807 default:
1808 return -ENOENT;
1809 }
1810 if (clk_id == SCLK_UART1) {
1811 src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT;
1812 div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
1813 } else {
1814 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1815 div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT;
1816 }
1817 if (src == CLK_UART_SEL_GPLL)
1818 p_rate = priv->gpll_hz;
1819 else if (src == CLK_UART_SEL_CPLL)
1820 p_rate = priv->cpll_hz;
1821 else if (src == CLK_UART_SEL_AUPLL)
1822 p_rate = priv->aupll_hz;
1823 else if (src == CLK_UART_SEL_FRAC0)
1824 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0);
1825 else if (src == CLK_UART_SEL_FRAC1)
1826 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1);
1827 else if (src == CLK_UART_SEL_FRAC2)
1828 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2);
1829 else
1830 p_rate = OSC_HZ;
1831
1832 return DIV_TO_RATE(p_rate, div);
1833 }
1834
rk3576_uart_set_rate(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1835 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv,
1836 ulong clk_id, ulong rate)
1837 {
1838 struct rk3576_cru *cru = priv->cru;
1839 u32 reg, clk_src = 0, div = 0;
1840
1841 if (!(priv->gpll_hz % rate)) {
1842 clk_src = CLK_UART_SEL_GPLL;
1843 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1844 } else if (!(priv->cpll_hz % rate)) {
1845 clk_src = CLK_UART_SEL_CPLL;
1846 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1847 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) {
1848 clk_src = CLK_UART_SEL_FRAC0;
1849 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate);
1850 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) {
1851 clk_src = CLK_UART_SEL_FRAC1;
1852 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate);
1853 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) {
1854 clk_src = CLK_UART_SEL_FRAC2;
1855 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate);
1856 } else if (!(OSC_HZ % rate)) {
1857 clk_src = CLK_UART_SEL_OSC;
1858 div = DIV_ROUND_UP(OSC_HZ, rate);
1859 }
1860
1861 switch (clk_id) {
1862 case SCLK_UART0:
1863 reg = 60;
1864 break;
1865 case SCLK_UART1:
1866 if (rate == OSC_HZ) {
1867 rk_clrsetreg(&cru->pmuclksel_con[8],
1868 CLK_UART1_SEL_MASK,
1869 (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT));
1870 return 0;
1871 } else {
1872 rk_clrsetreg(&cru->clksel_con[27],
1873 CLK_UART1_SRC_SEL_MASK |
1874 CLK_UART1_SRC_DIV_MASK,
1875 (clk_src << CLK_UART1_SRC_SEL_SHIFT) |
1876 ((div - 1) << CLK_UART1_SRC_DIV_SHIFT));
1877 rk_clrsetreg(&cru->pmuclksel_con[8],
1878 CLK_UART1_SEL_MASK,
1879 (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT));
1880 return 0;
1881 }
1882 break;
1883 case SCLK_UART2:
1884 reg = 61;
1885 break;
1886 case SCLK_UART3:
1887 reg = 62;
1888 break;
1889 case SCLK_UART4:
1890 reg = 63;
1891 break;
1892 case SCLK_UART5:
1893 reg = 64;
1894 break;
1895 case SCLK_UART6:
1896 reg = 65;
1897 break;
1898 case SCLK_UART7:
1899 reg = 66;
1900 break;
1901 case SCLK_UART8:
1902 reg = 67;
1903 break;
1904 case SCLK_UART9:
1905 reg = 68;
1906 break;
1907 case SCLK_UART10:
1908 reg = 69;
1909 break;
1910 case SCLK_UART11:
1911 reg = 70;
1912 break;
1913 default:
1914 return -ENOENT;
1915 }
1916 rk_clrsetreg(&cru->clksel_con[reg],
1917 CLK_UART_SEL_MASK |
1918 CLK_UART_DIV_MASK,
1919 (clk_src << CLK_UART_SEL_SHIFT) |
1920 ((div - 1) << CLK_UART_DIV_SHIFT));
1921
1922 return rk3576_uart_get_rate(priv, clk_id);
1923 }
1924
rk3576_ref_clkout_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1925 static ulong rk3576_ref_clkout_get_clk(struct rk3576_clk_priv *priv,
1926 ulong clk_id)
1927 {
1928 struct rk3576_cru *cru = priv->cru;
1929 u32 reg, con, div, src, p_rate;
1930
1931 switch (clk_id) {
1932 case REF_CLK0_OUT_PLL:
1933 reg = 33;
1934 break;
1935 case REF_CLK1_OUT_PLL:
1936 reg = 34;
1937 break;
1938 case REF_CLK2_OUT_PLL:
1939 reg = 35;
1940 break;
1941 default:
1942 return -ENOENT;
1943 }
1944 con = readl(&cru->clksel_con[reg]);
1945 div = (con & REF_CLK0_OUT_PLL_DIV_MASK) >> REF_CLK0_OUT_PLL_DIV_SHIFT;
1946 src = (con & REF_CLK0_OUT_PLL_SEL_MASK) >> REF_CLK0_OUT_PLL_SEL_SHIFT;
1947 if (src == REF_CLK0_OUT_PLL_SEL_GPLL)
1948 p_rate = priv->gpll_hz;
1949 else if (src == REF_CLK0_OUT_PLL_SEL_CPLL)
1950 p_rate = priv->cpll_hz;
1951 else if (src == REF_CLK0_OUT_PLL_SEL_SPLL)
1952 p_rate = priv->spll_hz;
1953 else if (src == REF_CLK0_OUT_PLL_SEL_AUPLL)
1954 p_rate = priv->aupll_hz;
1955 else if (src == REF_CLK0_OUT_PLL_SEL_LPLL)
1956 p_rate = priv->lpll_hz / 2;
1957 else
1958 p_rate = OSC_HZ;
1959 return DIV_TO_RATE(p_rate, div);
1960 }
1961
rk3576_ref_clkout_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1962 static ulong rk3576_ref_clkout_set_clk(struct rk3576_clk_priv *priv,
1963 ulong clk_id, ulong rate)
1964 {
1965 struct rk3576_cru *cru = priv->cru;
1966 ulong p_rate, now, best_rate = 0;
1967 u32 i, con, div, best_div = 0, best_sel = 0;
1968
1969 switch (clk_id) {
1970 case REF_CLK0_OUT_PLL:
1971 con = 33;
1972 break;
1973 case REF_CLK1_OUT_PLL:
1974 con = 34;
1975 break;
1976 case REF_CLK2_OUT_PLL:
1977 con = 35;
1978 break;
1979 default:
1980 return -ENOENT;
1981 }
1982
1983 for (i = 0; i <= REF_CLK0_OUT_PLL_SEL_OSC; i++) {
1984 switch (i) {
1985 case REF_CLK0_OUT_PLL_SEL_GPLL:
1986 p_rate = priv->gpll_hz;
1987 break;
1988 case REF_CLK0_OUT_PLL_SEL_CPLL:
1989 p_rate = priv->cpll_hz;
1990 break;
1991 case REF_CLK0_OUT_PLL_SEL_SPLL:
1992 p_rate = priv->spll_hz;
1993 break;
1994 case REF_CLK0_OUT_PLL_SEL_AUPLL:
1995 p_rate = priv->aupll_hz;
1996 break;
1997 case REF_CLK0_OUT_PLL_SEL_LPLL:
1998 p_rate = 0;
1999 break;
2000 case REF_CLK0_OUT_PLL_SEL_OSC:
2001 p_rate = OSC_HZ;
2002 break;
2003 default:
2004 printf("do not support this vop pll sel\n");
2005 return -EINVAL;
2006 }
2007
2008 div = DIV_ROUND_UP(p_rate, rate);
2009 if (div > 255)
2010 continue;
2011 now = p_rate / div;
2012 if (abs(rate - now) < abs(rate - best_rate)) {
2013 best_rate = now;
2014 best_div = div;
2015 best_sel = i;
2016 }
2017 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
2018 p_rate, best_rate, best_div, best_sel);
2019 }
2020 if (best_rate) {
2021 rk_clrsetreg(&cru->clksel_con[con],
2022 REF_CLK0_OUT_PLL_DIV_MASK |
2023 REF_CLK0_OUT_PLL_SEL_MASK,
2024 best_sel << REF_CLK0_OUT_PLL_SEL_SHIFT |
2025 (best_div - 1) << REF_CLK0_OUT_PLL_DIV_SHIFT);
2026 } else {
2027 printf("do not support this vop freq %lu\n", rate);
2028 return -EINVAL;
2029 }
2030
2031 return rk3576_ref_clkout_get_clk(priv, clk_id);
2032 }
2033
2034 #endif
2035
rk3576_ufs_ref_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)2036 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
2037 {
2038 struct rk3576_cru *cru = priv->cru;
2039 u32 src, div;
2040
2041 src = readl(&cru->pmuclksel_con[3]) & 0x3;
2042 div= readl(&cru->pmuclksel_con[1]) & 0xff;
2043 if (src == 0)
2044 return OSC_HZ;
2045 else if (src == 2)
2046 return priv->ppll_hz / (div + 1);
2047 else
2048 return 26000000;
2049
2050 }
2051
rk3576_clk_get_rate(struct clk * clk)2052 static ulong rk3576_clk_get_rate(struct clk *clk)
2053 {
2054 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2055 ulong rate = 0;
2056
2057 if (!priv->gpll_hz) {
2058 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2059 return -ENOENT;
2060 }
2061
2062 if (!priv->ppll_hz) {
2063 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2064 priv->cru, PPLL);
2065 }
2066
2067 switch (clk->id) {
2068 case PLL_LPLL:
2069 rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru,
2070 LPLL);
2071 priv->lpll_hz = rate;
2072 break;
2073 case PLL_BPLL:
2074 rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru,
2075 BPLL);
2076 priv->bpll_hz = rate;
2077 break;
2078 case PLL_GPLL:
2079 rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru,
2080 GPLL);
2081 break;
2082 case PLL_CPLL:
2083 rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru,
2084 CPLL);
2085 break;
2086 case PLL_VPLL:
2087 rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru,
2088 VPLL);
2089 break;
2090 case PLL_AUPLL:
2091 rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru,
2092 AUPLL);
2093 break;
2094 case PLL_PPLL:
2095 rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru,
2096 PPLL) * 2;
2097 break;
2098 case ACLK_BUS_ROOT:
2099 case HCLK_BUS_ROOT:
2100 case PCLK_BUS_ROOT:
2101 rate = rk3576_bus_get_clk(priv, clk->id);
2102 break;
2103 case ACLK_TOP:
2104 case HCLK_TOP:
2105 case PCLK_TOP_ROOT:
2106 case ACLK_TOP_MID:
2107 rate = rk3576_top_get_clk(priv, clk->id);
2108 break;
2109 case CLK_I2C0:
2110 case CLK_I2C1:
2111 case CLK_I2C2:
2112 case CLK_I2C3:
2113 case CLK_I2C4:
2114 case CLK_I2C5:
2115 case CLK_I2C6:
2116 case CLK_I2C7:
2117 case CLK_I2C8:
2118 case CLK_I2C9:
2119 rate = rk3576_i2c_get_clk(priv, clk->id);
2120 break;
2121 case CLK_SPI0:
2122 case CLK_SPI1:
2123 case CLK_SPI2:
2124 case CLK_SPI3:
2125 case CLK_SPI4:
2126 rate = rk3576_spi_get_clk(priv, clk->id);
2127 break;
2128 case CLK_PWM1:
2129 case CLK_PWM2:
2130 case CLK_PMU1PWM:
2131 rate = rk3576_pwm_get_clk(priv, clk->id);
2132 break;
2133 case CLK_SARADC:
2134 case CLK_TSADC:
2135 rate = rk3576_adc_get_clk(priv, clk->id);
2136 break;
2137 case CCLK_SRC_SDIO:
2138 case CCLK_SRC_SDMMC0:
2139 case CCLK_SRC_EMMC:
2140 case BCLK_EMMC:
2141 case SCLK_FSPI_X2:
2142 case SCLK_FSPI1_X2:
2143 case DCLK_DECOM:
2144 case HCLK_SDMMC0:
2145 case HCLK_EMMC:
2146 case HCLK_SDIO:
2147 rate = rk3576_mmc_get_clk(priv, clk->id);
2148 break;
2149 case TCLK_WDT0:
2150 rate = OSC_HZ;
2151 break;
2152 #ifndef CONFIG_SPL_BUILD
2153 case ACLK_VOP_ROOT:
2154 case ACLK_VOP:
2155 case ACLK_VO0_ROOT:
2156 case ACLK_VO1_ROOT:
2157 case HCLK_VOP_ROOT:
2158 case PCLK_VOP_ROOT:
2159 rate = rk3576_aclk_vop_get_clk(priv, clk->id);
2160 break;
2161 case DCLK_VP0:
2162 case DCLK_VP0_SRC:
2163 case DCLK_VP1:
2164 case DCLK_VP1_SRC:
2165 case DCLK_VP2:
2166 case DCLK_VP2_SRC:
2167 rate = rk3576_dclk_vop_get_clk(priv, clk->id);
2168 break;
2169 case CLK_GMAC0_PTP_REF_SRC:
2170 case CLK_GMAC1_PTP_REF_SRC:
2171 case CLK_GMAC0_PTP_REF:
2172 case CLK_GMAC1_PTP_REF:
2173 case CLK_GMAC0_125M_SRC:
2174 case CLK_GMAC1_125M_SRC:
2175 rate = rk3576_gmac_get_clk(priv, clk->id);
2176 break;
2177 case CLK_UART_FRAC_0:
2178 case CLK_UART_FRAC_1:
2179 case CLK_UART_FRAC_2:
2180 rate = rk3576_uart_frac_get_rate(priv, clk->id);
2181 break;
2182 case SCLK_UART0:
2183 case SCLK_UART1:
2184 case SCLK_UART2:
2185 case SCLK_UART3:
2186 case SCLK_UART4:
2187 case SCLK_UART5:
2188 case SCLK_UART6:
2189 case SCLK_UART7:
2190 case SCLK_UART8:
2191 case SCLK_UART9:
2192 case SCLK_UART10:
2193 case SCLK_UART11:
2194 rate = rk3576_uart_get_rate(priv, clk->id);
2195 break;
2196 case CLK_DSIHOST0:
2197 rate = rk3576_clk_csihost_get_clk(priv, clk->id);
2198 break;
2199 case DCLK_EBC:
2200 case DCLK_EBC_FRAC_SRC:
2201 rate = rk3576_dclk_ebc_get_clk(priv, clk->id);
2202 break;
2203 case REF_CLK0_OUT_PLL:
2204 case REF_CLK1_OUT_PLL:
2205 case REF_CLK2_OUT_PLL:
2206 rate = rk3576_ref_clkout_get_clk(priv, clk->id);
2207 break;
2208 #endif
2209 case CLK_REF_UFS_CLKOUT:
2210 case CLK_REF_OSC_MPHY:
2211 rate = rk3576_ufs_ref_get_rate(priv, clk->id);
2212 break;
2213
2214 default:
2215 return -ENOENT;
2216 }
2217
2218 return rate;
2219 };
2220
rk3576_clk_set_rate(struct clk * clk,ulong rate)2221 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
2222 {
2223 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2224 ulong ret = 0;
2225
2226 if (!priv->ppll_hz) {
2227 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2228 priv->cru, PPLL);
2229 }
2230 if (!priv->aupll_hz) {
2231 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2232 priv->cru, AUPLL);
2233 }
2234
2235 switch (clk->id) {
2236 case PLL_CPLL:
2237 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2238 CPLL, rate);
2239 priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL],
2240 priv->cru, CPLL);
2241 break;
2242 case PLL_GPLL:
2243 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2244 GPLL, rate);
2245 priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL],
2246 priv->cru, GPLL);
2247 break;
2248 case PLL_VPLL:
2249 ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru,
2250 VPLL, rate);
2251 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
2252 priv->cru, VPLL);
2253 break;
2254 case PLL_AUPLL:
2255 ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru,
2256 AUPLL, rate);
2257 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2258 priv->cru, AUPLL);
2259 break;
2260 case PLL_PPLL:
2261 ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru,
2262 PPLL, rate);
2263 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2264 priv->cru, PPLL) * 2;
2265 break;
2266 case ACLK_BUS_ROOT:
2267 case HCLK_BUS_ROOT:
2268 case PCLK_BUS_ROOT:
2269 ret = rk3576_bus_set_clk(priv, clk->id, rate);
2270 break;
2271 case ACLK_TOP:
2272 case HCLK_TOP:
2273 case PCLK_TOP_ROOT:
2274 case ACLK_TOP_MID:
2275 ret = rk3576_top_set_clk(priv, clk->id, rate);
2276 break;
2277 case CLK_I2C0:
2278 case CLK_I2C1:
2279 case CLK_I2C2:
2280 case CLK_I2C3:
2281 case CLK_I2C4:
2282 case CLK_I2C5:
2283 case CLK_I2C6:
2284 case CLK_I2C7:
2285 case CLK_I2C8:
2286 case CLK_I2C9:
2287 ret = rk3576_i2c_set_clk(priv, clk->id, rate);
2288 break;
2289 case CLK_SPI0:
2290 case CLK_SPI1:
2291 case CLK_SPI2:
2292 case CLK_SPI3:
2293 case CLK_SPI4:
2294 ret = rk3576_spi_set_clk(priv, clk->id, rate);
2295 break;
2296 case CLK_PWM1:
2297 case CLK_PWM2:
2298 case CLK_PMU1PWM:
2299 ret = rk3576_pwm_set_clk(priv, clk->id, rate);
2300 break;
2301 case CLK_SARADC:
2302 case CLK_TSADC:
2303 ret = rk3576_adc_set_clk(priv, clk->id, rate);
2304 break;
2305 case CCLK_SRC_SDIO:
2306 case CCLK_SRC_SDMMC0:
2307 case CCLK_SRC_EMMC:
2308 case BCLK_EMMC:
2309 case SCLK_FSPI_X2:
2310 case SCLK_FSPI1_X2:
2311 case DCLK_DECOM:
2312 case HCLK_SDMMC0:
2313 case HCLK_EMMC:
2314 case HCLK_SDIO:
2315 ret = rk3576_mmc_set_clk(priv, clk->id, rate);
2316 break;
2317 case TCLK_WDT0:
2318 ret = OSC_HZ;
2319 break;
2320 #ifndef CONFIG_SPL_BUILD
2321 case ACLK_VOP_ROOT:
2322 case ACLK_VOP:
2323 case ACLK_VO0_ROOT:
2324 case ACLK_VO1_ROOT:
2325 case HCLK_VOP_ROOT:
2326 case PCLK_VOP_ROOT:
2327 ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate);
2328 break;
2329 case DCLK_VP0:
2330 case DCLK_VP0_SRC:
2331 case DCLK_VP1:
2332 case DCLK_VP1_SRC:
2333 case DCLK_VP2:
2334 case DCLK_VP2_SRC:
2335 ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate);
2336 break;
2337 case CLK_GMAC0_PTP_REF_SRC:
2338 case CLK_GMAC1_PTP_REF_SRC:
2339 case CLK_GMAC0_PTP_REF:
2340 case CLK_GMAC1_PTP_REF:
2341 case CLK_GMAC0_125M_SRC:
2342 case CLK_GMAC1_125M_SRC:
2343 ret = rk3576_gmac_set_clk(priv, clk->id, rate);
2344 break;
2345 case CLK_UART_FRAC_0:
2346 case CLK_UART_FRAC_1:
2347 case CLK_UART_FRAC_2:
2348 ret = rk3576_uart_frac_set_rate(priv, clk->id, rate);
2349 break;
2350 case SCLK_UART0:
2351 case SCLK_UART1:
2352 case SCLK_UART2:
2353 case SCLK_UART3:
2354 case SCLK_UART4:
2355 case SCLK_UART5:
2356 case SCLK_UART6:
2357 case SCLK_UART7:
2358 case SCLK_UART8:
2359 case SCLK_UART9:
2360 case SCLK_UART10:
2361 case SCLK_UART11:
2362 ret = rk3576_uart_set_rate(priv, clk->id, rate);
2363 break;
2364 case CLK_DSIHOST0:
2365 ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate);
2366 break;
2367 case DCLK_EBC:
2368 case DCLK_EBC_FRAC_SRC:
2369 ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate);
2370 break;
2371 case REF_CLK0_OUT_PLL:
2372 case REF_CLK1_OUT_PLL:
2373 case REF_CLK2_OUT_PLL:
2374 ret = rk3576_ref_clkout_set_clk(priv, clk->id, rate);
2375 break;
2376 #endif
2377 default:
2378 return -ENOENT;
2379 }
2380
2381 return ret;
2382 };
2383
2384 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
rk3576_dclk_vop_set_parent(struct clk * clk,struct clk * parent)2385 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk,
2386 struct clk *parent)
2387 {
2388 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2389 struct rk3576_cru *cru = priv->cru;
2390 u32 sel;
2391 const char *clock_dev_name = parent->dev->name;
2392
2393 if (parent->id == PLL_VPLL)
2394 sel = 2;
2395 else if (parent->id == PLL_GPLL)
2396 sel = 0;
2397 else if (parent->id == PLL_CPLL)
2398 sel = 1;
2399 else if (parent->id == PLL_BPLL)
2400 sel = 3;
2401 else
2402 sel = 4;
2403
2404 switch (clk->id) {
2405 case DCLK_VP0_SRC:
2406 rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK,
2407 sel << DCLK0_VOP_SRC_SEL_SHIFT);
2408 break;
2409 case DCLK_VP1_SRC:
2410 rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK,
2411 sel << DCLK0_VOP_SRC_SEL_SHIFT);
2412 break;
2413 case DCLK_VP2_SRC:
2414 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK,
2415 sel << DCLK0_VOP_SRC_SEL_SHIFT);
2416 break;
2417 case DCLK_VP0:
2418 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2419 sel = 1;
2420 else
2421 sel = 0;
2422 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK,
2423 sel << DCLK0_VOP_SEL_SHIFT);
2424 break;
2425 case DCLK_VP1:
2426 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2427 sel = 1;
2428 else
2429 sel = 0;
2430 rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK,
2431 sel << DCLK1_VOP_SEL_SHIFT);
2432 break;
2433 case DCLK_VP2:
2434 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2435 sel = 1;
2436 else
2437 sel = 0;
2438 rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK,
2439 sel << DCLK2_VOP_SEL_SHIFT);
2440 break;
2441 case DCLK_EBC:
2442 if (parent->id == PLL_GPLL)
2443 sel = 0;
2444 else if (parent->id == PLL_CPLL)
2445 sel = 1;
2446 else if (parent->id == PLL_VPLL)
2447 sel = 2;
2448 else if (parent->id == PLL_AUPLL)
2449 sel = 3;
2450 else if (parent->id == PLL_LPLL)
2451 sel = 4;
2452 else if (parent->id == DCLK_EBC_FRAC_SRC)
2453 sel = 5;
2454 else
2455 sel = 6;
2456 rk_clrsetreg(&cru->clksel_con[123], DCLK_EBC_SEL_MASK,
2457 sel << DCLK_EBC_SEL_SHIFT);
2458 break;
2459 default:
2460 return -EINVAL;
2461 }
2462 return 0;
2463 }
2464
rk3576_ufs_ref_set_parent(struct clk * clk,struct clk * parent)2465 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk,
2466 struct clk *parent)
2467 {
2468 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2469 struct rk3576_cru *cru = priv->cru;
2470 u32 sel;
2471 const char *clock_dev_name = parent->dev->name;
2472
2473 if (parent->id == CLK_REF_MPHY_26M)
2474 sel = 2;
2475 else if (!strcmp(clock_dev_name, "xin24m"))
2476 sel = 0;
2477 else
2478 sel = 1;
2479
2480 rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0);
2481 return 0;
2482 }
2483
rk3576_clk_set_parent(struct clk * clk,struct clk * parent)2484 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent)
2485 {
2486 switch (clk->id) {
2487 case DCLK_VP0_SRC:
2488 case DCLK_VP1_SRC:
2489 case DCLK_VP2_SRC:
2490 case DCLK_VP0:
2491 case DCLK_VP1:
2492 case DCLK_VP2:
2493 case DCLK_EBC:
2494 return rk3576_dclk_vop_set_parent(clk, parent);
2495 case CLK_REF_OSC_MPHY:
2496 return rk3576_ufs_ref_set_parent(clk, parent);
2497
2498 default:
2499 return -ENOENT;
2500 }
2501
2502 return 0;
2503 }
2504 #endif
2505
2506 static struct clk_ops rk3576_clk_ops = {
2507 .get_rate = rk3576_clk_get_rate,
2508 .set_rate = rk3576_clk_set_rate,
2509 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2510 .set_parent = rk3576_clk_set_parent,
2511 #endif
2512 };
2513
rk3576_clk_init(struct rk3576_clk_priv * priv)2514 static void rk3576_clk_init(struct rk3576_clk_priv *priv)
2515 {
2516 int ret;
2517
2518 priv->spll_hz = 702000000;
2519
2520 if (priv->cpll_hz != CPLL_HZ) {
2521 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2522 CPLL, CPLL_HZ);
2523 if (!ret)
2524 priv->cpll_hz = CPLL_HZ;
2525 }
2526 if (priv->gpll_hz != GPLL_HZ) {
2527 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2528 GPLL, GPLL_HZ);
2529 if (!ret)
2530 priv->gpll_hz = GPLL_HZ;
2531 }
2532 rk_clrsetreg(&priv->cru->clksel_con[123],
2533 DCLK_EBC_FRAC_SRC_SEL_MASK,
2534 (DCLK_EBC_FRAC_SRC_SEL_GPLL <<
2535 DCLK_EBC_FRAC_SRC_SEL_SHIFT));
2536 }
2537
rk3576_clk_probe(struct udevice * dev)2538 static int rk3576_clk_probe(struct udevice *dev)
2539 {
2540 struct rk3576_clk_priv *priv = dev_get_priv(dev);
2541 int ret;
2542 #if CONFIG_IS_ENABLED(CLK_SCMI)
2543 struct clk clk;
2544 #endif
2545
2546 priv->sync_kernel = false;
2547
2548 #ifdef CONFIG_SPL_BUILD
2549 /* relase presetn_bigcore_biu/cru/grf */
2550 writel(0x1c001c00, 0x26010010);
2551 /* set spll to normal mode */
2552 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2553 RK3576_SCRU_BASE + RK3576_PLL_CON(137));
2554 writel(BITS_WITH_WMASK(1, 0x3U, 0),
2555 RK3576_SCRU_BASE + RK3576_MODE_CON0);
2556 /* fix ppll\aupll\cpll */
2557 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2558 RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129));
2559 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2560 RK3576_CRU_BASE + RK3576_PLL_CON(97));
2561 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2562 RK3576_CRU_BASE + RK3576_PLL_CON(105));
2563 writel(BITS_WITH_WMASK(1, 0x3U, 6),
2564 RK3576_CRU_BASE + RK3576_MODE_CON0);
2565 writel(BITS_WITH_WMASK(1, 0x3U, 8),
2566 RK3576_CRU_BASE + RK3576_MODE_CON0);
2567 if (!(readl(RK3576_CRU_BASE + RK3576_LITCORE_CLKSEL_CON(0)) & CLK_LITCORE_SEL_MASK)) {
2568 /* init cci */
2569 writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2570 if (!priv->armclk_enter_hz) {
2571 ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru,
2572 LPLL, LPLL_HZ);
2573 priv->armclk_enter_hz =
2574 rockchip_pll_get_rate(&rk3576_pll_clks[LPLL],
2575 priv->cru, LPLL);
2576 priv->armclk_init_hz = priv->armclk_enter_hz;
2577 rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK,
2578 0 << CLK_LITCORE_DIV_SHIFT);
2579 }
2580 /* init cci */
2581 writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2582
2583 }
2584 if (!(readl(RK3576_CRU_BASE + RK3576_BIGCORE_CLKSEL_CON(0)) & CLK_BIGCORE_SEL_MASK)) {
2585 rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru,
2586 BPLL, LPLL_HZ);
2587 /* Change bigcore rm from 4 to 3 */
2588 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c);
2589 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44);
2590 writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38);
2591 udelay(1);
2592 writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38);
2593 }
2594 #endif
2595
2596 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2597 if (IS_ERR(priv->grf))
2598 return PTR_ERR(priv->grf);
2599
2600 rk3576_clk_init(priv);
2601
2602 #if CONFIG_IS_ENABLED(CLK_SCMI)
2603 #ifndef CONFIG_SPL_BUILD
2604 ret = rockchip_get_scmi_clk(&clk.dev);
2605 if (ret) {
2606 printf("Failed to get scmi clk dev, ret=%d\n", ret);
2607 return ret;
2608 }
2609 if (!priv->armclk_enter_hz) {
2610 clk.id = ARMCLK_L;
2611 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2612 if (ret < 0) {
2613 printf("Failed to set cpubl, ret=%d\n", ret);
2614 } else {
2615 priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2616 priv->armclk_init_hz = CPU_PVTPLL_HZ;
2617 }
2618 }
2619 clk.id = ARMCLK_B;
2620 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2621 if (ret < 0)
2622 printf("Failed to set cpub, ret=%d\n", ret);
2623 #endif
2624 #endif
2625
2626 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2627 ret = clk_set_defaults(dev);
2628 if (ret)
2629 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2630 else
2631 priv->sync_kernel = true;
2632
2633 return 0;
2634 }
2635
rk3576_clk_ofdata_to_platdata(struct udevice * dev)2636 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev)
2637 {
2638 struct rk3576_clk_priv *priv = dev_get_priv(dev);
2639
2640 priv->cru = dev_read_addr_ptr(dev);
2641
2642 return 0;
2643 }
2644
rk3576_clk_bind(struct udevice * dev)2645 static int rk3576_clk_bind(struct udevice *dev)
2646 {
2647 int ret;
2648 struct udevice *sys_child, *sf_child;
2649 struct sysreset_reg *priv;
2650 struct softreset_reg *sf_priv;
2651
2652 /* The reset driver does not have a device node, so bind it here */
2653 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2654 &sys_child);
2655 if (ret) {
2656 debug("Warning: No sysreset driver: ret=%d\n", ret);
2657 } else {
2658 priv = malloc(sizeof(struct sysreset_reg));
2659 priv->glb_srst_fst_value = offsetof(struct rk3576_cru,
2660 glb_srst_fst);
2661 priv->glb_srst_snd_value = offsetof(struct rk3576_cru,
2662 glb_srsr_snd);
2663 sys_child->priv = priv;
2664 }
2665
2666 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2667 dev_ofnode(dev), &sf_child);
2668 if (ret) {
2669 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2670 } else {
2671 sf_priv = malloc(sizeof(struct softreset_reg));
2672 sf_priv->sf_reset_offset = offsetof(struct rk3576_cru,
2673 softrst_con[0]);
2674 sf_priv->sf_reset_num = 524454;
2675 sf_child->priv = sf_priv;
2676 }
2677
2678 return 0;
2679 }
2680
2681 static const struct udevice_id rk3576_clk_ids[] = {
2682 { .compatible = "rockchip,rk3576-cru" },
2683 { }
2684 };
2685
2686 U_BOOT_DRIVER(rockchip_rk3576_cru) = {
2687 .name = "rockchip_rk3576_cru",
2688 .id = UCLASS_CLK,
2689 .of_match = rk3576_clk_ids,
2690 .priv_auto_alloc_size = sizeof(struct rk3576_clk_priv),
2691 .ofdata_to_platdata = rk3576_clk_ofdata_to_platdata,
2692 .ops = &rk3576_clk_ops,
2693 .bind = rk3576_clk_bind,
2694 .probe = rk3576_clk_probe,
2695 };
2696
2697 #ifndef CONFIG_SPL_BUILD
2698 /**
2699 * soc_clk_dump() - Print clock frequencies
2700 * Returns zero on success
2701 *
2702 * Implementation for the clk dump command.
2703 */
soc_clk_dump(void)2704 int soc_clk_dump(void)
2705 {
2706 struct udevice *cru_dev;
2707 struct rk3576_clk_priv *priv;
2708 const struct rk3576_clk_info *clk_dump;
2709 struct clk clk;
2710 unsigned long clk_count = ARRAY_SIZE(clks_dump);
2711 unsigned long rate;
2712 int i, ret;
2713
2714 ret = uclass_get_device_by_driver(UCLASS_CLK,
2715 DM_GET_DRIVER(rockchip_rk3576_cru),
2716 &cru_dev);
2717 if (ret) {
2718 printf("%s failed to get cru device\n", __func__);
2719 return ret;
2720 }
2721
2722 priv = dev_get_priv(cru_dev);
2723 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2724 priv->sync_kernel ? "sync kernel" : "uboot",
2725 priv->armclk_enter_hz / 1000,
2726 priv->armclk_init_hz / 1000,
2727 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2728 priv->set_armclk_rate ? " KHz" : "N/A");
2729 for (i = 0; i < clk_count; i++) {
2730 clk_dump = &clks_dump[i];
2731 if (clk_dump->name) {
2732 memset(&clk, 0, sizeof(struct clk));
2733 clk.id = clk_dump->id;
2734 if (clk_dump->is_cru)
2735 ret = clk_request(cru_dev, &clk);
2736 if (ret < 0)
2737 return ret;
2738
2739 rate = clk_get_rate(&clk);
2740 clk_free(&clk);
2741 if (rate < 0)
2742 printf(" %s %s\n", clk_dump->name,
2743 "unknown");
2744 else
2745 printf(" %s %lu KHz\n", clk_dump->name,
2746 rate / 1000);
2747 }
2748 }
2749
2750 return 0;
2751 }
2752 #endif
2753