1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2022 Fuzhou Rockchip Electronics Co., Ltd
4 * Author: Joseph Chen <chenjh@rock-chips.com>
5 */
6
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <syscon.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/cru_rk3528.h>
13 #include <asm/arch/grf_rk3528.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/io.h>
16 #include <dm/lists.h>
17 #include <dt-bindings/clock/rk3528-cru.h>
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
22
23 /*
24 * PLL attention.
25 *
26 * [FRAC PLL]: GPLL, PPLL, DPLL
27 * - frac mode: refdiv can be 1 or 2 only
28 * - int mode: refdiv has no special limit
29 * - VCO range: [950, 3800] MHZ
30 *
31 * [INT PLL]: CPLL, APLL
32 * - int mode: refdiv can be 1 or 2 only
33 * - VCO range: [475, 1900] MHZ
34 *
35 * [PPLL]: normal mode only.
36 *
37 */
38 static struct rockchip_pll_rate_table rk3528_pll_rates[] = {
39 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
40 RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
41 RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
42 RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
43 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
44 RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
45 RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
46 RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
47 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
48 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), /* GPLL */
49 RK3036_PLL_RATE(1092000000, 2, 91, 1, 1, 1, 0),
50 RK3036_PLL_RATE(1008000000, 1, 42, 1, 1, 1, 0),
51 RK3036_PLL_RATE(1000000000, 1, 125, 3, 1, 1, 0), /* PPLL */
52 RK3036_PLL_RATE(996000000, 2, 83, 1, 1, 1, 0), /* CPLL */
53 RK3036_PLL_RATE(960000000, 1, 40, 1, 1, 1, 0),
54 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
55 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
56 RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
57 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
58 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
59 RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
60 RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
61 RK3036_PLL_RATE(96000000, 1, 24, 3, 2, 1, 0),
62 { /* sentinel */ },
63 };
64
65 static struct rockchip_pll_clock rk3528_pll_clks[] = {
66 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3528_PLL_CON(0),
67 RK3528_MODE_CON, 0, 10, 0, rk3528_pll_rates),
68
69 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3528_PLL_CON(8),
70 RK3528_MODE_CON, 2, 10, 0, rk3528_pll_rates),
71
72 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3528_PLL_CON(24),
73 RK3528_MODE_CON, 4, 10, 0, rk3528_pll_rates),
74
75 [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3528_PCIE_PLL_CON(32),
76 RK3528_MODE_CON, 6, 10, ROCKCHIP_PLL_FIXED_MODE, rk3528_pll_rates),
77
78 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3528_DDRPHY_PLL_CON(16),
79 RK3528_DDRPHY_MODE_CON, 0, 10, 0, rk3528_pll_rates),
80 };
81
82 #define RK3528_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg) \
83 { \
84 .rate = _rate##U, \
85 .aclk_div = (_aclk_m_core), \
86 .pclk_div = (_pclk_dbg), \
87 }
88
89 /* sign-off: _aclk_m_core: 550M, _pclk_dbg: 137.5M, */
90 static struct rockchip_cpu_rate_table rk3528_cpu_rates[] = {
91 RK3528_CPUCLK_RATE(1896000000, 1, 13),
92 RK3528_CPUCLK_RATE(1800000000, 1, 12),
93 RK3528_CPUCLK_RATE(1704000000, 1, 11),
94 RK3528_CPUCLK_RATE(1608000000, 1, 11),
95 RK3528_CPUCLK_RATE(1512000000, 1, 11),
96 RK3528_CPUCLK_RATE(1416000000, 1, 9),
97 RK3528_CPUCLK_RATE(1296000000, 1, 8),
98 RK3528_CPUCLK_RATE(1200000000, 1, 8),
99 RK3528_CPUCLK_RATE(1188000000, 1, 8),
100 RK3528_CPUCLK_RATE(1092000000, 1, 7),
101 RK3528_CPUCLK_RATE(1008000000, 1, 6),
102 RK3528_CPUCLK_RATE(1000000000, 1, 6),
103 RK3528_CPUCLK_RATE(996000000, 1, 6),
104 RK3528_CPUCLK_RATE(960000000, 1, 6),
105 RK3528_CPUCLK_RATE(912000000, 1, 6),
106 RK3528_CPUCLK_RATE(816000000, 1, 5),
107 RK3528_CPUCLK_RATE(600000000, 1, 3),
108 RK3528_CPUCLK_RATE(594000000, 1, 3),
109 RK3528_CPUCLK_RATE(408000000, 1, 2),
110 RK3528_CPUCLK_RATE(312000000, 1, 2),
111 RK3528_CPUCLK_RATE(216000000, 1, 1),
112 RK3528_CPUCLK_RATE(96000000, 1, 0),
113 };
114
115 #ifndef CONFIG_SPL_BUILD
116 #define RK3528_CLK_DUMP(_id, _name) \
117 { \
118 .id = _id, \
119 .name = _name, \
120 }
121
122 static const struct rk3528_clk_info clks_dump[] = {
123 RK3528_CLK_DUMP(PLL_APLL, "apll"),
124 RK3528_CLK_DUMP(PLL_GPLL, "gpll"),
125 RK3528_CLK_DUMP(PLL_CPLL, "cpll"),
126 RK3528_CLK_DUMP(PLL_DPLL, "dpll"),
127 RK3528_CLK_DUMP(PLL_PPLL, "ppll"),
128 RK3528_CLK_DUMP(CLK_MATRIX_50M_SRC, "clk_50m"),
129 RK3528_CLK_DUMP(CLK_MATRIX_100M_SRC, "clk_100m"),
130 RK3528_CLK_DUMP(CLK_MATRIX_150M_SRC, "clk_150m"),
131 RK3528_CLK_DUMP(CLK_MATRIX_200M_SRC, "clk_200m"),
132 RK3528_CLK_DUMP(CLK_MATRIX_250M_SRC, "clk_250m"),
133 RK3528_CLK_DUMP(CLK_MATRIX_300M_SRC, "clk_300m"),
134 RK3528_CLK_DUMP(CLK_MATRIX_339M_SRC, "clk_339m"),
135 RK3528_CLK_DUMP(CLK_MATRIX_400M_SRC, "clk_400m"),
136 RK3528_CLK_DUMP(CLK_MATRIX_500M_SRC, "clk_500m"),
137 RK3528_CLK_DUMP(CLK_MATRIX_600M_SRC, "clk_600m"),
138 RK3528_CLK_DUMP(CLK_PPLL_50M_MATRIX, "clk_ppll_50m"),
139 RK3528_CLK_DUMP(CLK_PPLL_100M_MATRIX, "clk_ppll_100m"),
140 RK3528_CLK_DUMP(CLK_PPLL_125M_MATRIX, "clk_ppll_125m"),
141 };
142 #endif
143
144 /*
145 *
146 * rational_best_approximation(31415, 10000,
147 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
148 *
149 * you may look at given_numerator as a fixed point number,
150 * with the fractional part size described in given_denominator.
151 *
152 * for theoretical background, see:
153 * http://en.wikipedia.org/wiki/Continued_fraction
154 */
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)155 static void rational_best_approximation(unsigned long given_numerator,
156 unsigned long given_denominator,
157 unsigned long max_numerator,
158 unsigned long max_denominator,
159 unsigned long *best_numerator,
160 unsigned long *best_denominator)
161 {
162 unsigned long n, d, n0, d0, n1, d1;
163
164 n = given_numerator;
165 d = given_denominator;
166 n0 = 0;
167 d1 = 0;
168 n1 = 1;
169 d0 = 1;
170 for (;;) {
171 unsigned long t, a;
172
173 if (n1 > max_numerator || d1 > max_denominator) {
174 n1 = n0;
175 d1 = d0;
176 break;
177 }
178 if (d == 0)
179 break;
180 t = d;
181 a = n / d;
182 d = n % d;
183 n = t;
184 t = n0 + a * n1;
185 n0 = n1;
186 n1 = t;
187 t = d0 + a * d1;
188 d0 = d1;
189 d1 = t;
190 }
191 *best_numerator = n1;
192 *best_denominator = d1;
193 }
194
rk3528_armclk_set_clk(struct rk3528_clk_priv * priv,ulong new_rate)195 static int rk3528_armclk_set_clk(struct rk3528_clk_priv *priv, ulong new_rate)
196 {
197 const struct rockchip_cpu_rate_table *rate;
198 struct rk3528_cru *cru = priv->cru;
199 ulong old_rate;
200
201 rate = rockchip_get_cpu_settings(rk3528_cpu_rates, new_rate);
202 if (!rate) {
203 printf("%s unsupported rate\n", __func__);
204 return -EINVAL;
205 }
206
207 /*
208 * set up dependent divisors for DBG and ACLK clocks.
209 */
210 old_rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, APLL);
211 if (old_rate > new_rate) {
212 if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL],
213 priv->cru, APLL, new_rate))
214 return -EINVAL;
215
216 rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK,
217 rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT);
218
219 rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK,
220 rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT);
221 } else if (old_rate < new_rate) {
222 rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK,
223 rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT);
224
225 rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK,
226 rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT);
227
228 if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL],
229 priv->cru, APLL, new_rate))
230 return -EINVAL;
231 }
232
233 return 0;
234 }
235
rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)236 static ulong rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv *priv,
237 ulong clk_id)
238 {
239 struct rk3528_cru *cru = priv->cru;
240 u32 div, mask, shift;
241 void *reg;
242
243 switch (clk_id) {
244 case CLK_PPLL_50M_MATRIX:
245 case CLK_GMAC1_RMII_VPU:
246 mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK;
247 shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT;
248 reg = &cru->pcieclksel_con[1];
249 break;
250
251 case CLK_PPLL_100M_MATRIX:
252 mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK;
253 shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT;
254 reg = &cru->pcieclksel_con[1];
255 break;
256
257 case CLK_PPLL_125M_MATRIX:
258 case CLK_GMAC1_SRC_VPU:
259 mask = CLK_MATRIX_125M_SRC_DIV_MASK;
260 shift = CLK_MATRIX_125M_SRC_DIV_SHIFT;
261 reg = &cru->clksel_con[60];
262 break;
263
264 case CLK_GMAC1_VPU_25M:
265 mask = CLK_MATRIX_25M_SRC_DIV_MASK;
266 shift = CLK_MATRIX_25M_SRC_DIV_SHIFT;
267 reg = &cru->clksel_con[60];
268 break;
269 default:
270 return -ENOENT;
271 }
272
273 div = (readl(reg) & mask) >> shift;
274
275 return DIV_TO_RATE(priv->ppll_hz, div);
276 }
277
rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)278 static ulong rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv *priv,
279 ulong clk_id, ulong rate)
280 {
281 struct rk3528_cru *cru = priv->cru;
282 u32 id, div, mask, shift;
283 u8 is_pciecru = 0;
284
285 switch (clk_id) {
286 case CLK_PPLL_50M_MATRIX:
287 id = 1;
288 mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK;
289 shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT;
290 is_pciecru = 1;
291 break;
292
293 case CLK_PPLL_100M_MATRIX:
294 id = 1;
295 mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK;
296 shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT;
297 is_pciecru = 1;
298 break;
299
300 case CLK_PPLL_125M_MATRIX:
301 id = 60;
302 mask = CLK_MATRIX_125M_SRC_DIV_MASK;
303 shift = CLK_MATRIX_125M_SRC_DIV_SHIFT;
304 break;
305 case CLK_GMAC1_VPU_25M:
306 id = 60;
307 mask = CLK_MATRIX_25M_SRC_DIV_MASK;
308 shift = CLK_MATRIX_25M_SRC_DIV_SHIFT;
309 break;
310 default:
311 return -ENOENT;
312 }
313
314 div = DIV_ROUND_UP(priv->ppll_hz, rate);
315 if (is_pciecru)
316 rk_clrsetreg(&cru->pcieclksel_con[id], mask, (div - 1) << shift);
317 else
318 rk_clrsetreg(&cru->clksel_con[id], mask, (div - 1) << shift);
319
320 return rk3528_ppll_matrix_get_rate(priv, clk_id);
321 }
322
rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)323 static ulong rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv *priv,
324 ulong clk_id)
325 {
326 struct rk3528_cru *cru = priv->cru;
327 u32 sel, div, mask, shift, con;
328 u32 sel_mask = 0, sel_shift;
329 u8 is_gpll_parent = 1;
330 u8 is_halfdiv = 0;
331 ulong prate;
332
333 switch (clk_id) {
334 case CLK_MATRIX_50M_SRC:
335 con = 0;
336 mask = CLK_MATRIX_50M_SRC_DIV_MASK;
337 shift = CLK_MATRIX_50M_SRC_DIV_SHIFT;
338 is_gpll_parent = 0;
339 break;
340
341 case CLK_MATRIX_100M_SRC:
342 con = 0;
343 mask = CLK_MATRIX_100M_SRC_DIV_MASK;
344 shift = CLK_MATRIX_100M_SRC_DIV_SHIFT;
345 is_gpll_parent = 0;
346 break;
347
348 case CLK_MATRIX_150M_SRC:
349 con = 1;
350 mask = CLK_MATRIX_150M_SRC_DIV_MASK;
351 shift = CLK_MATRIX_150M_SRC_DIV_SHIFT;
352 break;
353
354 case CLK_MATRIX_200M_SRC:
355 con = 1;
356 mask = CLK_MATRIX_200M_SRC_DIV_MASK;
357 shift = CLK_MATRIX_200M_SRC_DIV_SHIFT;
358 break;
359
360 case CLK_MATRIX_250M_SRC:
361 con = 1;
362 mask = CLK_MATRIX_250M_SRC_DIV_MASK;
363 shift = CLK_MATRIX_250M_SRC_DIV_SHIFT;
364 sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK;
365 sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT;
366 break;
367
368 case CLK_MATRIX_300M_SRC:
369 con = 2;
370 mask = CLK_MATRIX_300M_SRC_DIV_MASK;
371 shift = CLK_MATRIX_300M_SRC_DIV_SHIFT;
372 break;
373
374 case CLK_MATRIX_339M_SRC:
375 con = 2;
376 mask = CLK_MATRIX_339M_SRC_DIV_MASK;
377 shift = CLK_MATRIX_339M_SRC_DIV_SHIFT;
378 is_halfdiv = 1;
379 break;
380
381 case CLK_MATRIX_400M_SRC:
382 con = 2;
383 mask = CLK_MATRIX_400M_SRC_DIV_MASK;
384 shift = CLK_MATRIX_400M_SRC_DIV_SHIFT;
385 break;
386
387 case CLK_MATRIX_500M_SRC:
388 con = 3;
389 mask = CLK_MATRIX_500M_SRC_DIV_MASK;
390 shift = CLK_MATRIX_500M_SRC_DIV_SHIFT;
391 sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK;
392 sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT;
393 break;
394
395 case CLK_MATRIX_600M_SRC:
396 con = 4;
397 mask = CLK_MATRIX_600M_SRC_DIV_MASK;
398 shift = CLK_MATRIX_600M_SRC_DIV_SHIFT;
399 break;
400
401 case ACLK_BUS_VOPGL_ROOT:
402 case ACLK_BUS_VOPGL_BIU:
403 con = 43;
404 mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK;
405 shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT;
406 break;
407
408 default:
409 return -ENOENT;
410 }
411
412 if (sel_mask) {
413 sel = (readl(&cru->clksel_con[con]) & sel_mask) >> sel_shift;
414 if (sel == CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX) // TODO
415 prate = priv->gpll_hz;
416 else
417 prate = priv->cpll_hz;
418 } else {
419 if (is_gpll_parent)
420 prate = priv->gpll_hz;
421 else
422 prate = priv->cpll_hz;
423 }
424
425 div = (readl(&cru->clksel_con[con]) & mask) >> shift;
426
427 /* NOTE: '-1' to balance the DIV_TO_RATE() 'div+1' */
428 return is_halfdiv ? DIV_TO_RATE(prate * 2, (3 + 2 * div) - 1) : DIV_TO_RATE(prate, div);
429 }
430
rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)431 static ulong rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv *priv,
432 ulong clk_id, ulong rate)
433 {
434 struct rk3528_cru *cru = priv->cru;
435 u32 sel, div, mask, shift, con;
436 u32 sel_mask = 0, sel_shift;
437 u8 is_gpll_parent = 1;
438 u8 is_halfdiv = 0;
439 ulong prate = 0;
440
441 switch (clk_id) {
442 case CLK_MATRIX_50M_SRC:
443 con = 0;
444 mask = CLK_MATRIX_50M_SRC_DIV_MASK;
445 shift = CLK_MATRIX_50M_SRC_DIV_SHIFT;
446 is_gpll_parent = 0;
447 break;
448
449 case CLK_MATRIX_100M_SRC:
450 con = 0;
451 mask = CLK_MATRIX_100M_SRC_DIV_MASK;
452 shift = CLK_MATRIX_100M_SRC_DIV_SHIFT;
453 is_gpll_parent = 0;
454 break;
455
456 case CLK_MATRIX_150M_SRC:
457 con = 1;
458 mask = CLK_MATRIX_150M_SRC_DIV_MASK;
459 shift = CLK_MATRIX_150M_SRC_DIV_SHIFT;
460 break;
461
462 case CLK_MATRIX_200M_SRC:
463 con = 1;
464 mask = CLK_MATRIX_200M_SRC_DIV_MASK;
465 shift = CLK_MATRIX_200M_SRC_DIV_SHIFT;
466 break;
467
468 case CLK_MATRIX_250M_SRC:
469 con = 1;
470 mask = CLK_MATRIX_250M_SRC_DIV_MASK;
471 shift = CLK_MATRIX_250M_SRC_DIV_SHIFT;
472 sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK;
473 sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT;
474 break;
475
476 case CLK_MATRIX_300M_SRC:
477 con = 2;
478 mask = CLK_MATRIX_300M_SRC_DIV_MASK;
479 shift = CLK_MATRIX_300M_SRC_DIV_SHIFT;
480 break;
481
482 case CLK_MATRIX_339M_SRC:
483 con = 2;
484 mask = CLK_MATRIX_339M_SRC_DIV_MASK;
485 shift = CLK_MATRIX_339M_SRC_DIV_SHIFT;
486 is_halfdiv = 1;
487 break;
488
489 case CLK_MATRIX_400M_SRC:
490 con = 2;
491 mask = CLK_MATRIX_400M_SRC_DIV_MASK;
492 shift = CLK_MATRIX_400M_SRC_DIV_SHIFT;
493 break;
494
495 case CLK_MATRIX_500M_SRC:
496 con = 3;
497 mask = CLK_MATRIX_500M_SRC_DIV_MASK;
498 shift = CLK_MATRIX_500M_SRC_DIV_SHIFT;
499 sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK;
500 sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT;
501 break;
502
503 case CLK_MATRIX_600M_SRC:
504 con = 4;
505 mask = CLK_MATRIX_600M_SRC_DIV_MASK;
506 shift = CLK_MATRIX_600M_SRC_DIV_SHIFT;
507 break;
508
509 case ACLK_BUS_VOPGL_ROOT:
510 case ACLK_BUS_VOPGL_BIU:
511 con = 43;
512 mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK;
513 shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT;
514 break;
515
516 default:
517 return -ENOENT;
518 }
519
520 if (sel_mask) {
521 if (priv->gpll_hz % rate == 0) {
522 sel = CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX; // TODO
523 prate = priv->gpll_hz;
524 } else {
525 sel = CLK_MATRIX_250M_SRC_SEL_CLK_CPLL_MUX;
526 prate = priv->cpll_hz;
527 }
528 } else {
529 if (is_gpll_parent)
530 prate = priv->gpll_hz;
531 else
532 prate = priv->cpll_hz;
533 }
534
535 if (is_halfdiv)
536 /* NOTE: '+1' to balance the following rk_clrsetreg() 'div-1' */
537 div = DIV_ROUND_UP((prate * 2) - (3 * rate), 2 * rate) + 1;
538 else
539 div = DIV_ROUND_UP(prate, rate);
540
541 rk_clrsetreg(&cru->clksel_con[con], mask, (div - 1) << shift);
542 if (sel_mask)
543 rk_clrsetreg(&cru->clksel_con[con], sel_mask, sel << sel_shift);
544
545 return rk3528_cgpll_matrix_get_rate(priv, clk_id);
546 }
547
rk3528_i2c_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)548 static ulong rk3528_i2c_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
549 {
550 struct rk3528_cru *cru = priv->cru;
551 u32 id, sel, con, mask, shift;
552 u8 is_pmucru = 0;
553 ulong rate;
554
555 switch (clk_id) {
556 case CLK_I2C0:
557 id = 79;
558 mask = CLK_I2C0_SEL_MASK;
559 shift = CLK_I2C0_SEL_SHIFT;
560 break;
561
562 case CLK_I2C1:
563 id = 79;
564 mask = CLK_I2C1_SEL_MASK;
565 shift = CLK_I2C1_SEL_SHIFT;
566 break;
567
568 case CLK_I2C2:
569 id = 0;
570 mask = CLK_I2C2_SEL_MASK;
571 shift = CLK_I2C2_SEL_SHIFT;
572 is_pmucru = 1;
573 break;
574
575 case CLK_I2C3:
576 id = 63;
577 mask = CLK_I2C3_SEL_MASK;
578 shift = CLK_I2C3_SEL_SHIFT;
579 break;
580
581 case CLK_I2C4:
582 id = 85;
583 mask = CLK_I2C4_SEL_MASK;
584 shift = CLK_I2C4_SEL_SHIFT;
585 break;
586
587 case CLK_I2C5:
588 id = 63;
589 mask = CLK_I2C5_SEL_MASK;
590 shift = CLK_I2C5_SEL_SHIFT;
591 break;
592
593 case CLK_I2C6:
594 id = 64;
595 mask = CLK_I2C6_SEL_MASK;
596 shift = CLK_I2C6_SEL_SHIFT;
597 break;
598
599 case CLK_I2C7:
600 id = 86;
601 mask = CLK_I2C7_SEL_MASK;
602 shift = CLK_I2C7_SEL_SHIFT;
603 break;
604
605 default:
606 return -ENOENT;
607 }
608
609 if (is_pmucru)
610 con = readl(&cru->pmuclksel_con[id]);
611 else
612 con = readl(&cru->clksel_con[id]);
613 sel = (con & mask) >> shift;
614 if (sel == CLK_I2C3_SEL_CLK_MATRIX_200M_SRC)
615 rate = 200 * MHz;
616 else if (sel == CLK_I2C3_SEL_CLK_MATRIX_100M_SRC)
617 rate = 100 * MHz;
618 else if (sel == CLK_I2C3_SEL_CLK_MATRIX_50M_SRC)
619 rate = 50 * MHz;
620 else
621 rate = OSC_HZ;
622
623 return rate;
624 }
625
rk3528_i2c_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)626 static ulong rk3528_i2c_set_clk(struct rk3528_clk_priv *priv, ulong clk_id,
627 ulong rate)
628 {
629 struct rk3528_cru *cru = priv->cru;
630 u32 id, sel, mask, shift;
631 u8 is_pmucru = 0;
632
633 if (rate == 200 * MHz)
634 sel = CLK_I2C3_SEL_CLK_MATRIX_200M_SRC;
635 else if (rate == 100 * MHz)
636 sel = CLK_I2C3_SEL_CLK_MATRIX_100M_SRC;
637 else if (rate == 50 * MHz)
638 sel = CLK_I2C3_SEL_CLK_MATRIX_50M_SRC;
639 else
640 sel = CLK_I2C3_SEL_XIN_OSC0_FUNC;
641
642 switch (clk_id) {
643 case CLK_I2C0:
644 id = 79;
645 mask = CLK_I2C0_SEL_MASK;
646 shift = CLK_I2C0_SEL_SHIFT;
647 break;
648
649 case CLK_I2C1:
650 id = 79;
651 mask = CLK_I2C1_SEL_MASK;
652 shift = CLK_I2C1_SEL_SHIFT;
653 break;
654
655 case CLK_I2C2:
656 id = 0;
657 mask = CLK_I2C2_SEL_MASK;
658 shift = CLK_I2C2_SEL_SHIFT;
659 is_pmucru = 1;
660 break;
661
662 case CLK_I2C3:
663 id = 63;
664 mask = CLK_I2C3_SEL_MASK;
665 shift = CLK_I2C3_SEL_SHIFT;
666 break;
667
668 case CLK_I2C4:
669 id = 85;
670 mask = CLK_I2C4_SEL_MASK;
671 shift = CLK_I2C4_SEL_SHIFT;
672 break;
673
674 case CLK_I2C5:
675 id = 63;
676 mask = CLK_I2C5_SEL_MASK;
677 shift = CLK_I2C5_SEL_SHIFT;
678
679 case CLK_I2C6:
680 id = 64;
681 mask = CLK_I2C6_SEL_MASK;
682 shift = CLK_I2C6_SEL_SHIFT;
683 break;
684
685 case CLK_I2C7:
686 id = 86;
687 mask = CLK_I2C7_SEL_MASK;
688 shift = CLK_I2C7_SEL_SHIFT;
689 break;
690
691 default:
692 return -ENOENT;
693 }
694
695 if (is_pmucru)
696 rk_clrsetreg(&cru->pmuclksel_con[id], mask, sel << shift);
697 else
698 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
699
700 return rk3528_i2c_get_clk(priv, clk_id);
701 }
702
rk3528_spi_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)703 static ulong rk3528_spi_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
704 {
705 struct rk3528_cru *cru = priv->cru;
706 u32 id, sel, con, mask, shift;
707 ulong rate;
708
709 switch (clk_id) {
710 case CLK_SPI0:
711 id = 79;
712 mask = CLK_SPI0_SEL_MASK;
713 shift = CLK_SPI0_SEL_SHIFT;
714 break;
715
716 case CLK_SPI1:
717 id = 63;
718 mask = CLK_SPI1_SEL_MASK;
719 shift = CLK_SPI1_SEL_SHIFT;
720 break;
721 default:
722 return -ENOENT;
723 }
724
725 con = readl(&cru->clksel_con[id]);
726 sel = (con & mask) >> shift;
727 if (sel == CLK_SPI1_SEL_CLK_MATRIX_200M_SRC)
728 rate = 200 * MHz;
729 else if (sel == CLK_SPI1_SEL_CLK_MATRIX_100M_SRC)
730 rate = 100 * MHz;
731 else if (sel == CLK_SPI1_SEL_CLK_MATRIX_50M_SRC)
732 rate = 50 * MHz;
733 else
734 rate = OSC_HZ;
735
736 return rate;
737 }
738
rk3528_spi_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)739 static ulong rk3528_spi_set_clk(struct rk3528_clk_priv *priv,
740 ulong clk_id, ulong rate)
741 {
742 struct rk3528_cru *cru = priv->cru;
743 u32 id, sel, mask, shift;
744
745 if (rate == 200 * MHz)
746 sel = CLK_SPI1_SEL_CLK_MATRIX_200M_SRC;
747 else if (rate == 100 * MHz)
748 sel = CLK_SPI1_SEL_CLK_MATRIX_100M_SRC;
749 else if (rate == 50 * MHz)
750 sel = CLK_SPI1_SEL_CLK_MATRIX_50M_SRC;
751 else
752 sel = CLK_SPI1_SEL_XIN_OSC0_FUNC;
753
754 switch (clk_id) {
755 case CLK_SPI0:
756 id = 79;
757 mask = CLK_SPI0_SEL_MASK;
758 shift = CLK_SPI0_SEL_SHIFT;
759 break;
760
761 case CLK_SPI1:
762 id = 63;
763 mask = CLK_SPI1_SEL_MASK;
764 shift = CLK_SPI1_SEL_SHIFT;
765 break;
766 default:
767 return -ENOENT;
768 }
769
770 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
771
772 return rk3528_spi_get_clk(priv, clk_id);
773 }
774
rk3528_pwm_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)775 static ulong rk3528_pwm_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
776 {
777 struct rk3528_cru *cru = priv->cru;
778 u32 id, sel, con, mask, shift;
779 ulong rate;
780
781 switch (clk_id) {
782 case CLK_PWM0:
783 id = 44;
784 mask = CLK_PWM0_SEL_MASK;
785 shift = CLK_PWM0_SEL_SHIFT;
786 break;
787
788 case CLK_PWM1:
789 id = 44;
790 mask = CLK_PWM1_SEL_MASK;
791 shift = CLK_PWM1_SEL_SHIFT;
792 break;
793
794 default:
795 return -ENOENT;
796 }
797
798 con = readl(&cru->clksel_con[id]);
799 sel = (con & mask) >> shift;
800 if (sel == CLK_PWM0_SEL_CLK_MATRIX_100M_SRC)
801 rate = 100 * MHz;
802 if (sel == CLK_PWM0_SEL_CLK_MATRIX_50M_SRC)
803 rate = 50 * MHz;
804 else
805 rate = OSC_HZ;
806
807 return rate;
808 }
809
rk3528_pwm_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)810 static ulong rk3528_pwm_set_clk(struct rk3528_clk_priv *priv,
811 ulong clk_id, ulong rate)
812 {
813 struct rk3528_cru *cru = priv->cru;
814 u32 id, sel, mask, shift;
815
816 if (rate == 100 * MHz)
817 sel = CLK_PWM0_SEL_CLK_MATRIX_100M_SRC;
818 else if (rate == 50 * MHz)
819 sel = CLK_PWM0_SEL_CLK_MATRIX_50M_SRC;
820 else
821 sel = CLK_PWM0_SEL_XIN_OSC0_FUNC;
822
823 switch (clk_id) {
824 case CLK_PWM0:
825 id = 44;
826 mask = CLK_PWM0_SEL_MASK;
827 shift = CLK_PWM0_SEL_SHIFT;
828 break;
829
830 case CLK_PWM1:
831 id = 44;
832 mask = CLK_PWM1_SEL_MASK;
833 shift = CLK_PWM1_SEL_SHIFT;
834 break;
835
836 default:
837 return -ENOENT;
838 }
839
840 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
841
842 return rk3528_pwm_get_clk(priv, clk_id);
843 }
844
rk3528_adc_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)845 static ulong rk3528_adc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
846 {
847 struct rk3528_cru *cru = priv->cru;
848 u32 div, con;
849
850 con = readl(&cru->clksel_con[74]);
851 switch (clk_id) {
852 case CLK_SARADC:
853 div = (con & CLK_SARADC_DIV_MASK) >>
854 CLK_SARADC_DIV_SHIFT;
855 break;
856
857 case CLK_TSADC_TSEN:
858 div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
859 CLK_TSADC_TSEN_DIV_SHIFT;
860 break;
861
862 case CLK_TSADC:
863 div = (con & CLK_TSADC_DIV_MASK) >>
864 CLK_TSADC_DIV_SHIFT;
865 break;
866
867 default:
868 return -ENOENT;
869 }
870
871 return DIV_TO_RATE(OSC_HZ, div);
872 }
873
rk3528_adc_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)874 static ulong rk3528_adc_set_clk(struct rk3528_clk_priv *priv,
875 ulong clk_id, ulong rate)
876 {
877 struct rk3528_cru *cru = priv->cru;
878 u32 div, mask, shift;
879
880 switch (clk_id) {
881 case CLK_SARADC:
882 mask = CLK_SARADC_DIV_MASK;
883 shift = CLK_SARADC_DIV_SHIFT;
884 break;
885
886 case CLK_TSADC_TSEN:
887 mask = CLK_TSADC_TSEN_DIV_MASK;
888 shift = CLK_TSADC_TSEN_DIV_SHIFT;
889 break;
890
891 case CLK_TSADC:
892 mask = CLK_TSADC_DIV_MASK;
893 shift = CLK_TSADC_DIV_SHIFT;
894 break;
895
896 default:
897 return -ENOENT;
898 }
899
900 div = DIV_ROUND_UP(OSC_HZ, rate);
901 rk_clrsetreg(&cru->clksel_con[74], mask, (div - 1) << shift);
902
903 return rk3528_adc_get_clk(priv, clk_id);
904 }
905
rk3528_sdmmc_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)906 static ulong rk3528_sdmmc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
907 {
908 struct rk3528_cru *cru = priv->cru;
909 u32 div, sel, con;
910 ulong prate;
911
912 con = readl(&cru->clksel_con[85]);
913 div = (con & CCLK_SRC_SDMMC0_DIV_MASK) >>
914 CCLK_SRC_SDMMC0_DIV_SHIFT;
915 sel = (con & CCLK_SRC_SDMMC0_SEL_MASK) >>
916 CCLK_SRC_SDMMC0_SEL_SHIFT;
917
918 if (sel == CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX)
919 prate = priv->gpll_hz;
920 else if (sel == CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX)
921 prate = priv->cpll_hz;
922 else
923 prate = OSC_HZ;
924
925 return DIV_TO_RATE(prate, div);
926 }
927
rk3528_sdmmc_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)928 static ulong rk3528_sdmmc_set_clk(struct rk3528_clk_priv *priv,
929 ulong clk_id, ulong rate)
930 {
931 struct rk3528_cru *cru = priv->cru;
932 u32 div, sel;
933
934 if (OSC_HZ % rate == 0) {
935 div = DIV_ROUND_UP(OSC_HZ, rate);
936 sel = CCLK_SRC_SDMMC0_SEL_XIN_OSC0_FUNC;
937 } else if ((priv->cpll_hz % rate) == 0) {
938 div = DIV_ROUND_UP(priv->cpll_hz, rate);
939 sel = CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX;
940 } else {
941 div = DIV_ROUND_UP(priv->gpll_hz, rate);
942 sel = CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX;
943 }
944
945 assert(div - 1 <= 31);
946 rk_clrsetreg(&cru->clksel_con[85],
947 CCLK_SRC_SDMMC0_SEL_MASK |
948 CCLK_SRC_SDMMC0_DIV_MASK,
949 sel << CCLK_SRC_SDMMC0_SEL_SHIFT |
950 (div - 1) << CCLK_SRC_SDMMC0_DIV_SHIFT);
951
952 return rk3528_sdmmc_get_clk(priv, clk_id);
953 }
954
rk3528_sfc_get_clk(struct rk3528_clk_priv * priv)955 static ulong rk3528_sfc_get_clk(struct rk3528_clk_priv *priv)
956 {
957 struct rk3528_cru *cru = priv->cru;
958 u32 div, sel, con, parent;
959
960 con = readl(&cru->clksel_con[61]);
961 div = (con & SCLK_SFC_DIV_MASK) >>
962 SCLK_SFC_DIV_SHIFT;
963 sel = (con & SCLK_SFC_SEL_MASK) >>
964 SCLK_SFC_SEL_SHIFT;
965 if (sel == SCLK_SFC_SEL_CLK_GPLL_MUX)
966 parent = priv->gpll_hz;
967 else if (sel == SCLK_SFC_SEL_CLK_CPLL_MUX)
968 parent = priv->cpll_hz;
969 else
970 parent = OSC_HZ;
971
972 return DIV_TO_RATE(parent, div);
973 }
974
rk3528_sfc_set_clk(struct rk3528_clk_priv * priv,ulong rate)975 static ulong rk3528_sfc_set_clk(struct rk3528_clk_priv *priv, ulong rate)
976 {
977 struct rk3528_cru *cru = priv->cru;
978 int div, sel;
979
980 if (OSC_HZ % rate == 0) {
981 div = DIV_ROUND_UP(OSC_HZ, rate);
982 sel = SCLK_SFC_SEL_XIN_OSC0_FUNC;
983 } else if ((priv->cpll_hz % rate) == 0) {
984 div = DIV_ROUND_UP(priv->cpll_hz, rate);
985 sel = SCLK_SFC_SEL_CLK_CPLL_MUX;
986 } else {
987 div = DIV_ROUND_UP(priv->gpll_hz, rate);
988 sel = SCLK_SFC_SEL_CLK_GPLL_MUX;
989 }
990
991 assert(div - 1 <= 63);
992 rk_clrsetreg(&cru->clksel_con[61],
993 SCLK_SFC_SEL_MASK |
994 SCLK_SFC_DIV_MASK,
995 sel << SCLK_SFC_SEL_SHIFT |
996 (div - 1) << SCLK_SFC_DIV_SHIFT);
997
998 return rk3528_sfc_get_clk(priv);
999 }
1000
rk3528_emmc_get_clk(struct rk3528_clk_priv * priv)1001 static ulong rk3528_emmc_get_clk(struct rk3528_clk_priv *priv)
1002 {
1003 struct rk3528_cru *cru = priv->cru;
1004 u32 div, sel, con, parent;
1005
1006 con = readl(&cru->clksel_con[62]);
1007 div = (con & CCLK_SRC_EMMC_DIV_MASK) >>
1008 CCLK_SRC_EMMC_DIV_SHIFT;
1009 sel = (con & CCLK_SRC_EMMC_SEL_MASK) >>
1010 CCLK_SRC_EMMC_SEL_SHIFT;
1011
1012 if (sel == CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX)
1013 parent = priv->gpll_hz;
1014 else if (sel == CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX)
1015 parent = priv->cpll_hz;
1016 else
1017 parent = OSC_HZ;
1018
1019 return DIV_TO_RATE(parent, div);
1020 }
1021
rk3528_emmc_set_clk(struct rk3528_clk_priv * priv,ulong rate)1022 static ulong rk3528_emmc_set_clk(struct rk3528_clk_priv *priv, ulong rate)
1023 {
1024 struct rk3528_cru *cru = priv->cru;
1025 u32 div, sel;
1026
1027 if (OSC_HZ % rate == 0) {
1028 div = DIV_ROUND_UP(OSC_HZ, rate);
1029 sel = CCLK_SRC_EMMC_SEL_XIN_OSC0_FUNC;
1030 } else if ((priv->cpll_hz % rate) == 0) {
1031 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1032 sel = CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX;
1033 } else {
1034 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1035 sel = CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX;
1036 }
1037
1038 assert(div - 1 <= 31);
1039 rk_clrsetreg(&cru->clksel_con[62],
1040 CCLK_SRC_EMMC_SEL_MASK |
1041 CCLK_SRC_EMMC_DIV_MASK,
1042 sel << CCLK_SRC_EMMC_SEL_SHIFT |
1043 (div - 1) << CCLK_SRC_EMMC_DIV_SHIFT);
1044
1045 return rk3528_emmc_get_clk(priv);
1046 }
1047
rk3528_dclk_vop_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)1048 static ulong rk3528_dclk_vop_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
1049 {
1050 struct rk3528_cru *cru = priv->cru;
1051 u32 div_mask, div_shift;
1052 u32 sel_mask, sel_shift;
1053 u32 id, con, sel, div;
1054 ulong prate;
1055
1056 switch (clk_id) {
1057 case DCLK_VOP0:
1058 id = 32;
1059 sel_mask = DCLK_VOP_SRC0_SEL_MASK;
1060 sel_shift = DCLK_VOP_SRC0_SEL_SHIFT;
1061 /* FIXME if need src: clk_hdmiphy_pixel_io */
1062 div_mask = DCLK_VOP_SRC0_DIV_MASK;
1063 div_shift = DCLK_VOP_SRC0_DIV_SHIFT;
1064 break;
1065
1066 case DCLK_VOP1:
1067 id = 33;
1068 sel_mask = DCLK_VOP_SRC1_SEL_MASK;
1069 sel_shift = DCLK_VOP_SRC1_SEL_SHIFT;
1070 div_mask = DCLK_VOP_SRC1_DIV_MASK;
1071 div_shift = DCLK_VOP_SRC1_DIV_SHIFT;
1072 break;
1073
1074 default:
1075 return -ENOENT;
1076 }
1077
1078 con = readl(&cru->clksel_con[id]);
1079 div = (con & div_mask) >> div_shift;
1080 sel = (con & sel_mask) >> sel_shift;
1081 if (sel == DCLK_VOP_SRC_SEL_CLK_GPLL_MUX)
1082 prate = priv->gpll_hz;
1083 else
1084 prate = priv->cpll_hz;
1085
1086 return DIV_TO_RATE(prate, div);
1087 }
1088
rk3528_dclk_vop_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)1089 static ulong rk3528_dclk_vop_set_clk(struct rk3528_clk_priv *priv,
1090 ulong clk_id, ulong rate)
1091 {
1092 struct rk3528_cru *cru = priv->cru;
1093 u32 div_mask, div_shift;
1094 u32 sel_mask, sel_shift;
1095 u32 id, sel, div;
1096 ulong prate;
1097
1098 switch (clk_id) {
1099 case DCLK_VOP0:
1100 id = 32;
1101 sel_mask = DCLK_VOP_SRC0_SEL_MASK;
1102 sel_shift = DCLK_VOP_SRC0_SEL_SHIFT;
1103 /* FIXME if need src: clk_hdmiphy_pixel_io */
1104 div_mask = DCLK_VOP_SRC0_DIV_MASK;
1105 div_shift = DCLK_VOP_SRC0_DIV_SHIFT;
1106 break;
1107
1108 case DCLK_VOP1:
1109 id = 33;
1110 sel_mask = DCLK_VOP_SRC1_SEL_MASK;
1111 sel_shift = DCLK_VOP_SRC1_SEL_SHIFT;
1112 div_mask = DCLK_VOP_SRC1_DIV_MASK;
1113 div_shift = DCLK_VOP_SRC1_DIV_SHIFT;
1114 break;
1115
1116 default:
1117 return -ENOENT;
1118 }
1119
1120 if ((priv->gpll_hz % rate) == 0) {
1121 prate = priv->gpll_hz;
1122 sel = (DCLK_VOP_SRC_SEL_CLK_GPLL_MUX << sel_shift) & sel_mask;
1123 } else {
1124 prate = priv->cpll_hz;
1125 sel = (DCLK_VOP_SRC_SEL_CLK_CPLL_MUX << sel_shift) & sel_mask;
1126 }
1127
1128 div = ((DIV_ROUND_UP(prate, rate) - 1) << div_shift) & div_mask;
1129 rk_clrsetreg(&cru->clksel_con[id], sel, div);
1130
1131 return rk3528_dclk_vop_get_clk(priv, clk_id);
1132 }
1133
rk3528_uart_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)1134 static ulong rk3528_uart_get_rate(struct rk3528_clk_priv *priv, ulong clk_id)
1135 {
1136 struct rk3528_cru *cru = priv->cru;
1137 u32 sel_shift, sel_mask, div_shift, div_mask;
1138 u32 sel, id, con, frac_div, div;
1139 ulong m, n, rate;
1140
1141 switch (clk_id) {
1142 case SCLK_UART0:
1143 id = 6;
1144 sel_shift = SCLK_UART0_SRC_SEL_SHIFT;
1145 sel_mask = SCLK_UART0_SRC_SEL_MASK;
1146 div_shift = CLK_UART0_SRC_DIV_SHIFT;
1147 div_mask = CLK_UART0_SRC_DIV_MASK;
1148 break;
1149
1150 case SCLK_UART1:
1151 id = 8;
1152 sel_shift = SCLK_UART1_SRC_SEL_SHIFT;
1153 sel_mask = SCLK_UART1_SRC_SEL_MASK;
1154 div_shift = CLK_UART1_SRC_DIV_SHIFT;
1155 div_mask = CLK_UART1_SRC_DIV_MASK;
1156 break;
1157
1158 case SCLK_UART2:
1159 id = 10;
1160 sel_shift = SCLK_UART2_SRC_SEL_SHIFT;
1161 sel_mask = SCLK_UART2_SRC_SEL_MASK;
1162 div_shift = CLK_UART2_SRC_DIV_SHIFT;
1163 div_mask = CLK_UART2_SRC_DIV_MASK;
1164 break;
1165
1166 case SCLK_UART3:
1167 id = 12;
1168 sel_shift = SCLK_UART3_SRC_SEL_SHIFT;
1169 sel_mask = SCLK_UART3_SRC_SEL_MASK;
1170 div_shift = CLK_UART3_SRC_DIV_SHIFT;
1171 div_mask = CLK_UART3_SRC_DIV_MASK;
1172 break;
1173
1174 case SCLK_UART4:
1175 id = 14;
1176 sel_shift = SCLK_UART4_SRC_SEL_SHIFT;
1177 sel_mask = SCLK_UART4_SRC_SEL_MASK;
1178 div_shift = CLK_UART4_SRC_DIV_SHIFT;
1179 div_mask = CLK_UART4_SRC_DIV_MASK;
1180 break;
1181
1182 case SCLK_UART5:
1183 id = 16;
1184 sel_shift = SCLK_UART5_SRC_SEL_SHIFT;
1185 sel_mask = SCLK_UART5_SRC_SEL_MASK;
1186 div_shift = CLK_UART5_SRC_DIV_SHIFT;
1187 div_mask = CLK_UART5_SRC_DIV_MASK;
1188 break;
1189
1190 case SCLK_UART6:
1191 id = 18;
1192 sel_shift = SCLK_UART6_SRC_SEL_SHIFT;
1193 sel_mask = SCLK_UART6_SRC_SEL_MASK;
1194 div_shift = CLK_UART6_SRC_DIV_SHIFT;
1195 div_mask = CLK_UART6_SRC_DIV_MASK;
1196 break;
1197
1198 case SCLK_UART7:
1199 id = 20;
1200 sel_shift = SCLK_UART7_SRC_SEL_SHIFT;
1201 sel_mask = SCLK_UART7_SRC_SEL_MASK;
1202 div_shift = CLK_UART7_SRC_DIV_SHIFT;
1203 div_mask = CLK_UART7_SRC_DIV_MASK;
1204 break;
1205
1206 default:
1207 return -ENOENT;
1208 }
1209
1210 con = readl(&cru->clksel_con[id - 2]);
1211 div = (con & div_mask) >> div_shift;
1212
1213 con = readl(&cru->clksel_con[id]);
1214 sel = (con & sel_mask) >> sel_shift;
1215
1216 if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_SRC) {
1217 rate = DIV_TO_RATE(priv->gpll_hz, div);
1218 } else if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_FRAC) {
1219 frac_div = readl(&cru->clksel_con[id - 1]);
1220 n = (frac_div & 0xffff0000) >> 16;
1221 m = frac_div & 0x0000ffff;
1222 rate = DIV_TO_RATE(priv->gpll_hz, div) * n / m;
1223 } else {
1224 rate = OSC_HZ;
1225 }
1226
1227 return rate;
1228 }
1229
rk3528_uart_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)1230 static ulong rk3528_uart_set_rate(struct rk3528_clk_priv *priv,
1231 ulong clk_id, ulong rate)
1232 {
1233 struct rk3528_cru *cru = priv->cru;
1234 u32 sel_shift, sel_mask, div_shift, div_mask;
1235 u32 sel, id, div;
1236 ulong m = 0, n = 0, val;
1237
1238 if (rate == OSC_HZ) {
1239 sel = SCLK_UART0_SRC_SEL_XIN_OSC0_FUNC;
1240 div = DIV_ROUND_UP(OSC_HZ, rate);
1241 } else if (priv->gpll_hz % rate == 0) {
1242 sel = SCLK_UART0_SRC_SEL_CLK_UART0_SRC;
1243 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1244 } else {
1245 sel = SCLK_UART0_SRC_SEL_CLK_UART0_FRAC;
1246 div = 2;
1247 rational_best_approximation(rate, priv->gpll_hz / div,
1248 GENMASK(16 - 1, 0),
1249 GENMASK(16 - 1, 0),
1250 &n, &m);
1251 }
1252
1253 switch (clk_id) {
1254 case SCLK_UART0:
1255 id = 6;
1256 sel_shift = SCLK_UART0_SRC_SEL_SHIFT;
1257 sel_mask = SCLK_UART0_SRC_SEL_MASK;
1258 div_shift = CLK_UART0_SRC_DIV_SHIFT;
1259 div_mask = CLK_UART0_SRC_DIV_MASK;
1260 break;
1261
1262 case SCLK_UART1:
1263 id = 8;
1264 sel_shift = SCLK_UART1_SRC_SEL_SHIFT;
1265 sel_mask = SCLK_UART1_SRC_SEL_MASK;
1266 div_shift = CLK_UART1_SRC_DIV_SHIFT;
1267 div_mask = CLK_UART1_SRC_DIV_MASK;
1268 break;
1269
1270 case SCLK_UART2:
1271 id = 10;
1272 sel_shift = SCLK_UART2_SRC_SEL_SHIFT;
1273 sel_mask = SCLK_UART2_SRC_SEL_MASK;
1274 div_shift = CLK_UART2_SRC_DIV_SHIFT;
1275 div_mask = CLK_UART2_SRC_DIV_MASK;
1276 break;
1277
1278 case SCLK_UART3:
1279 id = 12;
1280 sel_shift = SCLK_UART3_SRC_SEL_SHIFT;
1281 sel_mask = SCLK_UART3_SRC_SEL_MASK;
1282 div_shift = CLK_UART3_SRC_DIV_SHIFT;
1283 div_mask = CLK_UART3_SRC_DIV_MASK;
1284 break;
1285
1286 case SCLK_UART4:
1287 id = 14;
1288 sel_shift = SCLK_UART4_SRC_SEL_SHIFT;
1289 sel_mask = SCLK_UART4_SRC_SEL_MASK;
1290 div_shift = CLK_UART4_SRC_DIV_SHIFT;
1291 div_mask = CLK_UART4_SRC_DIV_MASK;
1292 break;
1293
1294 case SCLK_UART5:
1295 id = 16;
1296 sel_shift = SCLK_UART5_SRC_SEL_SHIFT;
1297 sel_mask = SCLK_UART5_SRC_SEL_MASK;
1298 div_shift = CLK_UART5_SRC_DIV_SHIFT;
1299 div_mask = CLK_UART5_SRC_DIV_MASK;
1300 break;
1301
1302 case SCLK_UART6:
1303 id = 18;
1304 sel_shift = SCLK_UART6_SRC_SEL_SHIFT;
1305 sel_mask = SCLK_UART6_SRC_SEL_MASK;
1306 div_shift = CLK_UART6_SRC_DIV_SHIFT;
1307 div_mask = CLK_UART6_SRC_DIV_MASK;
1308 break;
1309
1310 case SCLK_UART7:
1311 id = 20;
1312 sel_shift = SCLK_UART7_SRC_SEL_SHIFT;
1313 sel_mask = SCLK_UART7_SRC_SEL_MASK;
1314 div_shift = CLK_UART7_SRC_DIV_SHIFT;
1315 div_mask = CLK_UART7_SRC_DIV_MASK;
1316 break;
1317
1318 default:
1319 return -ENOENT;
1320 }
1321
1322 rk_clrsetreg(&cru->clksel_con[id - 2], div_mask, (div - 1) << div_shift);
1323 rk_clrsetreg(&cru->clksel_con[id], sel_mask, sel << sel_shift);
1324 if (m && n) {
1325 val = n << 16 | m;
1326 writel(val, &cru->clksel_con[id - 1]);
1327 }
1328
1329 return rk3528_uart_get_rate(priv, clk_id);
1330 }
1331
rk3528_clk_get_rate(struct clk * clk)1332 static ulong rk3528_clk_get_rate(struct clk *clk)
1333 {
1334 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1335 ulong rate = 0;
1336
1337 if (!priv->gpll_hz || !priv->cpll_hz) {
1338 printf("%s: gpll=%lu, cpll=%ld\n",
1339 __func__, priv->gpll_hz, priv->cpll_hz);
1340 return -ENOENT;
1341 }
1342
1343 switch (clk->id) {
1344 case PLL_APLL:
1345 case ARMCLK:
1346 rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru,
1347 APLL);
1348 break;
1349 case PLL_CPLL:
1350 rate = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], priv->cru,
1351 CPLL);
1352 break;
1353 case PLL_GPLL:
1354 rate = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], priv->cru,
1355 GPLL);
1356 break;
1357
1358 case PLL_PPLL:
1359 rate = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], priv->cru,
1360 PPLL);
1361 break;
1362 case PLL_DPLL:
1363 rate = rockchip_pll_get_rate(&rk3528_pll_clks[DPLL], priv->cru,
1364 DPLL);
1365 break;
1366
1367 case TCLK_WDT_NS:
1368 rate = OSC_HZ;
1369 break;
1370 case CLK_I2C0:
1371 case CLK_I2C1:
1372 case CLK_I2C2:
1373 case CLK_I2C3:
1374 case CLK_I2C4:
1375 case CLK_I2C5:
1376 case CLK_I2C6:
1377 case CLK_I2C7:
1378 rate = rk3528_i2c_get_clk(priv, clk->id);
1379 break;
1380 case CLK_SPI0:
1381 case CLK_SPI1:
1382 rate = rk3528_spi_get_clk(priv, clk->id);
1383 break;
1384 case CLK_PWM0:
1385 case CLK_PWM1:
1386 rate = rk3528_pwm_get_clk(priv, clk->id);
1387 break;
1388 case CLK_SARADC:
1389 case CLK_TSADC:
1390 case CLK_TSADC_TSEN:
1391 rate = rk3528_adc_get_clk(priv, clk->id);
1392 break;
1393 case CCLK_SRC_EMMC:
1394 rate = rk3528_emmc_get_clk(priv);
1395 break;
1396 case HCLK_SDMMC0:
1397 case CCLK_SRC_SDMMC0:
1398 rate = rk3528_sdmmc_get_clk(priv, clk->id);
1399 break;
1400 case SCLK_SFC:
1401 rate = rk3528_sfc_get_clk(priv);
1402 break;
1403 case DCLK_VOP0:
1404 case DCLK_VOP1:
1405 rate = rk3528_dclk_vop_get_clk(priv, clk->id);
1406 break;
1407 case DCLK_CVBS:
1408 rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1) / 4;
1409 break;
1410 case DCLK_4X_CVBS:
1411 rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1);
1412 break;
1413 case SCLK_UART0:
1414 case SCLK_UART1:
1415 case SCLK_UART2:
1416 case SCLK_UART3:
1417 case SCLK_UART4:
1418 case SCLK_UART5:
1419 case SCLK_UART6:
1420 case SCLK_UART7:
1421 rate = rk3528_uart_get_rate(priv, clk->id);
1422 break;
1423 case CLK_MATRIX_50M_SRC:
1424 case CLK_MATRIX_100M_SRC:
1425 case CLK_MATRIX_150M_SRC:
1426 case CLK_MATRIX_200M_SRC:
1427 case CLK_MATRIX_250M_SRC:
1428 case CLK_MATRIX_300M_SRC:
1429 case CLK_MATRIX_339M_SRC:
1430 case CLK_MATRIX_400M_SRC:
1431 case CLK_MATRIX_500M_SRC:
1432 case CLK_MATRIX_600M_SRC:
1433 case ACLK_BUS_VOPGL_BIU:
1434 rate = rk3528_cgpll_matrix_get_rate(priv, clk->id);
1435 break;
1436 case CLK_PPLL_50M_MATRIX:
1437 case CLK_PPLL_100M_MATRIX:
1438 case CLK_PPLL_125M_MATRIX:
1439 case CLK_GMAC1_VPU_25M:
1440 case CLK_GMAC1_RMII_VPU:
1441 case CLK_GMAC1_SRC_VPU:
1442 rate = rk3528_ppll_matrix_get_rate(priv, clk->id);
1443 break;
1444 default:
1445 return -ENOENT;
1446 }
1447
1448 return rate;
1449 };
1450
rk3528_clk_set_rate(struct clk * clk,ulong rate)1451 static ulong rk3528_clk_set_rate(struct clk *clk, ulong rate)
1452 {
1453 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1454 ulong ret = 0;
1455
1456 if (!priv->gpll_hz) {
1457 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1458 return -ENOENT;
1459 }
1460
1461 switch (clk->id) {
1462 case PLL_APLL:
1463 case ARMCLK:
1464 if (priv->armclk_hz)
1465 rk3528_armclk_set_clk(priv, rate);
1466 priv->armclk_hz = rate;
1467 break;
1468 case PLL_CPLL:
1469 ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru,
1470 CPLL, rate);
1471 priv->cpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL],
1472 priv->cru, CPLL);
1473 break;
1474 case PLL_GPLL:
1475 ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru,
1476 GPLL, rate);
1477 priv->gpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL],
1478 priv->cru, GPLL);
1479 break;
1480 case PLL_PPLL:
1481 ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru,
1482 PPLL, rate);
1483 priv->ppll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL],
1484 priv->cru, PPLL);
1485 break;
1486 case TCLK_WDT_NS:
1487 return (rate == OSC_HZ) ? 0 : -EINVAL;
1488 case CLK_I2C0:
1489 case CLK_I2C1:
1490 case CLK_I2C2:
1491 case CLK_I2C3:
1492 case CLK_I2C4:
1493 case CLK_I2C5:
1494 case CLK_I2C6:
1495 case CLK_I2C7:
1496 ret = rk3528_i2c_set_clk(priv, clk->id, rate);
1497 break;
1498 case CLK_SPI0:
1499 case CLK_SPI1:
1500 ret = rk3528_spi_set_clk(priv, clk->id, rate);
1501 break;
1502 case CLK_PWM0:
1503 case CLK_PWM1:
1504 ret = rk3528_pwm_set_clk(priv, clk->id, rate);
1505 break;
1506 case CLK_SARADC:
1507 case CLK_TSADC:
1508 case CLK_TSADC_TSEN:
1509 ret = rk3528_adc_set_clk(priv, clk->id, rate);
1510 break;
1511 case HCLK_SDMMC0:
1512 case CCLK_SRC_SDMMC0:
1513 ret = rk3528_sdmmc_set_clk(priv, clk->id, rate);
1514 break;
1515 case SCLK_SFC:
1516 ret = rk3528_sfc_set_clk(priv, rate);
1517 break;
1518 case CCLK_SRC_EMMC:
1519 ret = rk3528_emmc_set_clk(priv, rate);
1520 break;
1521 case DCLK_VOP0:
1522 case DCLK_VOP1:
1523 ret = rk3528_dclk_vop_set_clk(priv, clk->id, rate);
1524 break;
1525 case SCLK_UART0:
1526 case SCLK_UART1:
1527 case SCLK_UART2:
1528 case SCLK_UART3:
1529 case SCLK_UART4:
1530 case SCLK_UART5:
1531 case SCLK_UART6:
1532 case SCLK_UART7:
1533 ret = rk3528_uart_set_rate(priv, clk->id, rate);
1534 break;
1535 case CLK_MATRIX_50M_SRC:
1536 case CLK_MATRIX_100M_SRC:
1537 case CLK_MATRIX_150M_SRC:
1538 case CLK_MATRIX_200M_SRC:
1539 case CLK_MATRIX_250M_SRC:
1540 case CLK_MATRIX_300M_SRC:
1541 case CLK_MATRIX_339M_SRC:
1542 case CLK_MATRIX_400M_SRC:
1543 case CLK_MATRIX_500M_SRC:
1544 case CLK_MATRIX_600M_SRC:
1545 case ACLK_BUS_VOPGL_BIU:
1546 ret = rk3528_cgpll_matrix_set_rate(priv, clk->id, rate);
1547 break;
1548 case CLK_PPLL_50M_MATRIX:
1549 case CLK_PPLL_100M_MATRIX:
1550 case CLK_PPLL_125M_MATRIX:
1551 case CLK_GMAC1_VPU_25M:
1552 ret = rk3528_ppll_matrix_set_rate(priv, clk->id, rate);
1553 break;
1554 case CLK_GMAC1_RMII_VPU:
1555 case CLK_GMAC1_SRC_VPU:
1556 /* dummy set */
1557 ret = rk3528_ppll_matrix_get_rate(priv, clk->id);
1558 break;
1559 default:
1560 return -ENOENT;
1561 }
1562
1563 return ret;
1564 };
1565
1566 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
rk3528_clk_set_parent(struct clk * clk,struct clk * parent)1567 static int rk3528_clk_set_parent(struct clk *clk, struct clk *parent)
1568 {
1569 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1570 const char *clock_dev_name = parent->dev->name;
1571
1572 switch (clk->id) {
1573 case DCLK_VOP0:
1574 if (!strcmp(clock_dev_name, "inno_hdmi_pll_clk"))
1575 /* clk_hdmiphy_pixel_io */
1576 rk_clrsetreg(&priv->cru->clksel_con[84], 0x1, 1);
1577 else
1578 rk_clrsetreg(&priv->cru->clksel_con[84], 0x1, 0);
1579 break;
1580
1581 default:
1582 return -ENOENT;
1583 }
1584
1585 return 0;
1586 }
1587 #endif
1588
1589 static struct clk_ops rk3528_clk_ops = {
1590 .get_rate = rk3528_clk_get_rate,
1591 .set_rate = rk3528_clk_set_rate,
1592 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1593 .set_parent = rk3528_clk_set_parent,
1594 #endif
1595 };
1596
rk3528_grfclk_get_rate(struct clk * clk)1597 static ulong rk3528_grfclk_get_rate(struct clk *clk)
1598 {
1599 struct rk3528_clk_priv *priv;
1600 struct udevice *cru_dev;
1601 ulong rate = 0;
1602 int ret;
1603
1604 ret = uclass_get_device_by_driver(UCLASS_CLK,
1605 DM_GET_DRIVER(rockchip_rk3528_cru),
1606 &cru_dev);
1607 if (ret) {
1608 printf("%s: could not find cru device\n", __func__);
1609 return ret;
1610 }
1611 priv = dev_get_priv(cru_dev);
1612
1613 switch (clk->id) {
1614 case SCLK_SDMMC_SAMPLE:
1615 rate = rk3528_sdmmc_get_clk(priv, CCLK_SRC_SDMMC0) / 2;
1616 break;
1617 default:
1618 return -ENOENT;
1619 }
1620
1621 return rate;
1622 };
1623
1624 #define ROCKCHIP_MMC_DELAY_SEL BIT(11)
1625 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1626 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 3
1627 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1628 #define PSECS_PER_SEC 1000000000000LL
1629 /*
1630 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1631 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1632 */
1633 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1634
rk3528_mmc_get_phase(struct clk * clk)1635 int rk3528_mmc_get_phase(struct clk *clk)
1636 {
1637 struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev);
1638 u32 raw_value = 0, delay_num;
1639 u16 degrees = 0;
1640 ulong rate;
1641
1642 rate = rk3528_grfclk_get_rate(clk);
1643 if (rate < 0)
1644 return rate;
1645
1646 if (clk->id == SCLK_SDMMC_SAMPLE)
1647 raw_value = readl(&priv->grf->sdmmc_con1);
1648 else
1649 return -ENONET;
1650
1651 raw_value >>= 1;
1652 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1653
1654 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1655 /* degrees/delaynum * 10000 */
1656 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1657 36 * (rate / 1000000);
1658
1659 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1660 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1661 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1662 }
1663
1664 return degrees % 360;
1665 }
1666
rk3528_mmc_set_phase(struct clk * clk,u32 degrees)1667 int rk3528_mmc_set_phase(struct clk *clk, u32 degrees)
1668 {
1669 struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev);
1670 u8 nineties, remainder, delay_num;
1671 u32 raw_value, delay;
1672 ulong rate;
1673
1674 rate = rk3528_grfclk_get_rate(clk);
1675 if (rate < 0)
1676 return rate;
1677
1678 nineties = degrees / 90;
1679 remainder = (degrees % 90);
1680
1681 /*
1682 * Convert to delay; do a little extra work to make sure we
1683 * don't overflow 32-bit / 64-bit numbers.
1684 */
1685 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1686 delay *= remainder;
1687 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1688 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1689
1690 delay_num = (u8)min_t(u32, delay, 255);
1691
1692 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1693 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1694 raw_value |= nineties;
1695
1696 raw_value <<= 1;
1697 if (clk->id == SCLK_SDMMC_SAMPLE)
1698 writel(raw_value | 0xffff0000, &priv->grf->sdmmc_con1);
1699 else
1700 return -ENONET;
1701
1702 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1703 degrees, delay_num, raw_value, rk3528_mmc_get_phase(clk));
1704
1705 return 0;
1706 }
1707
rk3528_grfclk_get_phase(struct clk * clk)1708 static int rk3528_grfclk_get_phase(struct clk *clk)
1709 {
1710 int ret;
1711
1712 debug("%s %ld\n", __func__, clk->id);
1713 switch (clk->id) {
1714 case SCLK_SDMMC_SAMPLE:
1715 ret = rk3528_mmc_get_phase(clk);
1716 break;
1717 default:
1718 return -ENOENT;
1719 }
1720
1721 return ret;
1722 }
1723
rk3528_grfclk_set_phase(struct clk * clk,int degrees)1724 static int rk3528_grfclk_set_phase(struct clk *clk, int degrees)
1725 {
1726 int ret;
1727
1728 debug("%s %ld\n", __func__, clk->id);
1729 switch (clk->id) {
1730 case SCLK_SDMMC_SAMPLE:
1731 ret = rk3528_mmc_set_phase(clk, degrees);
1732 break;
1733 default:
1734 return -ENOENT;
1735 }
1736
1737 return ret;
1738 }
1739
1740 static struct clk_ops rk3528_grfclk_ops = {
1741 .get_rate = rk3528_grfclk_get_rate,
1742 .get_phase = rk3528_grfclk_get_phase,
1743 .set_phase = rk3528_grfclk_set_phase,
1744 };
1745
1746 #ifndef CONFIG_SPL_BUILD
1747 /**
1748 * soc_clk_dump() - Print clock frequencies
1749 * Returns zero on success
1750 *
1751 * Implementation for the clk dump command.
1752 */
soc_clk_dump(void)1753 int soc_clk_dump(void)
1754 {
1755 const struct rk3528_clk_info *clk_dump;
1756 struct rk3528_clk_priv *priv;
1757 struct udevice *cru_dev;
1758 struct clk clk;
1759 ulong clk_count = ARRAY_SIZE(clks_dump);
1760 ulong rate;
1761 int i, ret;
1762
1763 ret = uclass_get_device_by_driver(UCLASS_CLK,
1764 DM_GET_DRIVER(rockchip_rk3528_cru),
1765 &cru_dev);
1766 if (ret) {
1767 printf("%s failed to get cru device\n", __func__);
1768 return ret;
1769 }
1770
1771 priv = dev_get_priv(cru_dev);
1772 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1773 priv->sync_kernel ? "sync kernel" : "uboot",
1774 priv->armclk_enter_hz / 1000,
1775 priv->armclk_init_hz / 1000,
1776 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1777 priv->set_armclk_rate ? " KHz" : "N/A");
1778 for (i = 0; i < clk_count; i++) {
1779 clk_dump = &clks_dump[i];
1780 if (clk_dump->name) {
1781 clk.id = clk_dump->id;
1782 ret = clk_request(cru_dev, &clk);
1783 if (ret < 0)
1784 return ret;
1785
1786 rate = clk_get_rate(&clk);
1787 clk_free(&clk);
1788 if (i == 0) {
1789 if (rate < 0)
1790 printf(" %s %s\n", clk_dump->name,
1791 "unknown");
1792 else
1793 printf(" %s %lu KHz\n", clk_dump->name,
1794 rate / 1000);
1795 } else {
1796 if (rate < 0)
1797 printf(" %s %s\n", clk_dump->name,
1798 "unknown");
1799 else
1800 printf(" %s %lu KHz\n", clk_dump->name,
1801 rate / 1000);
1802 }
1803 }
1804 }
1805
1806 return 0;
1807 }
1808 #endif
1809
rk3528_grfclk_probe(struct udevice * dev)1810 static int rk3528_grfclk_probe(struct udevice *dev)
1811 {
1812 struct rk3528_grf_clk_priv *priv = dev_get_priv(dev);
1813
1814 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1815 if (IS_ERR(priv->grf))
1816 return PTR_ERR(priv->grf);
1817
1818 return 0;
1819 }
1820
1821 static const struct udevice_id rk3528_grf_cru_ids[] = {
1822 { .compatible = "rockchip,rk3528-grf-cru" },
1823 { }
1824 };
1825
1826 U_BOOT_DRIVER(rockchip_rk3528_grf_cru) = {
1827 .name = "rockchip_rk3528_grf_cru",
1828 .id = UCLASS_CLK,
1829 .of_match = rk3528_grf_cru_ids,
1830 .priv_auto_alloc_size = sizeof(struct rk3528_grf_clk_priv),
1831 .ops = &rk3528_grfclk_ops,
1832 .probe = rk3528_grfclk_probe,
1833 };
1834
rk3528_clk_init(struct rk3528_clk_priv * priv)1835 static int rk3528_clk_init(struct rk3528_clk_priv *priv)
1836 {
1837 int ret;
1838
1839 priv->sync_kernel = false;
1840
1841 #ifdef CONFIG_SPL_BUILD
1842 /*
1843 * BOOTROM:
1844 * CPU 1902/2(postdiv1)=546M
1845 * CPLL 996/2(postdiv1)=498M
1846 * GPLL 1188/2(postdiv1)=594M
1847 * |-- clk_matrix_200m_src_div=1 => rate: 300M
1848 * |-- clk_matrix_300m_src_div=2 => rate: 200M
1849 *
1850 * Avoid overclocking when change GPLL rate:
1851 * Change clk_matrix_200m_src_div to 5.
1852 * Change clk_matrix_300m_src_div to 3.
1853 */
1854 writel(0x01200120, &priv->cru->clksel_con[1]);
1855 writel(0x00030003, &priv->cru->clksel_con[2]);
1856
1857 if (!priv->armclk_enter_hz) {
1858 priv->armclk_enter_hz =
1859 rockchip_pll_get_rate(&rk3528_pll_clks[APLL],
1860 priv->cru, APLL);
1861 priv->armclk_init_hz = priv->armclk_enter_hz;
1862 }
1863
1864 if (priv->armclk_init_hz != APLL_HZ) {
1865 ret = rk3528_armclk_set_clk(priv, APLL_HZ);
1866 if (!ret)
1867 priv->armclk_init_hz = APLL_HZ;
1868 }
1869 #else
1870 if (!priv->armclk_enter_hz) {
1871 struct clk clk;
1872
1873 ret = rockchip_get_scmi_clk(&clk.dev);
1874 if (ret) {
1875 printf("Failed to get scmi clk dev\n");
1876 return ret;
1877 }
1878
1879 clk.id = SCMI_CLK_CPU;
1880 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
1881 if (ret < 0) {
1882 printf("Failed to set scmi cpu %dhz\n", CPU_PVTPLL_HZ);
1883 return ret;
1884 } else {
1885 priv->armclk_enter_hz =
1886 rockchip_pll_get_rate(&rk3528_pll_clks[APLL],
1887 priv->cru, APLL);
1888 priv->armclk_init_hz = CPU_PVTPLL_HZ;
1889 }
1890 }
1891 #endif
1892 if (priv->cpll_hz != CPLL_HZ) {
1893 ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru,
1894 CPLL, CPLL_HZ);
1895 if (!ret)
1896 priv->cpll_hz = CPLL_HZ;
1897 }
1898
1899 if (priv->gpll_hz != GPLL_HZ) {
1900 ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru,
1901 GPLL, GPLL_HZ);
1902 if (!ret)
1903 priv->gpll_hz = GPLL_HZ;
1904 }
1905
1906 if (priv->ppll_hz != PPLL_HZ) {
1907 ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru,
1908 PPLL, PPLL_HZ);
1909 if (!ret)
1910 priv->ppll_hz = PPLL_HZ;
1911 }
1912
1913 #ifdef CONFIG_SPL_BUILD
1914 /* Init to override bootrom config */
1915 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_50M_SRC, 50000000);
1916 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_100M_SRC, 100000000);
1917 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_150M_SRC, 150000000);
1918 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_200M_SRC, 200000000);
1919 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_250M_SRC, 250000000);
1920 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_300M_SRC, 300000000);
1921 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_339M_SRC, 340000000);
1922 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_400M_SRC, 400000000);
1923 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_500M_SRC, 500000000);
1924 rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_600M_SRC, 600000000);
1925 rk3528_cgpll_matrix_set_rate(priv, ACLK_BUS_VOPGL_BIU, 500000000);
1926
1927 /* The default rate is 100Mhz, it's not friendly for remote IR module */
1928 rk3528_pwm_set_clk(priv, CLK_PWM0, 24000000);
1929 rk3528_pwm_set_clk(priv, CLK_PWM1, 24000000);
1930 #endif
1931 return 0;
1932 }
1933
rk3528_clk_probe(struct udevice * dev)1934 static int rk3528_clk_probe(struct udevice *dev)
1935 {
1936 struct rk3528_clk_priv *priv = dev_get_priv(dev);
1937 int ret;
1938
1939 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1940 if (IS_ERR(priv->grf))
1941 return PTR_ERR(priv->grf);
1942
1943 ret = rk3528_clk_init(priv);
1944 if (ret)
1945 return ret;
1946
1947 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1948 ret = clk_set_defaults(dev);
1949 if (ret)
1950 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1951 else
1952 priv->sync_kernel = true;
1953
1954 return 0;
1955 }
1956
rk3528_clk_ofdata_to_platdata(struct udevice * dev)1957 static int rk3528_clk_ofdata_to_platdata(struct udevice *dev)
1958 {
1959 struct rk3528_clk_priv *priv = dev_get_priv(dev);
1960
1961 priv->cru = dev_read_addr_ptr(dev);
1962
1963 return 0;
1964 }
1965
rk3528_clk_bind(struct udevice * dev)1966 static int rk3528_clk_bind(struct udevice *dev)
1967 {
1968 struct udevice *sys_child, *sf_child;
1969 struct softreset_reg *sf_priv;
1970 struct sysreset_reg *priv;
1971 int ret;
1972
1973 /* The reset driver does not have a device node, so bind it here */
1974 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1975 &sys_child);
1976 if (ret) {
1977 debug("Warning: No sysreset driver: ret=%d\n", ret);
1978 } else {
1979 priv = malloc(sizeof(struct sysreset_reg));
1980 priv->glb_srst_fst_value = offsetof(struct rk3528_cru,
1981 glb_srst_fst);
1982 priv->glb_srst_snd_value = offsetof(struct rk3528_cru,
1983 glb_srst_snd);
1984 sys_child->priv = priv;
1985 }
1986
1987 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1988 dev_ofnode(dev), &sf_child);
1989 if (ret) {
1990 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1991 } else {
1992 sf_priv = malloc(sizeof(struct softreset_reg));
1993 sf_priv->sf_reset_offset = offsetof(struct rk3528_cru,
1994 softrst_con[0]);
1995 sf_priv->sf_reset_num = 47;
1996 sf_child->priv = sf_priv;
1997 }
1998
1999 return 0;
2000 }
2001
2002 static const struct udevice_id rk3528_clk_ids[] = {
2003 { .compatible = "rockchip,rk3528-cru" },
2004 { }
2005 };
2006
2007 U_BOOT_DRIVER(rockchip_rk3528_cru) = {
2008 .name = "rockchip_rk3528_cru",
2009 .id = UCLASS_CLK,
2010 .of_match = rk3528_clk_ids,
2011 .priv_auto_alloc_size = sizeof(struct rk3528_clk_priv),
2012 .ofdata_to_platdata = rk3528_clk_ofdata_to_platdata,
2013 .ops = &rk3528_clk_ops,
2014 .bind = rk3528_clk_bind,
2015 .probe = rk3528_clk_probe,
2016 };
2017
2018 /* spl scmi clk */
2019 #ifdef CONFIG_SPL_BUILD
2020
rk3528_crypto_get_rate(struct rk3528_clk_priv * priv,struct clk * clk)2021 static ulong rk3528_crypto_get_rate(struct rk3528_clk_priv *priv, struct clk *clk)
2022 {
2023 struct rk3528_cru *cru = priv->cru;
2024 u32 id, sel, con, mask, shift;
2025 ulong rate;
2026
2027 switch (clk->id) {
2028 case SCMI_CORE_CRYPTO:
2029 id = 43;
2030 mask = CLK_CORE_CRYPTO_SEL_MASK;
2031 shift = CLK_CORE_CRYPTO_SEL_SHIFT;
2032 break;
2033
2034 case SCMI_PKA_CRYPTO:
2035 id = 44;
2036 mask = CLK_PKA_CRYPTO_SEL_MASK;
2037 shift = CLK_PKA_CRYPTO_SEL_SHIFT;
2038 break;
2039
2040 default:
2041 return -ENOENT;
2042 }
2043
2044 con = readl(&cru->clksel_con[id]);
2045 sel = (con & mask) >> shift;
2046 if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC)
2047 rate = 300 * MHz;
2048 else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC)
2049 rate = 200 * MHz;
2050 else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC)
2051 rate = 100 * MHz;
2052 else
2053 rate = OSC_HZ;
2054
2055 return rate;
2056 }
2057
rk3528_crypto_set_rate(struct rk3528_clk_priv * priv,struct clk * clk,ulong rate)2058 static ulong rk3528_crypto_set_rate(struct rk3528_clk_priv *priv,
2059 struct clk *clk, ulong rate)
2060 {
2061 struct rk3528_cru *cru = priv->cru;
2062 u32 id, sel, mask, shift;
2063
2064 if (rate == 300 * MHz)
2065 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC;
2066 else if (rate == 200 * MHz)
2067 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC;
2068 else if (rate == 100 * MHz)
2069 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC;
2070 else
2071 sel = CLK_CORE_CRYPTO_SEL_XIN_OSC0_FUNC;
2072
2073 switch (clk->id) {
2074 case SCMI_CORE_CRYPTO:
2075 id = 43;
2076 mask = CLK_CORE_CRYPTO_SEL_MASK;
2077 shift = CLK_CORE_CRYPTO_SEL_SHIFT;
2078 break;
2079
2080 case SCMI_PKA_CRYPTO:
2081 id = 44;
2082 mask = CLK_PKA_CRYPTO_SEL_MASK;
2083 shift = CLK_PKA_CRYPTO_SEL_SHIFT;
2084 break;
2085
2086 default:
2087 return -ENOENT;
2088 }
2089
2090 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
2091
2092 return rk3528_crypto_get_rate(priv, clk);
2093 }
2094
rk3528_clk_scmi_get_rate(struct clk * clk)2095 static ulong rk3528_clk_scmi_get_rate(struct clk *clk)
2096 {
2097 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
2098
2099 switch (clk->id) {
2100 case SCMI_CORE_CRYPTO:
2101 case SCMI_PKA_CRYPTO:
2102 return rk3528_crypto_get_rate(priv, clk);
2103 default:
2104 return -ENOENT;
2105 }
2106 };
2107
rk3528_clk_scmi_set_rate(struct clk * clk,ulong rate)2108 static ulong rk3528_clk_scmi_set_rate(struct clk *clk, ulong rate)
2109 {
2110 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
2111
2112 switch (clk->id) {
2113 case SCMI_CORE_CRYPTO:
2114 case SCMI_PKA_CRYPTO:
2115 return rk3528_crypto_set_rate(priv, clk, rate);
2116 default:
2117 return -ENOENT;
2118 }
2119
2120 return 0;
2121 };
2122
rk3528_scmi_clk_ofdata_to_platdata(struct udevice * dev)2123 static int rk3528_scmi_clk_ofdata_to_platdata(struct udevice *dev)
2124 {
2125 struct rk3528_clk_priv *priv = dev_get_priv(dev);
2126
2127 priv->cru = (struct rk3528_cru *)0xff4a0000;
2128
2129 return 0;
2130 }
2131
2132 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2133 static const struct clk_ops scmi_clk_ops = {
2134 .get_rate = rk3528_clk_scmi_get_rate,
2135 .set_rate = rk3528_clk_scmi_set_rate,
2136 };
2137
2138 U_BOOT_DRIVER(scmi_clock) = {
2139 .name = "scmi_clk",
2140 .id = UCLASS_CLK,
2141 .ops = &scmi_clk_ops,
2142 .priv_auto_alloc_size = sizeof(struct rk3528_clk_priv),
2143 .ofdata_to_platdata = rk3528_scmi_clk_ofdata_to_platdata,
2144 };
2145 #endif
2146