1 /*
2 * (C) Copyright 2015 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 #include <common.h>
8 #include <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <dt-structs.h>
12 #include <errno.h>
13 #include <mapmem.h>
14 #include <syscon.h>
15 #include <asm/io.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/cru_rk3288.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/hardware.h>
20 #include <dt-bindings/clock/rk3288-cru.h>
21 #include <dm/device-internal.h>
22 #include <dm/lists.h>
23 #include <dm/uclass-internal.h>
24 #include <linux/log2.h>
25
26 DECLARE_GLOBAL_DATA_PTR;
27
28 struct rk3288_clk_plat {
29 #if CONFIG_IS_ENABLED(OF_PLATDATA)
30 struct dtd_rockchip_rk3288_cru dtd;
31 #endif
32 };
33
34 struct pll_div {
35 ulong rate;
36 u32 nr;
37 u32 nf;
38 u32 no;
39 u32 nb;
40 };
41
42 #define RK3288_PLL_RATE(_rate, _nr, _nf, _no, _nb) \
43 { \
44 .rate = _rate##U, \
45 .nr = _nr, \
46 .nf = _nf, \
47 .no = _no, \
48 .nb = _nb, \
49 }
50
51 static struct pll_div rk3288_pll_rates[] = {
52 /* _mhz, _nr, _nf, _no, _nb */
53 RK3288_PLL_RATE(1188000000, 1, 99, 2, 16),
54 RK3288_PLL_RATE(594000000, 1, 99, 4, 16),
55 RK3288_PLL_RATE(297000000, 1, 99, 8, 16),
56 };
57
58 #ifndef CONFIG_SPL_BUILD
59 #define RK3288_CLK_DUMP(_id, _name, _iscru) \
60 { \
61 .id = _id, \
62 .name = _name, \
63 .is_cru = _iscru, \
64 }
65
66 static const struct rk3288_clk_info clks_dump[] = {
67 RK3288_CLK_DUMP(PLL_APLL, "apll", true),
68 RK3288_CLK_DUMP(PLL_DPLL, "dpll", true),
69 RK3288_CLK_DUMP(PLL_CPLL, "cpll", true),
70 RK3288_CLK_DUMP(PLL_GPLL, "gpll", true),
71 RK3288_CLK_DUMP(PLL_NPLL, "npll", true),
72 RK3288_CLK_DUMP(ACLK_CPU, "aclk_bus", true),
73 };
74 #endif
75
76 enum {
77 VCO_MAX_HZ = 2200U * 1000000,
78 VCO_MIN_HZ = 440 * 1000000,
79 OUTPUT_MAX_HZ = 2200U * 1000000,
80 OUTPUT_MIN_HZ = 27500000,
81 FREF_MAX_HZ = 2200U * 1000000,
82 FREF_MIN_HZ = 269 * 1000,
83 };
84
85 enum {
86 /* PLL CON0 */
87 PLL_OD_MASK = 0x0f,
88
89 /* PLL CON1 */
90 PLL_NF_MASK = 0x1fff,
91
92 /* PLL CON2 */
93 PLL_BWADJ_MASK = 0x0fff,
94
95 /* PLL CON3 */
96 PLL_RESET_SHIFT = 5,
97
98 /* CLKSEL0 */
99 CORE_SEL_PLL_SHIFT = 15,
100 CORE_SEL_PLL_MASK = 1 << CORE_SEL_PLL_SHIFT,
101 A17_DIV_SHIFT = 8,
102 A17_DIV_MASK = 0x1f << A17_DIV_SHIFT,
103 MP_DIV_SHIFT = 4,
104 MP_DIV_MASK = 0xf << MP_DIV_SHIFT,
105 M0_DIV_SHIFT = 0,
106 M0_DIV_MASK = 0xf << M0_DIV_SHIFT,
107
108 /* CLKSEL1: pd bus clk pll sel: codec or general */
109 PD_BUS_SEL_PLL_SHIFT = 15,
110 PD_BUS_SEL_PLL_MASK = 1 << PD_BUS_SEL_PLL_SHIFT,
111 PD_BUS_SEL_CPLL = 0,
112 PD_BUS_SEL_GPLL,
113
114 /* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */
115 PD_BUS_PCLK_DIV_SHIFT = 12,
116 PD_BUS_PCLK_DIV_MASK = 7 << PD_BUS_PCLK_DIV_SHIFT,
117
118 /* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
119 PD_BUS_HCLK_DIV_SHIFT = 8,
120 PD_BUS_HCLK_DIV_MASK = 3 << PD_BUS_HCLK_DIV_SHIFT,
121
122 /* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */
123 PD_BUS_ACLK_DIV0_SHIFT = 3,
124 PD_BUS_ACLK_DIV0_MASK = 0x1f << PD_BUS_ACLK_DIV0_SHIFT,
125 PD_BUS_ACLK_DIV1_SHIFT = 0,
126 PD_BUS_ACLK_DIV1_MASK = 0x7 << PD_BUS_ACLK_DIV1_SHIFT,
127
128 /* CLKSEL2: tsadc */
129 CLK_TSADC_DIV_CON_SHIFT = 0,
130 CLK_TSADC_DIV_CON_MASK = GENMASK(5, 0),
131 CLK_TSADC_DIV_CON_WIDTH = 6,
132
133 /*
134 * CLKSEL10
135 * peripheral bus pclk div:
136 * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1
137 */
138 PERI_SEL_PLL_SHIFT = 15,
139 PERI_SEL_PLL_MASK = 1 << PERI_SEL_PLL_SHIFT,
140 PERI_SEL_CPLL = 0,
141 PERI_SEL_GPLL,
142
143 PERI_PCLK_DIV_SHIFT = 12,
144 PERI_PCLK_DIV_MASK = 3 << PERI_PCLK_DIV_SHIFT,
145
146 /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
147 PERI_HCLK_DIV_SHIFT = 8,
148 PERI_HCLK_DIV_MASK = 3 << PERI_HCLK_DIV_SHIFT,
149
150 /*
151 * peripheral bus aclk div:
152 * aclk_periph = periph_clk_src / (peri_aclk_div_con + 1)
153 */
154 PERI_ACLK_DIV_SHIFT = 0,
155 PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT,
156
157 /*
158 * CLKSEL24
159 * saradc_div_con:
160 * clk_saradc=24MHz/(saradc_div_con+1)
161 */
162 CLK_SARADC_DIV_CON_SHIFT = 8,
163 CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
164 CLK_SARADC_DIV_CON_WIDTH = 8,
165
166 /* CLKSEL26 */
167 CLK_CRYPTO_DIV_CON_SHIFT = 6,
168 CLK_CRYPTO_DIV_CON_MASK = GENMASK(7, 6),
169
170 /* CLKSEL33 */
171 PCLK_ALIVE_DIV_CON_SHIFT = 8,
172 PCLK_ALIVE_DIV_CON_MASK = 0x1f << PCLK_ALIVE_DIV_CON_SHIFT,
173
174 /* CLKSEL39 */
175 ACLK_HEVC_SEL_PLL_SHIFT = 14,
176 ACLK_HEVC_SEL_PLL_MASK = 0x3 << ACLK_HEVC_SEL_PLL_SHIFT,
177 ACLK_HEVC_SEL_CPLL = 0,
178 ACLK_HEVC_SEL_GPLL,
179 ACLK_HEVC_DIV_CON_SHIFT = 8,
180 ACLK_HEVC_DIV_CON_MASK = 0x1f << ACLK_HEVC_DIV_CON_SHIFT,
181
182 /* CLKSEL42 */
183 CLK_HEVC_CORE_SEL_PLL_SHIFT = 14,
184 CLK_HEVC_CORE_SEL_PLL_MASK = 0x3 << CLK_HEVC_CORE_SEL_PLL_SHIFT,
185 CLK_HEVC_CORE_SEL_CPLL = 0,
186 CLK_HEVC_CORE_SEL_GPLL,
187 CLK_HEVC_CORE_DIV_CON_SHIFT = 8,
188 CLK_HEVC_CORE_DIV_CON_MASK = 0x1f << CLK_HEVC_CORE_DIV_CON_SHIFT,
189 CLK_HEVC_CABAC_SEL_PLL_SHIFT = 6,
190 CLK_HEVC_CABAC_SEL_PLL_MASK = 0x3 << CLK_HEVC_CABAC_SEL_PLL_SHIFT,
191 CLK_HEVC_CABAC_SEL_CPLL = 0,
192 CLK_HEVC_CABAC_SEL_GPLL,
193 CLK_HEVC_CABAC_DIV_CON_SHIFT = 0,
194 CLK_HEVC_CABAC_DIV_CON_MASK = 0x1f << CLK_HEVC_CABAC_DIV_CON_SHIFT,
195
196 /* MISC */
197 CLK_TEST_SRC_SEL_SHIFT = 8,
198 CLK_TEST_SRC_SEL_MASK = 0xf << CLK_TEST_SRC_SEL_SHIFT,
199 CLK_TEST_SRC_SEL_24M = 8,
200 CLK_TEST_SRC_SEL_27M,
201 CLK_TEST_SRC_SEL_32k,
202
203 SOCSTS_DPLL_LOCK = 1 << 5,
204 SOCSTS_APLL_LOCK = 1 << 6,
205 SOCSTS_CPLL_LOCK = 1 << 7,
206 SOCSTS_GPLL_LOCK = 1 << 8,
207 SOCSTS_NPLL_LOCK = 1 << 9,
208 };
209
210 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
211
212 #define PLL_DIVISORS(hz, _nr, _no) {\
213 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
214 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
215 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
216 "divisors on line " __stringify(__LINE__));
217
218 /* Keep divisors as low as possible to reduce jitter and power usage */
219 static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
220 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4);
221 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
222
rkclk_get_pll_config(ulong freq_hz)223 struct pll_div *rkclk_get_pll_config(ulong freq_hz)
224 {
225 unsigned int rate_count = ARRAY_SIZE(rk3288_pll_rates);
226 int i;
227
228 for (i = 0; i < rate_count; i++) {
229 if (freq_hz == rk3288_pll_rates[i].rate)
230 return &rk3288_pll_rates[i];
231 }
232 return NULL;
233 }
234
rkclk_set_pll(struct rk3288_cru * cru,enum rk_clk_id clk_id,const struct pll_div * div)235 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
236 const struct pll_div *div)
237 {
238 int pll_id = rk_pll_id(clk_id);
239 struct rk3288_pll *pll = &cru->pll[pll_id];
240 /* All PLLs have same VCO and output frequency range restrictions. */
241 uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
242 uint output_hz = vco_hz / div->no;
243
244 debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
245 (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
246
247 /* enter reset */
248 rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
249
250 rk_clrsetreg(&pll->con0, CLKR_MASK | PLL_OD_MASK,
251 ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
252 rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
253
254 /* adjust pll bw for better clock jitter */
255 if (div->nb)
256 rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, div->nb - 1);
257 else
258 rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
259
260 udelay(10);
261
262 /* return from reset */
263 rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
264
265 return 0;
266 }
267
268 /* Get pll rate by id */
rkclk_pll_get_rate(struct rk3288_cru * cru,enum rk_clk_id clk_id)269 static u32 rkclk_pll_get_rate(struct rk3288_cru *cru,
270 enum rk_clk_id clk_id)
271 {
272 u32 nr, no, nf;
273 u32 con;
274 int pll_id = rk_pll_id(clk_id);
275 struct rk3288_pll *pll = &cru->pll[pll_id];
276 static u8 clk_shift[CLK_COUNT] = {
277 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
278 GPLL_MODE_SHIFT, NPLL_MODE_SHIFT
279 };
280 uint shift;
281
282 con = readl(&cru->cru_mode_con);
283 shift = clk_shift[clk_id];
284 switch ((con >> shift) & CRU_MODE_MASK) {
285 case APLL_MODE_SLOW:
286 return OSC_HZ;
287 case APLL_MODE_NORMAL:
288 /* normal mode */
289 con = readl(&pll->con0);
290 no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1;
291 nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1;
292 con = readl(&pll->con1);
293 nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1;
294
295 return (24 * nf / (nr * no)) * 1000000;
296 case APLL_MODE_DEEP:
297 default:
298 return 32768;
299 }
300 }
301
rkclk_configure_ddr(struct rk3288_cru * cru,struct rk3288_grf * grf,unsigned int hz)302 static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
303 unsigned int hz)
304 {
305 static const struct pll_div dpll_cfg[] = {
306 {.nf = 25, .nr = 2, .no = 1},
307 {.nf = 400, .nr = 9, .no = 2},
308 {.nf = 500, .nr = 9, .no = 2},
309 {.nf = 100, .nr = 3, .no = 1},
310 };
311 int cfg;
312
313 switch (hz) {
314 case 300000000:
315 cfg = 0;
316 break;
317 case 533000000: /* actually 533.3P MHz */
318 cfg = 1;
319 break;
320 case 666000000: /* actually 666.6P MHz */
321 cfg = 2;
322 break;
323 case 800000000:
324 cfg = 3;
325 break;
326 default:
327 debug("Unsupported SDRAM frequency");
328 return -EINVAL;
329 }
330
331 /* pll enter slow-mode */
332 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
333 DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
334
335 rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
336
337 /* wait for pll lock */
338 while (!(readl(&grf->soc_status[1]) & SOCSTS_DPLL_LOCK))
339 udelay(1);
340
341 /* PLL enter normal-mode */
342 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
343 DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
344
345 return 0;
346 }
347
348 #ifndef CONFIG_SPL_BUILD
349 #define VCO_MAX_KHZ 2200000
350 #define VCO_MIN_KHZ 440000
351 #define FREF_MAX_KHZ 2200000
352 #define FREF_MIN_KHZ 269
353 #define PLL_LIMIT_FREQ 594000000
354
pll_para_config(ulong freq_hz,struct pll_div * div,uint * ext_div)355 static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div)
356 {
357 struct pll_div *best_div = NULL;
358 uint ref_khz = OSC_HZ / 1000, nr, nf = 0;
359 uint fref_khz;
360 uint diff_khz, best_diff_khz;
361 const uint max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4;
362 uint vco_khz;
363 uint no = 1;
364 uint freq_khz = freq_hz / 1000;
365
366 if (!freq_hz) {
367 printf("%s: the frequency can not be 0 Hz\n", __func__);
368 return -EINVAL;
369 }
370
371 no = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
372 if (ext_div) {
373 *ext_div = DIV_ROUND_UP(PLL_LIMIT_FREQ, freq_hz);
374 no = DIV_ROUND_UP(no, *ext_div);
375 }
376
377 best_div = rkclk_get_pll_config(freq_hz * (*ext_div));
378 if (best_div) {
379 div->nr = best_div->nr;
380 div->nf = best_div->nf;
381 div->no = best_div->no;
382 div->nb = best_div->nb;
383 return 0;
384 }
385
386 /* only even divisors (and 1) are supported */
387 if (no > 1)
388 no = DIV_ROUND_UP(no, 2) * 2;
389
390 vco_khz = freq_khz * no;
391 if (ext_div)
392 vco_khz *= *ext_div;
393
394 if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) {
395 printf("%s: Cannot find out a supported VCO for Frequency (%luHz).\n",
396 __func__, freq_hz);
397 return -1;
398 }
399
400 div->no = no;
401
402 best_diff_khz = vco_khz;
403 for (nr = 1; nr < max_nr && best_diff_khz; nr++) {
404 fref_khz = ref_khz / nr;
405 if (fref_khz < FREF_MIN_KHZ)
406 break;
407 if (fref_khz > FREF_MAX_KHZ)
408 continue;
409
410 nf = vco_khz / fref_khz;
411 if (nf >= max_nf)
412 continue;
413 diff_khz = vco_khz - nf * fref_khz;
414 if (nf + 1 < max_nf && diff_khz > fref_khz / 2) {
415 nf++;
416 diff_khz = fref_khz - diff_khz;
417 }
418
419 if (diff_khz >= best_diff_khz)
420 continue;
421
422 best_diff_khz = diff_khz;
423 div->nr = nr;
424 div->nf = nf;
425 }
426
427 if (best_diff_khz > 4 * 1000) {
428 printf("%s: Failed to match output frequency %lu, difference is %u Hz, exceed 4MHZ\n",
429 __func__, freq_hz, best_diff_khz * 1000);
430 return -EINVAL;
431 }
432
433 return 0;
434 }
435
rockchip_mac_set_clk(struct rk3288_cru * cru,uint freq)436 static int rockchip_mac_set_clk(struct rk3288_cru *cru, uint freq)
437 {
438 ulong ret;
439
440 /*
441 * The gmac clock can be derived either from an external clock
442 * or can be generated from internally by a divider from SCLK_MAC.
443 */
444 if (readl(&cru->cru_clksel_con[21]) & RMII_EXTCLK_MASK) {
445 /* An external clock will always generate the right rate... */
446 ret = freq;
447 } else {
448 u32 con = readl(&cru->cru_clksel_con[21]);
449 ulong pll_rate;
450 u8 div;
451
452 if (((con >> EMAC_PLL_SHIFT) & EMAC_PLL_MASK) ==
453 EMAC_PLL_SELECT_GENERAL)
454 pll_rate = GPLL_HZ;
455 else if (((con >> EMAC_PLL_SHIFT) & EMAC_PLL_MASK) ==
456 EMAC_PLL_SELECT_CODEC)
457 pll_rate = CPLL_HZ;
458 else
459 pll_rate = NPLL_HZ;
460
461 div = DIV_ROUND_UP(pll_rate, freq) - 1;
462 if (div <= 0x1f)
463 rk_clrsetreg(&cru->cru_clksel_con[21], MAC_DIV_CON_MASK,
464 div << MAC_DIV_CON_SHIFT);
465 else
466 debug("Unsupported div for gmac:%d\n", div);
467
468 return DIV_TO_RATE(pll_rate, div);
469 }
470
471 return ret;
472 }
473
rockchip_vop_set_clk(struct rk3288_cru * cru,struct rk3288_grf * grf,int periph,unsigned int rate_hz)474 static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
475 int periph, unsigned int rate_hz)
476 {
477 struct pll_div cpll_config = {0};
478 u32 lcdc_div, parent;
479 int ret;
480 unsigned int gpll_rate, npll_rate;
481
482 gpll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
483 npll_rate = rkclk_pll_get_rate(cru, CLK_NEW);
484
485 /* vop dclk source clk: cpll,dclk_div: 1 */
486 switch (periph) {
487 case DCLK_VOP0:
488 ret = (readl(&cru->cru_clksel_con[27]) & DCLK_VOP0_PLL_MASK) >>
489 DCLK_VOP0_PLL_SHIFT;
490 if (ret == DCLK_VOP0_SELECT_CPLL) {
491 ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div);
492 if (ret)
493 return ret;
494
495 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
496 CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
497 rkclk_set_pll(cru, CLK_CODEC, &cpll_config);
498
499 /* waiting for pll lock */
500 while (1) {
501 if (readl(&grf->soc_status[1]) &
502 SOCSTS_CPLL_LOCK)
503 break;
504 udelay(1);
505 }
506
507 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
508 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
509 parent = DCLK_VOP0_SELECT_CPLL;
510 } else if (ret == DCLK_VOP0_SELECT_GPLL) {
511 parent = DCLK_VOP0_SELECT_GPLL;
512 lcdc_div = DIV_ROUND_UP(gpll_rate,
513 rate_hz);
514 } else {
515 parent = DCLK_VOP0_SELECT_NPLL;
516 lcdc_div = DIV_ROUND_UP(npll_rate,
517 rate_hz);
518 }
519 rk_clrsetreg(&cru->cru_clksel_con[27],
520 DCLK_VOP0_DIV_MASK | DCLK_VOP0_PLL_MASK,
521 ((lcdc_div - 1) << DCLK_VOP0_DIV_SHIFT) |
522 (parent << DCLK_VOP0_PLL_SHIFT));
523 break;
524 case DCLK_VOP1:
525 ret = (readl(&cru->cru_clksel_con[29]) & DCLK_VOP1_PLL_MASK) >>
526 DCLK_VOP1_PLL_SHIFT;
527 if (ret == DCLK_VOP1_SELECT_CPLL) {
528 ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div);
529 if (ret)
530 return ret;
531
532 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
533 CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
534 rkclk_set_pll(cru, CLK_CODEC, &cpll_config);
535
536 /* waiting for pll lock */
537 while (1) {
538 if (readl(&grf->soc_status[1]) &
539 SOCSTS_CPLL_LOCK)
540 break;
541 udelay(1);
542 }
543
544 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
545 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
546
547 parent = DCLK_VOP1_SELECT_CPLL;
548 } else if (ret == DCLK_VOP1_SELECT_GPLL) {
549 parent = DCLK_VOP1_SELECT_GPLL;
550 lcdc_div = DIV_ROUND_UP(gpll_rate,
551 rate_hz);
552 } else {
553 parent = DCLK_VOP1_SELECT_NPLL;
554 lcdc_div = DIV_ROUND_UP(npll_rate,
555 rate_hz);
556 }
557 rk_clrsetreg(&cru->cru_clksel_con[29],
558 DCLK_VOP1_DIV_MASK | DCLK_VOP1_PLL_MASK,
559 ((lcdc_div - 1) << DCLK_VOP1_DIV_SHIFT) |
560 (parent << DCLK_VOP1_PLL_SHIFT));
561 break;
562 case ACLK_VIO0:
563 lcdc_div = DIV_ROUND_UP(gpll_rate, rate_hz);
564 rk_clrsetreg(&cru->cru_clksel_con[31],
565 ACLK_VIO0_PLL_MASK | ACLK_VIO0_DIV_MASK,
566 ACLK_VIO_SELECT_GPLL << ACLK_VIO0_PLL_SHIFT |
567 (lcdc_div - 1) << ACLK_VIO0_DIV_SHIFT);
568 break;
569 case ACLK_VIO1:
570 lcdc_div = DIV_ROUND_UP(gpll_rate, rate_hz);
571 rk_clrsetreg(&cru->cru_clksel_con[31],
572 ACLK_VIO1_PLL_MASK | ACLK_VIO1_DIV_MASK,
573 ACLK_VIO_SELECT_GPLL << ACLK_VIO1_PLL_SHIFT |
574 (lcdc_div - 1) << ACLK_VIO1_DIV_SHIFT);
575
576 lcdc_div = DIV_ROUND_UP(rate_hz, HCLK_VIO_HZ);
577 rk_clrsetreg(&cru->cru_clksel_con[28],
578 HCLK_VIO_DIV_MASK,
579 (lcdc_div - 1) << HCLK_VIO_DIV_SHIFT);
580 break;
581 }
582
583 return 0;
584 }
585 #endif /* CONFIG_SPL_BUILD */
586
rkclk_init(struct rk3288_cru * cru,struct rk3288_grf * grf)587 static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
588 {
589 u32 aclk_div;
590 u32 hclk_div;
591 u32 pclk_div;
592
593 /* pll enter slow-mode */
594 rk_clrsetreg(&cru->cru_mode_con,
595 GPLL_MODE_MASK | CPLL_MODE_MASK,
596 GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
597 CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
598
599 /* init pll */
600 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
601 rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
602
603 /* waiting for pll lock */
604 while ((readl(&grf->soc_status[1]) &
605 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
606 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
607 udelay(1);
608
609 /*
610 * pd_bus clock pll source selection and
611 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
612 */
613 aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1;
614 assert((aclk_div + 1) * PD_BUS_ACLK_HZ <= GPLL_HZ && aclk_div <= 0x1f);
615 hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1;
616 assert((hclk_div + 1) * PD_BUS_HCLK_HZ <=
617 PD_BUS_ACLK_HZ && (hclk_div <= 0x3) && (hclk_div != 0x2));
618
619 pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1;
620 assert((pclk_div + 1) * PD_BUS_PCLK_HZ <=
621 PD_BUS_ACLK_HZ && pclk_div <= 0x7);
622
623 rk_clrsetreg(&cru->cru_clksel_con[1],
624 PD_BUS_PCLK_DIV_MASK | PD_BUS_HCLK_DIV_MASK |
625 PD_BUS_ACLK_DIV0_MASK | PD_BUS_ACLK_DIV1_MASK,
626 pclk_div << PD_BUS_PCLK_DIV_SHIFT |
627 hclk_div << PD_BUS_HCLK_DIV_SHIFT |
628 aclk_div << PD_BUS_ACLK_DIV0_SHIFT |
629 0 << 0);
630
631 /*
632 * peri clock pll source selection and
633 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
634 */
635 aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
636 assert((aclk_div + 1) * PERI_ACLK_HZ <= GPLL_HZ && aclk_div <= 0x1f);
637
638 hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
639 assert((1 << hclk_div) * PERI_HCLK_HZ <=
640 PERI_ACLK_HZ && (hclk_div <= 0x2));
641
642 pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
643 assert((1 << pclk_div) * PERI_PCLK_HZ <=
644 PERI_ACLK_HZ && (pclk_div <= 0x3));
645
646 rk_clrsetreg(&cru->cru_clksel_con[10],
647 PERI_PCLK_DIV_MASK | PERI_HCLK_DIV_MASK |
648 PERI_ACLK_DIV_MASK,
649 PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
650 pclk_div << PERI_PCLK_DIV_SHIFT |
651 hclk_div << PERI_HCLK_DIV_SHIFT |
652 aclk_div << PERI_ACLK_DIV_SHIFT);
653
654 rk_clrsetreg(&cru->cru_clksel_con[39],
655 ACLK_HEVC_SEL_PLL_MASK | ACLK_HEVC_DIV_CON_MASK,
656 ACLK_HEVC_SEL_CPLL << ACLK_HEVC_SEL_PLL_SHIFT |
657 4 << ACLK_HEVC_DIV_CON_SHIFT);
658 rk_clrsetreg(&cru->cru_clksel_con[42],
659 CLK_HEVC_CORE_SEL_PLL_MASK | CLK_HEVC_CORE_DIV_CON_MASK |
660 CLK_HEVC_CORE_SEL_PLL_MASK | CLK_HEVC_CORE_DIV_CON_MASK,
661 CLK_HEVC_CORE_SEL_CPLL << CLK_HEVC_CORE_SEL_PLL_SHIFT |
662 CLK_HEVC_CABAC_SEL_CPLL << CLK_HEVC_CABAC_DIV_CON_SHIFT |
663 4 << CLK_HEVC_CORE_DIV_CON_SHIFT |
664 4 << CLK_HEVC_CABAC_DIV_CON_SHIFT);
665
666 /* PLL enter normal-mode */
667 rk_clrsetreg(&cru->cru_mode_con,
668 GPLL_MODE_MASK | CPLL_MODE_MASK,
669 GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
670 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
671 }
672
rk3288_clk_configure_cpu(struct rk3288_cru * cru,struct rk3288_grf * grf)673 void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
674 {
675 /* pll enter slow-mode */
676 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
677 APLL_MODE_SLOW << APLL_MODE_SHIFT);
678
679 rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
680
681 /* waiting for pll lock */
682 while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK))
683 udelay(1);
684
685 /*
686 * core clock pll source selection and
687 * set up dependent divisors for MPAXI/M0AXI and ARM clocks.
688 * core clock select apll, apll clk = 1800MHz
689 * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz
690 */
691 rk_clrsetreg(&cru->cru_clksel_con[0],
692 CORE_SEL_PLL_MASK | A17_DIV_MASK | MP_DIV_MASK |
693 M0_DIV_MASK,
694 0 << A17_DIV_SHIFT |
695 3 << MP_DIV_SHIFT |
696 1 << M0_DIV_SHIFT);
697
698 /*
699 * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
700 * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
701 */
702 rk_clrsetreg(&cru->cru_clksel_con[37],
703 CLK_L2RAM_DIV_MASK | ATCLK_CORE_DIV_CON_MASK |
704 PCLK_CORE_DBG_DIV_MASK,
705 1 << CLK_L2RAM_DIV_SHIFT |
706 3 << ATCLK_CORE_DIV_CON_SHIFT |
707 3 << PCLK_CORE_DBG_DIV_SHIFT);
708
709 /* PLL enter normal-mode */
710 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
711 APLL_MODE_NORMAL << APLL_MODE_SHIFT);
712 }
713
rockchip_mmc_get_clk(struct rk3288_cru * cru,uint gclk_rate,int periph)714 static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
715 int periph)
716 {
717 uint src_rate;
718 uint div, mux;
719 u32 con;
720
721 switch (periph) {
722 case HCLK_EMMC:
723 case SCLK_EMMC:
724 case SCLK_EMMC_SAMPLE:
725 con = readl(&cru->cru_clksel_con[12]);
726 mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
727 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
728 break;
729 case HCLK_SDMMC:
730 case SCLK_SDMMC:
731 con = readl(&cru->cru_clksel_con[11]);
732 mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
733 div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
734 break;
735 case HCLK_SDIO0:
736 case SCLK_SDIO0:
737 con = readl(&cru->cru_clksel_con[12]);
738 mux = (con & SDIO0_PLL_MASK) >> SDIO0_PLL_SHIFT;
739 div = (con & SDIO0_DIV_MASK) >> SDIO0_DIV_SHIFT;
740 break;
741 default:
742 return -EINVAL;
743 }
744
745 src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : gclk_rate;
746 return DIV_TO_RATE(src_rate, div) / 2;
747 }
748
rockchip_mmc_set_clk(struct rk3288_cru * cru,uint gclk_rate,int periph,uint freq)749 static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
750 int periph, uint freq)
751 {
752 int src_clk_div;
753 int mux;
754
755 debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
756 /* mmc clock default div 2 internal, need provide double in cru */
757 src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq);
758
759 if (src_clk_div > 0x3f) {
760 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
761 assert(src_clk_div < 0x40);
762 mux = EMMC_PLL_SELECT_24MHZ;
763 assert((int)EMMC_PLL_SELECT_24MHZ ==
764 (int)MMC0_PLL_SELECT_24MHZ);
765 } else {
766 mux = EMMC_PLL_SELECT_GENERAL;
767 assert((int)EMMC_PLL_SELECT_GENERAL ==
768 (int)MMC0_PLL_SELECT_GENERAL);
769 }
770 switch (periph) {
771 case HCLK_EMMC:
772 case SCLK_EMMC:
773 rk_clrsetreg(&cru->cru_clksel_con[12],
774 EMMC_PLL_MASK | EMMC_DIV_MASK,
775 mux << EMMC_PLL_SHIFT |
776 (src_clk_div - 1) << EMMC_DIV_SHIFT);
777 break;
778 case HCLK_SDMMC:
779 case SCLK_SDMMC:
780 rk_clrsetreg(&cru->cru_clksel_con[11],
781 MMC0_PLL_MASK | MMC0_DIV_MASK,
782 mux << MMC0_PLL_SHIFT |
783 (src_clk_div - 1) << MMC0_DIV_SHIFT);
784 break;
785 case HCLK_SDIO0:
786 case SCLK_SDIO0:
787 rk_clrsetreg(&cru->cru_clksel_con[12],
788 SDIO0_PLL_MASK | SDIO0_DIV_MASK,
789 mux << SDIO0_PLL_SHIFT |
790 (src_clk_div - 1) << SDIO0_DIV_SHIFT);
791 break;
792 default:
793 return -EINVAL;
794 }
795
796 return rockchip_mmc_get_clk(cru, gclk_rate, periph);
797 }
798
rockchip_spi_get_clk(struct rk3288_cru * cru,uint gclk_rate,int periph)799 static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate,
800 int periph)
801 {
802 uint div, mux;
803 u32 con;
804
805 switch (periph) {
806 case SCLK_SPI0:
807 con = readl(&cru->cru_clksel_con[25]);
808 mux = (con & SPI0_PLL_MASK) >> SPI0_PLL_SHIFT;
809 div = (con & SPI0_DIV_MASK) >> SPI0_DIV_SHIFT;
810 break;
811 case SCLK_SPI1:
812 con = readl(&cru->cru_clksel_con[25]);
813 mux = (con & SPI1_PLL_MASK) >> SPI1_PLL_SHIFT;
814 div = (con & SPI1_DIV_MASK) >> SPI1_DIV_SHIFT;
815 break;
816 case SCLK_SPI2:
817 con = readl(&cru->cru_clksel_con[39]);
818 mux = (con & SPI2_PLL_MASK) >> SPI2_PLL_SHIFT;
819 div = (con & SPI2_DIV_MASK) >> SPI2_DIV_SHIFT;
820 break;
821 default:
822 return -EINVAL;
823 }
824 assert(mux == SPI0_PLL_SELECT_GENERAL);
825
826 return DIV_TO_RATE(gclk_rate, div);
827 }
828
rockchip_spi_set_clk(struct rk3288_cru * cru,uint gclk_rate,int periph,uint freq)829 static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
830 int periph, uint freq)
831 {
832 int src_clk_div;
833
834 debug("%s: clk_general_rate=%u\n", __func__, gclk_rate);
835 src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1;
836 assert(src_clk_div < 128);
837 switch (periph) {
838 case SCLK_SPI0:
839 rk_clrsetreg(&cru->cru_clksel_con[25],
840 SPI0_PLL_MASK | SPI0_DIV_MASK,
841 SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT |
842 src_clk_div << SPI0_DIV_SHIFT);
843 break;
844 case SCLK_SPI1:
845 rk_clrsetreg(&cru->cru_clksel_con[25],
846 SPI1_PLL_MASK | SPI1_DIV_MASK,
847 SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT |
848 src_clk_div << SPI1_DIV_SHIFT);
849 break;
850 case SCLK_SPI2:
851 rk_clrsetreg(&cru->cru_clksel_con[39],
852 SPI2_PLL_MASK | SPI2_DIV_MASK,
853 SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT |
854 src_clk_div << SPI2_DIV_SHIFT);
855 break;
856 default:
857 return -EINVAL;
858 }
859
860 return rockchip_spi_get_clk(cru, gclk_rate, periph);
861 }
862
rockchip_aclk_peri_get_clk(struct rk3288_cru * cru)863 static ulong rockchip_aclk_peri_get_clk(struct rk3288_cru *cru)
864 {
865 uint div, mux;
866 u32 con;
867 ulong rate, parent_rate;
868
869 con = readl(&cru->cru_clksel_con[10]);
870 mux = (con & PERI_SEL_PLL_MASK) >> PERI_SEL_PLL_SHIFT;
871 div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
872 if (mux)
873 parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
874 else
875 parent_rate = rkclk_pll_get_rate(cru, CLK_CODEC);
876 rate = DIV_TO_RATE(parent_rate, div);
877
878 return rate;
879 }
880
rockchip_aclk_cpu_get_clk(struct rk3288_cru * cru)881 static ulong rockchip_aclk_cpu_get_clk(struct rk3288_cru *cru)
882 {
883 uint div, mux;
884 u32 con;
885 ulong rate, parent_rate;
886
887 con = readl(&cru->cru_clksel_con[1]);
888 mux = (con & PD_BUS_SEL_PLL_MASK) >> PD_BUS_SEL_PLL_SHIFT;
889 div = (con & PD_BUS_ACLK_DIV0_MASK) >> PD_BUS_ACLK_DIV0_SHIFT;
890 if (mux)
891 parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
892 else
893 parent_rate = rkclk_pll_get_rate(cru, CLK_CODEC);
894 parent_rate = DIV_TO_RATE(parent_rate, div);
895
896 div = (con & PD_BUS_ACLK_DIV1_MASK) >> PD_BUS_ACLK_DIV1_SHIFT;
897 rate = DIV_TO_RATE(parent_rate, div);
898
899 return rate;
900 }
901
rockchip_pclk_peri_get_clk(struct rk3288_cru * cru)902 static ulong rockchip_pclk_peri_get_clk(struct rk3288_cru *cru)
903 {
904 uint div;
905 u32 con;
906 ulong rate, parent_rate;
907
908 parent_rate = rockchip_aclk_peri_get_clk(cru);
909 con = readl(&cru->cru_clksel_con[10]);
910 div = (con & PERI_PCLK_DIV_MASK) >> PERI_PCLK_DIV_SHIFT;
911 rate = parent_rate / (1 << div);
912
913 return rate;
914 }
915
rockchip_pclk_cpu_get_clk(struct rk3288_cru * cru)916 static ulong rockchip_pclk_cpu_get_clk(struct rk3288_cru *cru)
917 {
918 uint div;
919 u32 con;
920 ulong rate, parent_rate;
921
922 parent_rate = rockchip_aclk_cpu_get_clk(cru);
923 con = readl(&cru->cru_clksel_con[1]);
924 div = (con & PD_BUS_PCLK_DIV_MASK) >> PD_BUS_PCLK_DIV_SHIFT;
925 rate = DIV_TO_RATE(parent_rate, div);
926
927 return rate;
928 }
929
rockchip_i2c_get_clk(struct rk3288_cru * cru,int periph)930 static ulong rockchip_i2c_get_clk(struct rk3288_cru *cru, int periph)
931 {
932 switch (periph) {
933 case PCLK_I2C0:
934 case PCLK_I2C2:
935 return rockchip_pclk_cpu_get_clk(cru);
936 case PCLK_I2C1:
937 case PCLK_I2C3:
938 case PCLK_I2C4:
939 case PCLK_I2C5:
940 return rockchip_pclk_peri_get_clk(cru);
941 default:
942 return -EINVAL;
943 }
944 }
945
rockchip_saradc_get_clk(struct rk3288_cru * cru)946 static ulong rockchip_saradc_get_clk(struct rk3288_cru *cru)
947 {
948 u32 div, val;
949
950 val = readl(&cru->cru_clksel_con[24]);
951 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
952 CLK_SARADC_DIV_CON_WIDTH);
953
954 return DIV_TO_RATE(OSC_HZ, div);
955 }
956
rockchip_saradc_set_clk(struct rk3288_cru * cru,uint hz)957 static ulong rockchip_saradc_set_clk(struct rk3288_cru *cru, uint hz)
958 {
959 int src_clk_div;
960
961 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
962 assert(src_clk_div < 128);
963
964 rk_clrsetreg(&cru->cru_clksel_con[24],
965 CLK_SARADC_DIV_CON_MASK,
966 src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
967
968 return rockchip_saradc_get_clk(cru);
969 }
970
rockchip_tsadc_get_clk(struct rk3288_cru * cru)971 static ulong rockchip_tsadc_get_clk(struct rk3288_cru *cru)
972 {
973 u32 div, val;
974
975 val = readl(&cru->cru_clksel_con[2]);
976 div = bitfield_extract(val, CLK_TSADC_DIV_CON_SHIFT,
977 CLK_TSADC_DIV_CON_WIDTH);
978
979 return DIV_TO_RATE(32768, div);
980 }
981
rockchip_tsadc_set_clk(struct rk3288_cru * cru,uint hz)982 static ulong rockchip_tsadc_set_clk(struct rk3288_cru *cru, uint hz)
983 {
984 int src_clk_div;
985
986 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
987 assert(src_clk_div < 128);
988
989 rk_clrsetreg(&cru->cru_clksel_con[2],
990 CLK_TSADC_DIV_CON_MASK,
991 src_clk_div << CLK_TSADC_DIV_CON_SHIFT);
992
993 return rockchip_tsadc_get_clk(cru);
994 }
995
996 #ifndef CONFIG_SPL_BUILD
997
rockchip_crypto_get_clk(struct rk3288_cru * cru)998 static ulong rockchip_crypto_get_clk(struct rk3288_cru *cru)
999 {
1000 u32 div, val;
1001
1002 val = readl(&cru->cru_clksel_con[26]);
1003 div = (val & CLK_CRYPTO_DIV_CON_MASK) >> CLK_CRYPTO_DIV_CON_SHIFT;
1004
1005 return DIV_TO_RATE(rockchip_aclk_cpu_get_clk(cru), div);
1006 }
1007
rockchip_crypto_set_clk(struct rk3288_cru * cru,uint hz)1008 static ulong rockchip_crypto_set_clk(struct rk3288_cru *cru, uint hz)
1009 {
1010 int src_clk_div;
1011 uint p_rate;
1012
1013 p_rate = rockchip_aclk_cpu_get_clk(cru);
1014 src_clk_div = DIV_ROUND_UP(p_rate, hz) - 1;
1015 assert(src_clk_div < 3);
1016
1017 rk_clrsetreg(&cru->cru_clksel_con[26],
1018 CLK_CRYPTO_DIV_CON_MASK,
1019 src_clk_div << CLK_CRYPTO_DIV_CON_SHIFT);
1020
1021 return rockchip_crypto_get_clk(cru);
1022 }
1023
rk3288_alive_get_clk(struct rk3288_cru * cru,uint gclk_rate)1024 static ulong rk3288_alive_get_clk(struct rk3288_cru *cru, uint gclk_rate)
1025 {
1026 u32 div, con, parent;
1027
1028 con = readl(&cru->cru_clksel_con[33]);
1029 div = (con & PCLK_ALIVE_DIV_CON_MASK) >>
1030 PCLK_ALIVE_DIV_CON_SHIFT;
1031 parent = gclk_rate;
1032 return DIV_TO_RATE(parent, div);
1033 }
1034
rockchip_test_get_clk(struct rk3288_cru * cru,int id)1035 static ulong rockchip_test_get_clk(struct rk3288_cru *cru, int id)
1036 {
1037 u32 src, val;
1038
1039 val = readl(&cru->cru_misc_con);
1040 src = (val & CLK_TEST_SRC_SEL_MASK) >> CLK_TEST_SRC_SEL_SHIFT;
1041 switch (src) {
1042 case CLK_TEST_SRC_SEL_24M:
1043 return 24000000;
1044 case CLK_TEST_SRC_SEL_27M:
1045 return 27000000;
1046 case CLK_TEST_SRC_SEL_32k:
1047 return 32768;
1048 default:
1049 return -ENOENT;
1050 }
1051 }
1052
rockchip_test_set_clk(struct rk3288_cru * cru,int id,uint hz)1053 static ulong rockchip_test_set_clk(struct rk3288_cru *cru, int id, uint hz)
1054 {
1055 int src = 0;
1056
1057 switch (hz) {
1058 case 24000000:
1059 src = 8;
1060 break;
1061 case 27000000:
1062 src = 9;
1063 break;
1064 case 32768:
1065 src = 10;
1066 break;
1067 default:
1068 return -EINVAL;
1069 }
1070 rk_clrsetreg(&cru->cru_misc_con,
1071 CLK_TEST_SRC_SEL_MASK,
1072 src << CLK_TEST_SRC_SEL_SHIFT);
1073
1074 return rockchip_test_get_clk(cru, id);
1075 }
1076 #endif
1077
rk3288_clk_get_rate(struct clk * clk)1078 static ulong rk3288_clk_get_rate(struct clk *clk)
1079 {
1080 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1081 ulong new_rate, gclk_rate;
1082
1083 gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
1084 switch (clk->id) {
1085 case 0 ... 63:
1086 new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
1087 break;
1088 case HCLK_EMMC:
1089 case HCLK_SDMMC:
1090 case HCLK_SDIO0:
1091 case SCLK_EMMC:
1092 case SCLK_EMMC_SAMPLE:
1093 case SCLK_SDMMC:
1094 case SCLK_SDMMC_SAMPLE:
1095 case SCLK_SDIO0:
1096 new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
1097 break;
1098 case SCLK_SPI0:
1099 case SCLK_SPI1:
1100 case SCLK_SPI2:
1101 new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, clk->id);
1102 break;
1103 case PCLK_I2C0:
1104 case PCLK_I2C1:
1105 case PCLK_I2C2:
1106 case PCLK_I2C3:
1107 case PCLK_I2C4:
1108 case PCLK_I2C5:
1109 new_rate = rockchip_i2c_get_clk(priv->cru, clk->id);
1110 break;
1111 case PCLK_PWM:
1112 case PCLK_RKPWM:
1113 return PD_BUS_PCLK_HZ;
1114 case SCLK_SARADC:
1115 new_rate = rockchip_saradc_get_clk(priv->cru);
1116 break;
1117 case SCLK_TSADC:
1118 new_rate = rockchip_tsadc_get_clk(priv->cru);
1119 break;
1120 case ACLK_CPU:
1121 new_rate = rockchip_aclk_cpu_get_clk(priv->cru);
1122 break;
1123 case ACLK_PERI:
1124 new_rate = rockchip_aclk_peri_get_clk(priv->cru);
1125 break;
1126 case PCLK_CPU:
1127 new_rate = rockchip_pclk_cpu_get_clk(priv->cru);
1128 break;
1129 case PCLK_PERI:
1130 new_rate = rockchip_pclk_peri_get_clk(priv->cru);
1131 break;
1132 #ifndef CONFIG_SPL_BUILD
1133 case SCLK_CRYPTO:
1134 new_rate = rockchip_crypto_get_clk(priv->cru);
1135 break;
1136 case PCLK_WDT:
1137 new_rate = rk3288_alive_get_clk(priv->cru, gclk_rate);
1138 break;
1139 case SCLK_TESTOUT_SRC:
1140 case SCLK_TESTOUT:
1141 new_rate = rockchip_test_get_clk(priv->cru, clk->id);
1142 break;
1143 #endif
1144 default:
1145 return -ENOENT;
1146 }
1147
1148 return new_rate;
1149 }
1150
rk3288_clk_set_rate(struct clk * clk,ulong rate)1151 static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
1152 {
1153 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1154 struct rk3288_cru *cru = priv->cru;
1155 ulong new_rate, gclk_rate;
1156
1157 gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
1158 switch (clk->id) {
1159 case PLL_APLL:
1160 /* We only support a fixed rate here */
1161 if (rate != 1800000000)
1162 return -EINVAL;
1163 rk3288_clk_configure_cpu(priv->cru, priv->grf);
1164 new_rate = rate;
1165 break;
1166 case CLK_DDR:
1167 new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate);
1168 break;
1169 case HCLK_EMMC:
1170 case HCLK_SDMMC:
1171 case HCLK_SDIO0:
1172 case SCLK_EMMC:
1173 case SCLK_SDMMC:
1174 case SCLK_SDIO0:
1175 new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate);
1176 break;
1177 case SCLK_SPI0:
1178 case SCLK_SPI1:
1179 case SCLK_SPI2:
1180 new_rate = rockchip_spi_set_clk(cru, gclk_rate, clk->id, rate);
1181 break;
1182 #ifndef CONFIG_SPL_BUILD
1183 case SCLK_MAC:
1184 new_rate = rockchip_mac_set_clk(priv->cru, rate);
1185 break;
1186 case DCLK_VOP0:
1187 case DCLK_VOP1:
1188 case ACLK_VIO0:
1189 case ACLK_VIO1:
1190 new_rate = rockchip_vop_set_clk(cru, priv->grf, clk->id, rate);
1191 break;
1192 case SCLK_EDP_24M:
1193 /* clk_edp_24M source: 24M */
1194 rk_setreg(&cru->cru_clksel_con[28], 1 << 15);
1195
1196 /* rst edp */
1197 rk_setreg(&cru->cru_clksel_con[6], 1 << 15);
1198 udelay(1);
1199 rk_clrreg(&cru->cru_clksel_con[6], 1 << 15);
1200 new_rate = rate;
1201 break;
1202 case PCLK_HDMI_CTRL:
1203 /* enable pclk hdmi ctrl */
1204 rk_clrreg(&cru->cru_clkgate_con[16], 1 << 9);
1205
1206 /* software reset hdmi */
1207 rk_setreg(&cru->cru_clkgate_con[7], 1 << 9);
1208 udelay(1);
1209 rk_clrreg(&cru->cru_clkgate_con[7], 1 << 9);
1210 new_rate = rate;
1211 break;
1212 case SCLK_CRYPTO:
1213 new_rate = rockchip_crypto_set_clk(priv->cru, rate);
1214 break;
1215 case SCLK_TESTOUT_SRC:
1216 case SCLK_TESTOUT:
1217 new_rate = rockchip_test_set_clk(priv->cru, clk->id, rate);
1218 break;
1219 #endif
1220 case SCLK_SARADC:
1221 new_rate = rockchip_saradc_set_clk(priv->cru, rate);
1222 break;
1223 case SCLK_TSADC:
1224 new_rate = rockchip_tsadc_set_clk(priv->cru, rate);
1225 break;
1226 case PLL_GPLL:
1227 case PLL_CPLL:
1228 case PLL_NPLL:
1229 case ACLK_CPU:
1230 case HCLK_CPU:
1231 case PCLK_CPU:
1232 case ACLK_PERI:
1233 case HCLK_PERI:
1234 case PCLK_PERI:
1235 case SCLK_UART0:
1236 return 0;
1237 default:
1238 return -ENOENT;
1239 }
1240
1241 return new_rate;
1242 }
1243
1244 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1245 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1246 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1247 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1248
1249 #define PSECS_PER_SEC 1000000000000LL
1250 /*
1251 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1252 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1253 */
1254 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1255
rockchip_mmc_get_phase(struct clk * clk)1256 int rockchip_mmc_get_phase(struct clk *clk)
1257 {
1258 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1259 struct rk3288_cru *cru = priv->cru;
1260 u32 raw_value, delay_num;
1261 u16 degrees = 0;
1262 ulong rate;
1263
1264 rate = rk3288_clk_get_rate(clk);
1265
1266 if (rate < 0)
1267 return rate;
1268
1269 if (clk->id == SCLK_EMMC_SAMPLE)
1270 raw_value = readl(&cru->cru_emmc_con[1]);
1271 else
1272 raw_value = readl(&cru->cru_sdmmc_con[1]);
1273
1274 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1275
1276 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1277 /* degrees/delaynum * 10000 */
1278 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1279 36 * (rate / 1000000);
1280
1281 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1282 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1283 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1284 }
1285
1286 return degrees % 360;
1287 }
1288
rockchip_mmc_set_phase(struct clk * clk,u32 degrees)1289 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees)
1290 {
1291 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1292 struct rk3288_cru *cru = priv->cru;
1293 u8 nineties, remainder, delay_num;
1294 u32 raw_value, delay;
1295 ulong rate;
1296
1297 rate = rk3288_clk_get_rate(clk);
1298
1299 if (rate < 0)
1300 return rate;
1301
1302 nineties = degrees / 90;
1303 remainder = (degrees % 90);
1304
1305 /*
1306 * Convert to delay; do a little extra work to make sure we
1307 * don't overflow 32-bit / 64-bit numbers.
1308 */
1309 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1310 delay *= remainder;
1311 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1312 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1313
1314 delay_num = (u8)min_t(u32, delay, 255);
1315
1316 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1317 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1318 raw_value |= nineties;
1319
1320 if (clk->id == SCLK_EMMC_SAMPLE)
1321 writel(raw_value | 0xffff0000, &cru->cru_emmc_con[1]);
1322 else
1323 writel(raw_value | 0xffff0000, &cru->cru_sdmmc_con[1]);
1324
1325 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1326 degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk));
1327
1328 return 0;
1329 }
1330
rk3288_clk_get_phase(struct clk * clk)1331 static int rk3288_clk_get_phase(struct clk *clk)
1332 {
1333 int ret;
1334
1335 switch (clk->id) {
1336 case SCLK_EMMC_SAMPLE:
1337 case SCLK_SDMMC_SAMPLE:
1338 ret = rockchip_mmc_get_phase(clk);
1339 break;
1340 default:
1341 return -ENOENT;
1342 }
1343
1344 return ret;
1345 }
1346
rk3288_clk_set_phase(struct clk * clk,int degrees)1347 static int rk3288_clk_set_phase(struct clk *clk, int degrees)
1348 {
1349 int ret;
1350
1351 switch (clk->id) {
1352 case SCLK_EMMC_SAMPLE:
1353 case SCLK_SDMMC_SAMPLE:
1354 ret = rockchip_mmc_set_phase(clk, degrees);
1355 break;
1356 default:
1357 return -ENOENT;
1358 }
1359
1360 return ret;
1361 }
1362
rk3288_gmac_set_parent(struct clk * clk,struct clk * parent)1363 static int __maybe_unused rk3288_gmac_set_parent(struct clk *clk, struct clk *parent)
1364 {
1365 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1366 struct rk3288_cru *cru = priv->cru;
1367 const char *clock_output_name;
1368 int ret;
1369
1370 /*
1371 * If the requested parent is in the same clock-controller and
1372 * the id is SCLK_MAC_PLL ("mac_pll_src"), switch to the internal
1373 * clock.
1374 */
1375 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC_PLL)) {
1376 debug("%s: switching GAMC to SCLK_MAC_PLL\n", __func__);
1377 rk_clrsetreg(&cru->cru_clksel_con[21], RMII_EXTCLK_MASK, 0);
1378 return 0;
1379 }
1380
1381 /*
1382 * Otherwise, we need to check the clock-output-names of the
1383 * requested parent to see if the requested id is "ext_gmac".
1384 */
1385 ret = dev_read_string_index(parent->dev, "clock-output-names",
1386 parent->id, &clock_output_name);
1387 if (ret < 0)
1388 return -ENODATA;
1389
1390 /* If this is "ext_gmac", switch to the external clock input */
1391 if (!strcmp(clock_output_name, "ext_gmac")) {
1392 debug("%s: switching GMAC to external clock\n", __func__);
1393 rk_clrsetreg(&cru->cru_clksel_con[21], RMII_EXTCLK_MASK,
1394 RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT);
1395 return 0;
1396 }
1397
1398 return -EINVAL;
1399 }
1400
rk3288_vop_set_parent(struct clk * clk,struct clk * parent)1401 static int __maybe_unused rk3288_vop_set_parent(struct clk *clk,
1402 struct clk *parent)
1403 {
1404 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
1405 struct rk3288_cru *cru = priv->cru;
1406 int parent_sel;
1407
1408 switch (parent->id) {
1409 case PLL_CPLL:
1410 parent_sel = 0;
1411 break;
1412 case PLL_GPLL:
1413 parent_sel = 1;
1414 break;
1415 case PLL_NPLL:
1416 parent_sel = 2;
1417 break;
1418 default:
1419 parent_sel = 0;
1420 break;
1421 }
1422
1423 switch (clk->id) {
1424 case DCLK_VOP0:
1425 rk_clrsetreg(&cru->cru_clksel_con[27],
1426 DCLK_VOP0_PLL_MASK, parent_sel << 0);
1427 break;
1428 case DCLK_VOP1:
1429 rk_clrsetreg(&cru->cru_clksel_con[29],
1430 DCLK_VOP1_PLL_MASK, parent_sel << 6);
1431 break;
1432 default:
1433 return -EINVAL;
1434 }
1435
1436 return 0;
1437 }
1438
rk3288_clk_set_parent(struct clk * clk,struct clk * parent)1439 static int __maybe_unused rk3288_clk_set_parent(struct clk *clk, struct clk *parent)
1440 {
1441 switch (clk->id) {
1442 case SCLK_MAC:
1443 return rk3288_gmac_set_parent(clk, parent);
1444 case DCLK_VOP0:
1445 case DCLK_VOP1:
1446 return rk3288_vop_set_parent(clk, parent);
1447 case SCLK_USBPHY480M_SRC:
1448 return 0;
1449 }
1450
1451 debug("%s: unsupported clk %ld\n", __func__, clk->id);
1452 return -ENOENT;
1453 }
1454
1455 static struct clk_ops rk3288_clk_ops = {
1456 .get_rate = rk3288_clk_get_rate,
1457 .set_rate = rk3288_clk_set_rate,
1458 .get_phase = rk3288_clk_get_phase,
1459 .set_phase = rk3288_clk_set_phase,
1460 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1461 .set_parent = rk3288_clk_set_parent,
1462 #endif
1463 };
1464
rk3288_clk_ofdata_to_platdata(struct udevice * dev)1465 static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
1466 {
1467 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
1468 struct rk3288_clk_priv *priv = dev_get_priv(dev);
1469
1470 priv->cru = dev_read_addr_ptr(dev);
1471 #endif
1472
1473 return 0;
1474 }
1475
rk3288_clk_probe(struct udevice * dev)1476 static int rk3288_clk_probe(struct udevice *dev)
1477 {
1478 struct rk3288_clk_priv *priv = dev_get_priv(dev);
1479 bool init_clocks = false;
1480 int ret;
1481
1482 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1483 if (IS_ERR(priv->grf))
1484 return PTR_ERR(priv->grf);
1485 #ifdef CONFIG_SPL_BUILD
1486 #if CONFIG_IS_ENABLED(OF_PLATDATA)
1487 struct rk3288_clk_plat *plat = dev_get_platdata(dev);
1488
1489 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
1490 #endif
1491 init_clocks = true;
1492 #endif
1493 if (!(gd->flags & GD_FLG_RELOC)) {
1494 u32 reg;
1495
1496 /*
1497 * Init clocks in U-Boot proper if the NPLL is runnning. This
1498 * indicates that a previous boot loader set up the clocks, so
1499 * we need to redo it. U-Boot's SPL does not set this clock.
1500 * Or if the CPLL is not init, we need to redo the clk_init.
1501 */
1502 reg = readl(&priv->cru->cru_mode_con);
1503 if ((((reg & NPLL_MODE_MASK) >> NPLL_MODE_SHIFT) ==
1504 NPLL_MODE_NORMAL) ||
1505 !(reg & CPLL_MODE_MASK))
1506 init_clocks = true;
1507 }
1508
1509 priv->sync_kernel = false;
1510 if (!priv->armclk_enter_hz)
1511 priv->armclk_enter_hz = rkclk_pll_get_rate(priv->cru,
1512 CLK_ARM);
1513
1514 if (init_clocks) {
1515 rkclk_init(priv->cru, priv->grf);
1516 if (!priv->armclk_init_hz)
1517 priv->armclk_init_hz = rkclk_pll_get_rate(priv->cru,
1518 CLK_ARM);
1519 } else {
1520 if (!priv->armclk_init_hz)
1521 priv->armclk_init_hz = priv->armclk_enter_hz;
1522 }
1523
1524 ret = clk_set_defaults(dev);
1525 if (ret)
1526 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1527 else
1528 priv->sync_kernel = true;
1529
1530 return 0;
1531 }
1532
rk3288_clk_bind(struct udevice * dev)1533 static int rk3288_clk_bind(struct udevice *dev)
1534 {
1535 int ret;
1536 struct udevice *sys_child, *sf_child;
1537 struct sysreset_reg *priv;
1538 struct softreset_reg *sf_priv;
1539
1540 /* The reset driver does not have a device node, so bind it here */
1541 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1542 &sys_child);
1543 if (ret) {
1544 debug("Warning: No sysreset driver: ret=%d\n", ret);
1545 } else {
1546 priv = malloc(sizeof(struct sysreset_reg));
1547 priv->glb_srst_fst_value = offsetof(struct rk3288_cru,
1548 cru_glb_srst_fst_value);
1549 priv->glb_srst_snd_value = offsetof(struct rk3288_cru,
1550 cru_glb_srst_snd_value);
1551 sys_child->priv = priv;
1552 }
1553
1554 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1555 dev_ofnode(dev), &sf_child);
1556 if (ret) {
1557 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1558 } else {
1559 sf_priv = malloc(sizeof(struct softreset_reg));
1560 sf_priv->sf_reset_offset = offsetof(struct rk3288_cru,
1561 cru_softrst_con[0]);
1562 sf_priv->sf_reset_num = 12;
1563 sf_child->priv = sf_priv;
1564 }
1565
1566 return 0;
1567 }
1568
1569 static const struct udevice_id rk3288_clk_ids[] = {
1570 { .compatible = "rockchip,rk3288-cru" },
1571 { }
1572 };
1573
1574 U_BOOT_DRIVER(rockchip_rk3288_cru) = {
1575 .name = "rockchip_rk3288_cru",
1576 .id = UCLASS_CLK,
1577 .of_match = rk3288_clk_ids,
1578 .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
1579 .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
1580 .ops = &rk3288_clk_ops,
1581 .bind = rk3288_clk_bind,
1582 .ofdata_to_platdata = rk3288_clk_ofdata_to_platdata,
1583 .probe = rk3288_clk_probe,
1584 };
1585
1586 #ifndef CONFIG_SPL_BUILD
1587 /**
1588 * soc_clk_dump() - Print clock frequencies
1589 * Returns zero on success
1590 *
1591 * Implementation for the clk dump command.
1592 */
soc_clk_dump(void)1593 int soc_clk_dump(void)
1594 {
1595 struct udevice *cru_dev;
1596 struct rk3288_clk_priv *priv;
1597 const struct rk3288_clk_info *clk_dump;
1598 struct clk clk;
1599 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1600 unsigned long rate;
1601 int i, ret;
1602
1603 ret = uclass_get_device_by_driver(UCLASS_CLK,
1604 DM_GET_DRIVER(rockchip_rk3288_cru),
1605 &cru_dev);
1606 if (ret) {
1607 printf("%s failed to get cru device\n", __func__);
1608 return ret;
1609 }
1610
1611 priv = dev_get_priv(cru_dev);
1612 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1613 priv->sync_kernel ? "sync kernel" : "uboot",
1614 priv->armclk_enter_hz / 1000,
1615 priv->armclk_init_hz / 1000,
1616 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1617 priv->set_armclk_rate ? " KHz" : "N/A");
1618 for (i = 0; i < clk_count; i++) {
1619 clk_dump = &clks_dump[i];
1620 if (clk_dump->name) {
1621 clk.id = clk_dump->id;
1622 if (clk_dump->is_cru)
1623 ret = clk_request(cru_dev, &clk);
1624 if (ret < 0)
1625 return ret;
1626
1627 rate = clk_get_rate(&clk);
1628 clk_free(&clk);
1629 if (i == 0) {
1630 if (rate < 0)
1631 printf(" %s %s\n", clk_dump->name,
1632 "unknown");
1633 else
1634 printf(" %s %lu KHz\n", clk_dump->name,
1635 rate / 1000);
1636 } else {
1637 if (rate < 0)
1638 printf(" %s %s\n", clk_dump->name,
1639 "unknown");
1640 else
1641 printf(" %s %lu KHz\n", clk_dump->name,
1642 rate / 1000);
1643 }
1644 }
1645 }
1646
1647 return 0;
1648 }
1649 #endif
1650
1651