1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <bitfield.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <syscon.h>
12 #include <clk.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk1808.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rk1808-cru.h>
19 #include <div64.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 #define RK1808_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
24 { \
25 .rate = _rate##U, \
26 .aclk_div = _aclk_div, \
27 .pclk_div = _pclk_div, \
28 }
29
30 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
31
32 static struct rockchip_pll_rate_table rk1808_pll_rates[] = {
33 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
34 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
35 RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
36 RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
37 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
38 RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
39 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
40 RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
41 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
42 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
43 RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
44 RK3036_PLL_RATE(200000000, 1, 200, 6, 4, 1, 0),
45 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
46 { /* sentinel */ },
47 };
48
49 #ifndef CONFIG_SPL_BUILD
50 #define RK1808_CLK_DUMP(_id, _name, _iscru) \
51 { \
52 .id = _id, \
53 .name = _name, \
54 .is_cru = _iscru, \
55 }
56
57 static const struct rk1808_clk_info clks_dump[] = {
58 RK1808_CLK_DUMP(PLL_APLL, "apll", true),
59 RK1808_CLK_DUMP(PLL_DPLL, "dpll", true),
60 RK1808_CLK_DUMP(PLL_CPLL, "cpll", true),
61 RK1808_CLK_DUMP(PLL_GPLL, "gpll", true),
62 RK1808_CLK_DUMP(PLL_NPLL, "npll", true),
63 RK1808_CLK_DUMP(PLL_PPLL, "ppll", true),
64 RK1808_CLK_DUMP(HSCLK_BUS_PRE, "hsclk_bus", true),
65 RK1808_CLK_DUMP(MSCLK_BUS_PRE, "msclk_bus", true),
66 RK1808_CLK_DUMP(LSCLK_BUS_PRE, "lsclk_bus", true),
67 RK1808_CLK_DUMP(MSCLK_PERI, "msclk_peri", true),
68 RK1808_CLK_DUMP(LSCLK_PERI, "lsclk_peri", true),
69 };
70 #endif
71
72 static struct rockchip_cpu_rate_table rk1808_cpu_rates[] = {
73 RK1808_CPUCLK_RATE(1200000000, 1, 5),
74 RK1808_CPUCLK_RATE(1008000000, 1, 5),
75 RK1808_CPUCLK_RATE(816000000, 1, 3),
76 RK1808_CPUCLK_RATE(600000000, 1, 3),
77 };
78
79 static struct rockchip_pll_clock rk1808_pll_clks[] = {
80 [APLL] = PLL(pll_rk3036, PLL_APLL, RK1808_PLL_CON(0),
81 RK1808_MODE_CON, 0, 10, 0, rk1808_pll_rates),
82 [DPLL] = PLL(pll_rk3036, PLL_DPLL, RK1808_PLL_CON(8),
83 RK1808_MODE_CON, 2, 10, 0, NULL),
84 [CPLL] = PLL(pll_rk3036, PLL_CPLL, RK1808_PLL_CON(16),
85 RK1808_MODE_CON, 4, 10, 0, rk1808_pll_rates),
86 [GPLL] = PLL(pll_rk3036, PLL_GPLL, RK1808_PLL_CON(24),
87 RK1808_MODE_CON, 6, 10, 0, rk1808_pll_rates),
88 [NPLL] = PLL(pll_rk3036, PLL_NPLL, RK1808_PLL_CON(32),
89 RK1808_MODE_CON, 8, 10, 0, rk1808_pll_rates),
90 [PPLL] = PLL(pll_rk3036, PLL_PPLL, RK1808_PMU_PLL_CON(0),
91 RK1808_PMU_MODE_CON, 0, 10, 0, rk1808_pll_rates),
92 };
93
94 #ifndef CONFIG_SPL_BUILD
rk1808_i2c_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)95 static ulong rk1808_i2c_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
96 {
97 struct rk1808_cru *cru = priv->cru;
98 u32 div, con;
99
100 switch (clk_id) {
101 case SCLK_PMU_I2C0:
102 con = readl(&cru->pmu_clksel_con[7]);
103 div = (con & CLK_I2C0_DIV_CON_MASK) >> CLK_I2C0_DIV_CON_SHIFT;
104 break;
105 case SCLK_I2C1:
106 con = readl(&cru->clksel_con[59]);
107 div = (con & CLK_I2C1_DIV_CON_MASK) >> CLK_I2C1_DIV_CON_SHIFT;
108 break;
109 case SCLK_I2C2:
110 con = readl(&cru->clksel_con[59]);
111 div = (con & CLK_I2C2_DIV_CON_MASK) >> CLK_I2C2_DIV_CON_SHIFT;
112 break;
113 case SCLK_I2C3:
114 con = readl(&cru->clksel_con[60]);
115 div = (con & CLK_I2C3_DIV_CON_MASK) >> CLK_I2C3_DIV_CON_SHIFT;
116 break;
117 case SCLK_I2C4:
118 con = readl(&cru->clksel_con[71]);
119 div = (con & CLK_I2C4_DIV_CON_MASK) >> CLK_I2C4_DIV_CON_SHIFT;
120 break;
121 case SCLK_I2C5:
122 con = readl(&cru->clksel_con[71]);
123 div = (con & CLK_I2C5_DIV_CON_MASK) >> CLK_I2C5_DIV_CON_SHIFT;
124 break;
125 default:
126 printf("do not support this i2c bus\n");
127 return -EINVAL;
128 }
129
130 return DIV_TO_RATE(priv->gpll_hz, div);
131 }
132
rk1808_i2c_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,uint hz)133 static ulong rk1808_i2c_set_clk(struct rk1808_clk_priv *priv,
134 ulong clk_id, uint hz)
135 {
136 struct rk1808_cru *cru = priv->cru;
137 int src_clk_div;
138
139 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
140 assert(src_clk_div - 1 < 127);
141
142 switch (clk_id) {
143 case SCLK_PMU_I2C0:
144 rk_clrsetreg(&cru->pmu_clksel_con[7],
145 CLK_I2C0_DIV_CON_MASK | CLK_I2C0_PLL_SEL_MASK,
146 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
147 CLK_I2C0_PLL_SEL_PPLL << CLK_I2C0_PLL_SEL_SHIFT);
148 break;
149 case SCLK_I2C1:
150 rk_clrsetreg(&cru->clksel_con[59],
151 CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
152 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
153 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
154 break;
155 case SCLK_I2C2:
156 rk_clrsetreg(&cru->clksel_con[59],
157 CLK_I2C2_DIV_CON_MASK | CLK_I2C2_PLL_SEL_MASK,
158 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
159 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
160 break;
161 case SCLK_I2C3:
162 rk_clrsetreg(&cru->clksel_con[60],
163 CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
164 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
165 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
166 break;
167 case SCLK_I2C4:
168 rk_clrsetreg(&cru->clksel_con[71],
169 CLK_I2C4_DIV_CON_MASK | CLK_I2C4_PLL_SEL_MASK,
170 (src_clk_div - 1) << CLK_I2C4_DIV_CON_SHIFT |
171 CLK_I2C_PLL_SEL_GPLL << CLK_I2C4_PLL_SEL_SHIFT);
172 break;
173 case SCLK_I2C5:
174 rk_clrsetreg(&cru->clksel_con[71],
175 CLK_I2C5_DIV_CON_MASK | CLK_I2C5_PLL_SEL_MASK,
176 (src_clk_div - 1) << CLK_I2C5_DIV_CON_SHIFT |
177 CLK_I2C_PLL_SEL_GPLL << CLK_I2C5_PLL_SEL_SHIFT);
178 break;
179 default:
180 printf("do not support this i2c bus\n");
181 return -EINVAL;
182 }
183
184 return rk1808_i2c_get_clk(priv, clk_id);
185 }
186 #endif
187
rk1808_mmc_get_clk(struct rk1808_clk_priv * priv,uint clk_id)188 static ulong rk1808_mmc_get_clk(struct rk1808_clk_priv *priv, uint clk_id)
189 {
190 struct rk1808_cru *cru = priv->cru;
191 u32 div, con, con_id;
192
193 switch (clk_id) {
194 case HCLK_SDMMC:
195 case SCLK_SDMMC:
196 con_id = 20;
197 break;
198 case HCLK_SDIO:
199 case SCLK_SDIO:
200 con_id = 22;
201 break;
202 case HCLK_EMMC:
203 case SCLK_EMMC:
204 case SCLK_EMMC_SAMPLE:
205 con_id = 24;
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 con = readl(&cru->clksel_con[con_id]);
212 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
213
214 if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
215 == EMMC_SEL_24M)
216 return DIV_TO_RATE(OSC_HZ, div) / 2;
217 else
218 return DIV_TO_RATE(priv->gpll_hz, div) / 2;
219 }
220
rk1808_mmc_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong set_rate)221 static ulong rk1808_mmc_set_clk(struct rk1808_clk_priv *priv,
222 ulong clk_id, ulong set_rate)
223 {
224 struct rk1808_cru *cru = priv->cru;
225 int src_clk_div;
226 u32 con_id;
227
228 switch (clk_id) {
229 case HCLK_SDMMC:
230 case SCLK_SDMMC:
231 con_id = 20;
232 break;
233 case HCLK_SDIO:
234 case SCLK_SDIO:
235 con_id = 22;
236 break;
237 case HCLK_EMMC:
238 case SCLK_EMMC:
239 con_id = 24;
240 break;
241 default:
242 return -EINVAL;
243 }
244
245 /* Select clk_sdmmc/emmc source from GPLL by default */
246 /* mmc clock defaulg div 2 internal, need provide double in cru */
247 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
248
249 if (src_clk_div > 127) {
250 /* use 24MHz source for 400KHz clock */
251 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
252 rk_clrsetreg(&cru->clksel_con[con_id],
253 EMMC_PLL_MASK | EMMC_DIV_MASK,
254 EMMC_SEL_24M << EMMC_PLL_SHIFT |
255 (src_clk_div - 1) << EMMC_DIV_SHIFT);
256 } else {
257 rk_clrsetreg(&cru->clksel_con[con_id],
258 EMMC_PLL_MASK | EMMC_DIV_MASK,
259 EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
260 (src_clk_div - 1) << EMMC_DIV_SHIFT);
261 }
262 rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK,
263 EMMC_CLK_SEL_EMMC);
264
265 return rk1808_mmc_get_clk(priv, clk_id);
266 }
267
rk1808_sfc_get_clk(struct rk1808_clk_priv * priv,uint clk_id)268 static ulong rk1808_sfc_get_clk(struct rk1808_clk_priv *priv, uint clk_id)
269 {
270 struct rk1808_cru *cru = priv->cru;
271 u32 div, con;
272
273 con = readl(&cru->clksel_con[26]);
274 div = (con & SFC_DIV_CON_MASK) >> SFC_DIV_CON_SHIFT;
275
276 return DIV_TO_RATE(priv->gpll_hz, div);
277 }
278
rk1808_sfc_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong set_rate)279 static ulong rk1808_sfc_set_clk(struct rk1808_clk_priv *priv,
280 ulong clk_id, ulong set_rate)
281 {
282 struct rk1808_cru *cru = priv->cru;
283 int src_clk_div;
284
285 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
286 rk_clrsetreg(&cru->clksel_con[26],
287 SFC_PLL_SEL_MASK | SFC_DIV_CON_MASK,
288 0 << SFC_PLL_SEL_SHIFT |
289 (src_clk_div - 1) << SFC_DIV_CON_SHIFT);
290
291 return rk1808_sfc_get_clk(priv, clk_id);
292 }
293
rk1808_saradc_get_clk(struct rk1808_clk_priv * priv)294 static ulong rk1808_saradc_get_clk(struct rk1808_clk_priv *priv)
295 {
296 struct rk1808_cru *cru = priv->cru;
297 u32 div, con;
298
299 con = readl(&cru->clksel_con[63]);
300 div = con & CLK_SARADC_DIV_CON_MASK;
301
302 return DIV_TO_RATE(OSC_HZ, div);
303 }
304
rk1808_saradc_set_clk(struct rk1808_clk_priv * priv,uint hz)305 static ulong rk1808_saradc_set_clk(struct rk1808_clk_priv *priv, uint hz)
306 {
307 struct rk1808_cru *cru = priv->cru;
308 int src_clk_div;
309
310 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
311 assert(src_clk_div - 1 < 2047);
312
313 rk_clrsetreg(&cru->clksel_con[63],
314 CLK_SARADC_DIV_CON_MASK,
315 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
316
317 return rk1808_saradc_get_clk(priv);
318 }
319
320 #ifndef CONFIG_SPL_BUILD
rk1808_pwm_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)321 static ulong rk1808_pwm_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
322 {
323 struct rk1808_cru *cru = priv->cru;
324 u32 div, con;
325
326 switch (clk_id) {
327 case SCLK_PWM0:
328 con = readl(&cru->clksel_con[69]);
329 div = (con & CLK_PWM0_DIV_CON_MASK) >> CLK_PWM0_DIV_CON_SHIFT;
330 break;
331 case SCLK_PWM1:
332 con = readl(&cru->clksel_con[69]);
333 div = (con & CLK_PWM1_DIV_CON_MASK) >> CLK_PWM1_DIV_CON_SHIFT;
334 break;
335 case SCLK_PWM2:
336 con = readl(&cru->clksel_con[70]);
337 div = (con & CLK_PWM2_DIV_CON_MASK) >> CLK_PWM2_DIV_CON_SHIFT;
338 break;
339 default:
340 printf("do not support this pwm bus\n");
341 return -EINVAL;
342 }
343
344 return DIV_TO_RATE(priv->gpll_hz, div);
345 }
346
rk1808_pwm_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,uint hz)347 static ulong rk1808_pwm_set_clk(struct rk1808_clk_priv *priv,
348 ulong clk_id, uint hz)
349 {
350 struct rk1808_cru *cru = priv->cru;
351 int src_clk_div;
352
353 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
354 assert(src_clk_div - 1 < 127);
355
356 switch (clk_id) {
357 case SCLK_PWM0:
358 rk_clrsetreg(&cru->clksel_con[69],
359 CLK_PWM0_DIV_CON_MASK | CLK_PWM0_PLL_SEL_MASK,
360 (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
361 CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
362 break;
363 case SCLK_PWM1:
364 rk_clrsetreg(&cru->clksel_con[69],
365 CLK_PWM1_DIV_CON_MASK | CLK_PWM1_PLL_SEL_MASK,
366 (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
367 CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
368 break;
369 case SCLK_PWM2:
370 rk_clrsetreg(&cru->clksel_con[70],
371 CLK_PWM2_DIV_CON_MASK | CLK_PWM2_PLL_SEL_MASK,
372 (src_clk_div - 1) << CLK_PWM2_DIV_CON_SHIFT |
373 CLK_PWM_PLL_SEL_GPLL << CLK_PWM2_PLL_SEL_SHIFT);
374 break;
375 default:
376 printf("do not support this pwm bus\n");
377 return -EINVAL;
378 }
379
380 return rk1808_pwm_get_clk(priv, clk_id);
381 }
382
rk1808_tsadc_get_clk(struct rk1808_clk_priv * priv)383 static ulong rk1808_tsadc_get_clk(struct rk1808_clk_priv *priv)
384 {
385 struct rk1808_cru *cru = priv->cru;
386 u32 div, con;
387
388 con = readl(&cru->clksel_con[62]);
389 div = con & CLK_SARADC_DIV_CON_MASK;
390
391 return DIV_TO_RATE(OSC_HZ, div);
392 }
393
rk1808_tsadc_set_clk(struct rk1808_clk_priv * priv,uint hz)394 static ulong rk1808_tsadc_set_clk(struct rk1808_clk_priv *priv, uint hz)
395 {
396 struct rk1808_cru *cru = priv->cru;
397 int src_clk_div;
398
399 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
400 assert(src_clk_div - 1 < 2047);
401
402 rk_clrsetreg(&cru->clksel_con[62],
403 CLK_SARADC_DIV_CON_MASK,
404 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
405
406 return rk1808_tsadc_get_clk(priv);
407 }
408
rk1808_spi_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)409 static ulong rk1808_spi_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
410 {
411 struct rk1808_cru *cru = priv->cru;
412 u32 div, con;
413
414 switch (clk_id) {
415 case SCLK_SPI0:
416 con = readl(&cru->clksel_con[60]);
417 div = (con & CLK_SPI0_DIV_CON_MASK) >> CLK_SPI0_DIV_CON_SHIFT;
418 break;
419 case SCLK_SPI1:
420 con = readl(&cru->clksel_con[61]);
421 div = (con & CLK_SPI1_DIV_CON_MASK) >> CLK_SPI1_DIV_CON_SHIFT;
422 break;
423 case SCLK_SPI2:
424 con = readl(&cru->clksel_con[61]);
425 div = (con & CLK_SPI2_DIV_CON_MASK) >> CLK_SPI2_DIV_CON_SHIFT;
426 break;
427 default:
428 printf("do not support this pwm bus\n");
429 return -EINVAL;
430 }
431
432 return DIV_TO_RATE(priv->gpll_hz, div);
433 }
434
rk1808_spi_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,uint hz)435 static ulong rk1808_spi_set_clk(struct rk1808_clk_priv *priv,
436 ulong clk_id, uint hz)
437 {
438 struct rk1808_cru *cru = priv->cru;
439 int src_clk_div;
440
441 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
442 assert(src_clk_div - 1 < 127);
443
444 switch (clk_id) {
445 case SCLK_SPI0:
446 rk_clrsetreg(&cru->clksel_con[60],
447 CLK_SPI0_DIV_CON_MASK | CLK_SPI0_PLL_SEL_MASK,
448 (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
449 CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
450 break;
451 case SCLK_SPI1:
452 rk_clrsetreg(&cru->clksel_con[61],
453 CLK_SPI1_DIV_CON_MASK | CLK_SPI1_PLL_SEL_MASK,
454 (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
455 CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
456 break;
457 case SCLK_SPI2:
458 rk_clrsetreg(&cru->clksel_con[61],
459 CLK_SPI2_DIV_CON_MASK | CLK_SPI2_PLL_SEL_MASK,
460 (src_clk_div - 1) << CLK_SPI2_DIV_CON_SHIFT |
461 CLK_SPI_PLL_SEL_GPLL << CLK_SPI2_PLL_SEL_SHIFT);
462 break;
463 default:
464 printf("do not support this pwm bus\n");
465 return -EINVAL;
466 }
467
468 return rk1808_spi_get_clk(priv, clk_id);
469 }
470
471 #define RK1808_VOP_PLL_LIMIT_FREQ 600 * 1000000
rk1808_vop_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)472 static ulong rk1808_vop_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
473 {
474 struct rk1808_cru *cru = priv->cru;
475 u32 div, con, parent;
476
477 switch (clk_id) {
478 case ACLK_VOPRAW:
479 case ACLK_VOPLITE:
480 con = readl(&cru->clksel_con[4]);
481 div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT;
482 parent = priv->gpll_hz;
483 break;
484 case HCLK_VOPRAW:
485 case HCLK_VOPLITE:
486 parent = rk1808_vop_get_clk(priv, ACLK_VOPRAW);
487 con = readl(&cru->clksel_con[4]);
488 div = (con & HCLK_VOP_DIV_CON_MASK) >> HCLK_VOP_DIV_CON_SHIFT;
489 break;
490 case DCLK_VOPRAW:
491 con = readl(&cru->clksel_con[5]);
492 div = con & DCLK_VOPRAW_DIV_CON_MASK;
493 parent = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL],
494 priv->cru, NPLL);
495 break;
496 case DCLK_VOPLITE:
497 con = readl(&cru->clksel_con[7]);
498 div = con & DCLK_VOPLITE_DIV_CON_MASK;
499 parent = (con & DCLK_VOPLITE_PLL_SEL_MASK) >>
500 DCLK_VOPLITE_PLL_SEL_SHIFT;
501 if (parent == DCLK_VOPLITE_PLL_SEL_NPLL)
502 parent = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL],
503 priv->cru, NPLL);
504 else if (parent == DCLK_VOPLITE_PLL_SEL_CPLL)
505 parent = priv->cpll_hz;
506 else
507 parent = priv->gpll_hz;
508 break;
509 default:
510 return -ENOENT;
511 }
512
513 return DIV_TO_RATE(parent, div);
514 }
515
rk1808_vop_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,uint hz)516 static ulong rk1808_vop_set_clk(struct rk1808_clk_priv *priv,
517 ulong clk_id, uint hz)
518 {
519 struct rk1808_cru *cru = priv->cru;
520 int src_clk_div, parent;
521
522 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
523 assert(src_clk_div - 1 < 31);
524
525 switch (clk_id) {
526 case ACLK_VOPRAW:
527 case ACLK_VOPLITE:
528 rk_clrsetreg(&cru->clksel_con[4],
529 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
530 ACLK_VOP_PLL_SEL_GPLL << ACLK_VOP_PLL_SEL_SHIFT |
531 (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT);
532 break;
533 case HCLK_VOPRAW:
534 case HCLK_VOPLITE:
535 src_clk_div =
536 DIV_ROUND_UP(rk1808_vop_get_clk(priv, ACLK_VOPRAW), hz);
537 assert(src_clk_div - 1 < 15);
538 rk_clrsetreg(&cru->clksel_con[4],
539 HCLK_VOP_DIV_CON_MASK,
540 (src_clk_div - 1) << HCLK_VOP_DIV_CON_SHIFT);
541 break;
542 case DCLK_VOPRAW:
543 /*
544 * vopb dclk source from npll, and equals to
545 */
546 src_clk_div = DIV_ROUND_UP(RK1808_VOP_PLL_LIMIT_FREQ, hz);
547 rk_clrsetreg(&cru->clksel_con[5],
548 DCLK_VOPRAW_SEL_MASK |
549 DCLK_VOPRAW_PLL_SEL_MASK |
550 DCLK_VOPRAW_DIV_CON_MASK,
551 (DCLK_VOPRAW_SEL_VOPRAW <<
552 DCLK_VOPRAW_SEL_SHIFT) |
553 (DCLK_VOPRAW_PLL_SEL_NPLL <<
554 DCLK_VOPRAW_PLL_SEL_SHIFT) |
555 ((src_clk_div - 1) << DCLK_VOPRAW_DIV_CON_SHIFT));
556 rockchip_pll_set_rate(&rk1808_pll_clks[NPLL],
557 priv->cru, NPLL, src_clk_div * hz);
558
559 break;
560 case DCLK_VOPLITE:
561 /*
562 * vopl dclk source from cpll, and equals to
563 */
564 if (!(priv->cpll_hz % hz)) {
565 parent = DCLK_VOPLITE_PLL_SEL_CPLL;
566 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
567 } else if (!(priv->gpll_hz % hz)) {
568 parent = DCLK_VOPLITE_PLL_SEL_GPLL;
569 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
570 } else {
571 parent = DCLK_VOPLITE_PLL_SEL_NPLL;
572 src_clk_div = DIV_ROUND_UP(RK1808_VOP_PLL_LIMIT_FREQ,
573 hz);
574 rockchip_pll_set_rate(&rk1808_pll_clks[NPLL],
575 priv->cru, NPLL,
576 src_clk_div * hz);
577 }
578 rk_clrsetreg(&cru->clksel_con[7],
579 DCLK_VOPLITE_SEL_MASK | DCLK_VOPLITE_PLL_SEL_MASK |
580 DCLK_VOPLITE_DIV_CON_MASK,
581 (DCLK_VOPLITE_SEL_VOPRAW <<
582 DCLK_VOPLITE_SEL_SHIFT) |
583 (parent << DCLK_VOPLITE_PLL_SEL_SHIFT) |
584 ((src_clk_div - 1) << DCLK_VOPLITE_DIV_CON_SHIFT));
585 break;
586 default:
587 printf("do not support this vop freq\n");
588 return -EINVAL;
589 }
590
591 return rk1808_vop_get_clk(priv, clk_id);
592 }
593
rk1808_mac_set_clk(struct clk * clk,uint hz)594 static ulong rk1808_mac_set_clk(struct clk *clk, uint hz)
595 {
596 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
597 struct rk1808_cru *cru = priv->cru;
598 u32 con = readl(&cru->clksel_con[26]);
599 ulong pll_rate;
600 u8 div;
601
602 if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL)
603 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL],
604 priv->cru, NPLL);
605 else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_PPLL)
606 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[PPLL],
607 priv->cru, PPLL);
608 else
609 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[CPLL],
610 priv->cru, CPLL);
611
612 /*default set 50MHZ for gmac*/
613 if (!hz)
614 hz = 50000000;
615
616 div = DIV_ROUND_UP(pll_rate, hz) - 1;
617 assert(div < 32);
618 rk_clrsetreg(&cru->clksel_con[26], CLK_GMAC_DIV_MASK,
619 div << CLK_GMAC_DIV_SHIFT);
620
621 return DIV_TO_RATE(pll_rate, div);
622 }
623
rk1808_mac_set_speed_clk(struct clk * clk,ulong clk_id,uint hz)624 static int rk1808_mac_set_speed_clk(struct clk *clk, ulong clk_id, uint hz)
625 {
626 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
627 struct rk1808_cru *cru = priv->cru;
628 u32 sel;
629
630 switch (clk_id) {
631 case SCLK_GMAC_RGMII_SPEED:
632 if (hz == 125000000)
633 sel = 0;
634 else if (hz == 2500000)
635 sel = 2;
636 else
637 sel = 3;
638 rk_clrsetreg(&cru->clksel_con[27], RGMII_CLK_SEL_MASK,
639 sel << RGMII_CLK_SEL_SHIFT);
640 break;
641 case SCLK_GMAC_RMII_SPEED:
642 if (hz == 2500000)
643 sel = 0;
644 else
645 sel = 1;
646 rk_clrsetreg(&cru->clksel_con[27], RMII_CLK_SEL_MASK,
647 sel << RMII_CLK_SEL_SHIFT);
648 break;
649 default:
650 return -ENOENT;
651 }
652 return 0;
653 }
654
rk1808_crypto_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)655 static ulong rk1808_crypto_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
656 {
657 struct rk1808_cru *cru = priv->cru;
658 u32 div, con, parent;
659
660 switch (clk_id) {
661 case SCLK_CRYPTO:
662 con = readl(&cru->clksel_con[29]);
663 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
664 parent = priv->gpll_hz;
665 break;
666 case SCLK_CRYPTO_APK:
667 con = readl(&cru->clksel_con[29]);
668 div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
669 parent = priv->gpll_hz;
670 break;
671 default:
672 return -ENOENT;
673 }
674
675 return DIV_TO_RATE(parent, div);
676 }
677
rk1808_crypto_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong hz)678 static ulong rk1808_crypto_set_clk(struct rk1808_clk_priv *priv, ulong clk_id,
679 ulong hz)
680 {
681 struct rk1808_cru *cru = priv->cru;
682 int src_clk_div;
683
684 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
685 assert(src_clk_div - 1 <= 31);
686
687 /*
688 * select gpll as crypto clock source and
689 * set up dependent divisors for crypto clocks.
690 */
691 switch (clk_id) {
692 case SCLK_CRYPTO:
693 rk_clrsetreg(&cru->clksel_con[29],
694 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
695 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
696 (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
697 break;
698 case SCLK_CRYPTO_APK:
699 rk_clrsetreg(&cru->clksel_con[29],
700 CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
701 CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT |
702 (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
703 break;
704 default:
705 printf("do not support this peri freq\n");
706 return -EINVAL;
707 }
708
709 return rk1808_crypto_get_clk(priv, clk_id);
710 }
711 #endif
712
rk1808_bus_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)713 static ulong rk1808_bus_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
714 {
715 struct rk1808_cru *cru = priv->cru;
716 u32 div, con, parent;
717
718 switch (clk_id) {
719 case HSCLK_BUS_PRE:
720 con = readl(&cru->clksel_con[27]);
721 div = (con & HSCLK_BUS_DIV_CON_MASK) >> HSCLK_BUS_DIV_CON_SHIFT;
722 parent = priv->gpll_hz;
723 break;
724 case MSCLK_BUS_PRE:
725 con = readl(&cru->clksel_con[28]);
726 div = (con & MSCLK_BUS_DIV_CON_MASK) >> MSCLK_BUS_DIV_CON_SHIFT;
727 parent = priv->gpll_hz;
728 break;
729 case LSCLK_BUS_PRE:
730 case PCLK_WDT:
731 con = readl(&cru->clksel_con[28]);
732 div = (con & LSCLK_BUS_DIV_CON_MASK) >> LSCLK_BUS_DIV_CON_SHIFT;
733 parent = priv->gpll_hz;
734 break;
735 default:
736 return -ENOENT;
737 }
738
739 return DIV_TO_RATE(parent, div);
740 }
741
rk1808_bus_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong hz)742 static ulong rk1808_bus_set_clk(struct rk1808_clk_priv *priv,
743 ulong clk_id, ulong hz)
744 {
745 struct rk1808_cru *cru = priv->cru;
746 int src_clk_div;
747
748 /*
749 * select gpll as pd_bus bus clock source and
750 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
751 */
752 switch (clk_id) {
753 case HSCLK_BUS_PRE:
754 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
755 assert(src_clk_div - 1 < 31);
756 rk_clrsetreg(&cru->clksel_con[27],
757 CLK_BUS_PLL_SEL_MASK | HSCLK_BUS_DIV_CON_MASK,
758 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT |
759 (src_clk_div - 1) << HSCLK_BUS_DIV_CON_SHIFT);
760 break;
761 case MSCLK_BUS_PRE:
762 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
763 assert(src_clk_div - 1 < 31);
764 rk_clrsetreg(&cru->clksel_con[28],
765 CLK_BUS_PLL_SEL_MASK | MSCLK_BUS_DIV_CON_MASK,
766 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT |
767 (src_clk_div - 1) << MSCLK_BUS_DIV_CON_SHIFT);
768 break;
769 case LSCLK_BUS_PRE:
770 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
771 assert(src_clk_div - 1 < 31);
772 rk_clrsetreg(&cru->clksel_con[28],
773 CLK_BUS_PLL_SEL_MASK | LSCLK_BUS_DIV_CON_MASK,
774 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT |
775 (src_clk_div - 1) << LSCLK_BUS_DIV_CON_SHIFT);
776 break;
777 default:
778 printf("do not support this bus freq\n");
779 return -EINVAL;
780 }
781
782 return rk1808_bus_get_clk(priv, clk_id);
783 }
784
rk1808_peri_get_clk(struct rk1808_clk_priv * priv,ulong clk_id)785 static ulong rk1808_peri_get_clk(struct rk1808_clk_priv *priv, ulong clk_id)
786 {
787 struct rk1808_cru *cru = priv->cru;
788 u32 div, con, parent;
789
790 switch (clk_id) {
791 case MSCLK_PERI:
792 con = readl(&cru->clksel_con[19]);
793 div = (con & MSCLK_PERI_DIV_CON_MASK) >>
794 MSCLK_PERI_DIV_CON_SHIFT;
795 parent = priv->gpll_hz;
796 break;
797 case LSCLK_PERI:
798 con = readl(&cru->clksel_con[19]);
799 div = (con & LSCLK_PERI_DIV_CON_MASK) >>
800 LSCLK_PERI_DIV_CON_SHIFT;
801 parent = priv->gpll_hz;
802 break;
803 default:
804 return -ENOENT;
805 }
806
807 return DIV_TO_RATE(parent, div);
808 }
809
rk1808_peri_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong hz)810 static ulong rk1808_peri_set_clk(struct rk1808_clk_priv *priv,
811 ulong clk_id, ulong hz)
812 {
813 struct rk1808_cru *cru = priv->cru;
814 int src_clk_div;
815
816 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
817 assert(src_clk_div - 1 < 31);
818
819 /*
820 * select gpll as pd_peri bus clock source and
821 * set up dependent divisors for HCLK and ACLK clocks.
822 */
823 switch (clk_id) {
824 case MSCLK_PERI:
825 rk_clrsetreg(&cru->clksel_con[19],
826 CLK_PERI_PLL_SEL_MASK | MSCLK_PERI_DIV_CON_MASK,
827 CLK_PERI_PLL_SEL_GPLL << CLK_PERI_PLL_SEL_SHIFT |
828 (src_clk_div - 1) << MSCLK_PERI_DIV_CON_SHIFT);
829 break;
830 case LSCLK_PERI:
831 rk_clrsetreg(&cru->clksel_con[19],
832 CLK_PERI_PLL_SEL_MASK | LSCLK_PERI_DIV_CON_MASK,
833 CLK_PERI_PLL_SEL_GPLL << CLK_PERI_PLL_SEL_SHIFT |
834 (src_clk_div - 1) << LSCLK_PERI_DIV_CON_SHIFT);
835 break;
836 default:
837 printf("do not support this peri freq\n");
838 return -EINVAL;
839 }
840
841 return rk1808_peri_get_clk(priv, clk_id);
842 }
843
rk1808_pclk_pmu_set_clk(struct rk1808_clk_priv * priv,ulong clk_id,ulong parent_hz,ulong hz)844 static ulong rk1808_pclk_pmu_set_clk(struct rk1808_clk_priv *priv,
845 ulong clk_id, ulong parent_hz, ulong hz)
846 {
847 struct rk1808_cru *cru = priv->cru;
848 int src_clk_div;
849
850 src_clk_div = DIV_ROUND_UP(parent_hz, hz);
851 assert(src_clk_div - 1 < 31);
852
853 rk_clrsetreg(&cru->pmu_clksel_con[0],
854 PCLK_PMU_DIV_CON_MASK,
855 (src_clk_div - 1) << PCLK_PMU_DIV_CON_SHIFT);
856
857 return parent_hz / src_clk_div;
858 }
859
rk1808_armclk_set_clk(struct rk1808_clk_priv * priv,ulong hz)860 static ulong rk1808_armclk_set_clk(struct rk1808_clk_priv *priv, ulong hz)
861 {
862 struct rk1808_cru *cru = priv->cru;
863 const struct rockchip_cpu_rate_table *rate;
864 ulong old_rate;
865
866 rate = rockchip_get_cpu_settings(rk1808_cpu_rates, hz);
867 if (!rate) {
868 printf("%s unsupported rate\n", __func__);
869 return -EINVAL;
870 }
871
872 /*
873 * select apll as cpu/core clock pll source and
874 * set up dependent divisors for PERI and ACLK clocks.
875 * core hz : apll = 1:1
876 */
877 old_rate = rockchip_pll_get_rate(&rk1808_pll_clks[APLL],
878 priv->cru, APLL);
879 if (old_rate > hz) {
880 if (rockchip_pll_set_rate(&rk1808_pll_clks[APLL],
881 priv->cru, APLL, hz))
882 return -EINVAL;
883 rk_clrsetreg(&cru->clksel_con[0],
884 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
885 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
886 rate->aclk_div << CORE_ACLK_DIV_SHIFT |
887 rate->pclk_div << CORE_DBG_DIV_SHIFT |
888 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
889 0 << CORE_DIV_CON_SHIFT);
890 } else if (old_rate < hz) {
891 rk_clrsetreg(&cru->clksel_con[0],
892 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
893 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
894 rate->aclk_div << CORE_ACLK_DIV_SHIFT |
895 rate->pclk_div << CORE_DBG_DIV_SHIFT |
896 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
897 0 << CORE_DIV_CON_SHIFT);
898 if (rockchip_pll_set_rate(&rk1808_pll_clks[APLL],
899 priv->cru, APLL, hz))
900 return -EINVAL;
901 }
902
903 return rockchip_pll_get_rate(&rk1808_pll_clks[APLL], priv->cru, APLL);
904 }
905
rk1808_clk_get_rate(struct clk * clk)906 static ulong rk1808_clk_get_rate(struct clk *clk)
907 {
908 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
909 ulong rate = 0;
910
911 debug("%s %ld\n", __func__, clk->id);
912 switch (clk->id) {
913 case PLL_APLL:
914 case PLL_DPLL:
915 case PLL_CPLL:
916 case PLL_GPLL:
917 case PLL_NPLL:
918 case PLL_PPLL:
919 rate = rockchip_pll_get_rate(&rk1808_pll_clks[clk->id - 1],
920 priv->cru, clk->id - 1);
921 break;
922 case ARMCLK:
923 rate = rockchip_pll_get_rate(&rk1808_pll_clks[APLL],
924 priv->cru, APLL);
925 break;
926 case HCLK_SDMMC:
927 case HCLK_EMMC:
928 case HCLK_SDIO:
929 case SCLK_SDMMC:
930 case SCLK_EMMC:
931 case SCLK_EMMC_SAMPLE:
932 case SCLK_SDIO:
933 rate = rk1808_mmc_get_clk(priv, clk->id);
934 break;
935 case SCLK_SFC:
936 rate = rk1808_sfc_get_clk(priv, clk->id);
937 break;
938 case SCLK_SARADC:
939 rate = rk1808_saradc_get_clk(priv);
940 break;
941 #ifndef CONFIG_SPL_BUILD
942 case SCLK_PMU_I2C0:
943 case SCLK_I2C1:
944 case SCLK_I2C2:
945 case SCLK_I2C3:
946 case SCLK_I2C4:
947 case SCLK_I2C5:
948 rate = rk1808_i2c_get_clk(priv, clk->id);
949 break;
950 case SCLK_PWM0:
951 case SCLK_PWM1:
952 case SCLK_PWM2:
953 rate = rk1808_pwm_get_clk(priv, clk->id);
954 break;
955 case SCLK_TSADC:
956 rate = rk1808_tsadc_get_clk(priv);
957 break;
958 case SCLK_SPI0:
959 case SCLK_SPI1:
960 case SCLK_SPI2:
961 rate = rk1808_spi_get_clk(priv, clk->id);
962 break;
963 case ACLK_VOPRAW:
964 case DCLK_VOPRAW:
965 case ACLK_VOPLITE:
966 case DCLK_VOPLITE:
967 rate = rk1808_vop_get_clk(priv, clk->id);
968 break;
969 case SCLK_CRYPTO:
970 case SCLK_CRYPTO_APK:
971 rate = rk1808_crypto_get_clk(priv, clk->id);
972 break;
973 #endif
974 case HSCLK_BUS_PRE:
975 case MSCLK_BUS_PRE:
976 case LSCLK_BUS_PRE:
977 case PCLK_WDT:
978 rate = rk1808_bus_get_clk(priv, clk->id);
979 break;
980 case MSCLK_PERI:
981 case LSCLK_PERI:
982 rate = rk1808_peri_get_clk(priv, clk->id);
983 break;
984 default:
985 return -ENOENT;
986 }
987
988 return rate;
989 }
990
rk1808_clk_set_rate(struct clk * clk,ulong rate)991 static ulong rk1808_clk_set_rate(struct clk *clk, ulong rate)
992 {
993 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
994 ulong ret = 0;
995
996 debug("%s %ld %ld\n", __func__, clk->id, rate);
997 switch (clk->id) {
998 case PLL_APLL:
999 case PLL_DPLL:
1000 ret = rockchip_pll_set_rate(&rk1808_pll_clks[clk->id - 1],
1001 priv->cru, clk->id - 1, rate);
1002 break;
1003 case PLL_PPLL:
1004 ret = rk1808_pclk_pmu_set_clk(priv, clk->id, rate, PCLK_PMU_HZ);
1005 ret = rockchip_pll_set_rate(&rk1808_pll_clks[PPLL],
1006 priv->cru, PPLL, rate);
1007 break;
1008 case PLL_CPLL:
1009 ret = rockchip_pll_set_rate(&rk1808_pll_clks[CPLL],
1010 priv->cru, CPLL, rate);
1011 if (ret == 0)
1012 priv->cpll_hz = rate;
1013 break;
1014 case PLL_GPLL:
1015 ret = rockchip_pll_set_rate(&rk1808_pll_clks[GPLL],
1016 priv->cru, GPLL, rate);
1017 if (ret == 0)
1018 priv->gpll_hz = rate;
1019 break;
1020 case PLL_NPLL:
1021 ret = rockchip_pll_set_rate(&rk1808_pll_clks[NPLL],
1022 priv->cru, NPLL, rate);
1023 if (ret == 0)
1024 priv->npll_hz = rate;
1025 break;
1026 case ARMCLK:
1027 if (priv->armclk_hz)
1028 rk1808_armclk_set_clk(priv, rate);
1029 priv->armclk_hz = rate;
1030 break;
1031 case HCLK_SDMMC:
1032 case HCLK_EMMC:
1033 case HCLK_SDIO:
1034 case SCLK_SDMMC:
1035 case SCLK_EMMC:
1036 case SCLK_SDIO:
1037 ret = rk1808_mmc_set_clk(priv, clk->id, rate);
1038 break;
1039 case SCLK_SFC:
1040 ret = rk1808_sfc_set_clk(priv, clk->id, rate);
1041 break;
1042 case SCLK_SARADC:
1043 ret = rk1808_saradc_set_clk(priv, rate);
1044 break;
1045 #ifndef CONFIG_SPL_BUILD
1046 case SCLK_PMU_I2C0:
1047 case SCLK_I2C1:
1048 case SCLK_I2C2:
1049 case SCLK_I2C3:
1050 case SCLK_I2C4:
1051 case SCLK_I2C5:
1052 ret = rk1808_i2c_set_clk(priv, clk->id, rate);
1053 break;
1054 case SCLK_PWM0:
1055 case SCLK_PWM1:
1056 case SCLK_PWM2:
1057 ret = rk1808_pwm_set_clk(priv, clk->id, rate);
1058 break;
1059 case SCLK_TSADC:
1060 ret = rk1808_tsadc_set_clk(priv, rate);
1061 break;
1062 case SCLK_SPI0:
1063 case SCLK_SPI1:
1064 case SCLK_SPI2:
1065 ret = rk1808_spi_set_clk(priv, clk->id, rate);
1066 break;
1067 case ACLK_VOPRAW:
1068 case DCLK_VOPRAW:
1069 case ACLK_VOPLITE:
1070 case DCLK_VOPLITE:
1071 ret = rk1808_vop_set_clk(priv, clk->id, rate);
1072 break;
1073 case SCLK_GMAC:
1074 case SCLK_GMAC_SRC:
1075 ret = rk1808_mac_set_clk(clk, rate);
1076 break;
1077 case SCLK_GMAC_RMII_SPEED:
1078 case SCLK_GMAC_RGMII_SPEED:
1079 ret = rk1808_mac_set_speed_clk(clk, clk->id, rate);
1080 break;
1081 case SCLK_CRYPTO:
1082 case SCLK_CRYPTO_APK:
1083 ret = rk1808_crypto_set_clk(priv, clk->id, rate);
1084 break;
1085 #endif
1086 case HSCLK_BUS_PRE:
1087 case MSCLK_BUS_PRE:
1088 case LSCLK_BUS_PRE:
1089 ret = rk1808_bus_set_clk(priv, clk->id, rate);
1090 break;
1091 case MSCLK_PERI:
1092 case LSCLK_PERI:
1093 ret = rk1808_peri_set_clk(priv, clk->id, rate);
1094 break;
1095 case SCLK_32K_IOE:
1096 return 0;
1097 default:
1098 return -ENOENT;
1099 }
1100
1101 return ret;
1102 }
1103
1104 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1105 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1106 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1107 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1108
1109 #define PSECS_PER_SEC 1000000000000LL
1110 /*
1111 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1112 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1113 */
1114 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1115
rk1808_mmc_get_phase(struct clk * clk)1116 int rk1808_mmc_get_phase(struct clk *clk)
1117 {
1118 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
1119 struct rk1808_cru *cru = priv->cru;
1120 u32 raw_value, delay_num;
1121 u16 degrees = 0;
1122 ulong rate;
1123
1124 rate = rk1808_clk_get_rate(clk);
1125
1126 if (rate < 0)
1127 return rate;
1128
1129 if (clk->id == SCLK_EMMC_SAMPLE)
1130 raw_value = readl(&cru->emmc_con[1]);
1131 else if (clk->id == SCLK_SDMMC_SAMPLE)
1132 raw_value = readl(&cru->sdmmc_con[1]);
1133 else
1134 raw_value = readl(&cru->sdio_con[1]);
1135
1136 raw_value >>= 1;
1137 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1138
1139 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1140 /* degrees/delaynum * 10000 */
1141 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1142 36 * (rate / 1000000);
1143
1144 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1145 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1146 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1147 }
1148
1149 return degrees % 360;
1150 }
1151
rk1808_mmc_set_phase(struct clk * clk,u32 degrees)1152 int rk1808_mmc_set_phase(struct clk *clk, u32 degrees)
1153 {
1154 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
1155 struct rk1808_cru *cru = priv->cru;
1156 u8 nineties, remainder, delay_num;
1157 u32 raw_value, delay;
1158 ulong rate;
1159
1160 rate = rk1808_clk_get_rate(clk);
1161
1162 if (rate < 0)
1163 return rate;
1164
1165 nineties = degrees / 90;
1166 remainder = (degrees % 90);
1167
1168 /*
1169 * Convert to delay; do a little extra work to make sure we
1170 * don't overflow 32-bit / 64-bit numbers.
1171 */
1172 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1173 delay *= remainder;
1174 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1175 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1176
1177 delay_num = (u8)min_t(u32, delay, 255);
1178
1179 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1180 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1181 raw_value |= nineties;
1182
1183 raw_value <<= 1;
1184 if (clk->id == SCLK_EMMC_SAMPLE)
1185 writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1186 else if (clk->id == SCLK_SDMMC_SAMPLE)
1187 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1188 else
1189 writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1190
1191 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1192 degrees, delay_num, raw_value, rk1808_mmc_get_phase(clk));
1193
1194 return 0;
1195 }
1196
rk1808_clk_get_phase(struct clk * clk)1197 static int rk1808_clk_get_phase(struct clk *clk)
1198 {
1199 int ret;
1200
1201 debug("%s %ld\n", __func__, clk->id);
1202 switch (clk->id) {
1203 case SCLK_EMMC_SAMPLE:
1204 case SCLK_SDMMC_SAMPLE:
1205 case SCLK_SDIO_SAMPLE:
1206 ret = rk1808_mmc_get_phase(clk);
1207 break;
1208 default:
1209 return -ENOENT;
1210 }
1211
1212 return ret;
1213 }
1214
rk1808_clk_set_phase(struct clk * clk,int degrees)1215 static int rk1808_clk_set_phase(struct clk *clk, int degrees)
1216 {
1217 int ret;
1218
1219 debug("%s %ld\n", __func__, clk->id);
1220 switch (clk->id) {
1221 case SCLK_EMMC_SAMPLE:
1222 case SCLK_SDMMC_SAMPLE:
1223 case SCLK_SDIO_SAMPLE:
1224 ret = rk1808_mmc_set_phase(clk, degrees);
1225 break;
1226 default:
1227 return -ENOENT;
1228 }
1229
1230 return ret;
1231 }
1232
1233 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
rk1808_gmac_set_parent(struct clk * clk,struct clk * parent)1234 static int rk1808_gmac_set_parent(struct clk *clk, struct clk *parent)
1235 {
1236 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev);
1237 struct rk1808_cru *cru = priv->cru;
1238
1239 if (parent->id == SCLK_GMAC_SRC) {
1240 debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__);
1241 rk_clrsetreg(&cru->clksel_con[27], RMII_EXTCLK_SEL_MASK,
1242 RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT);
1243 } else {
1244 debug("%s: switching GMAC to external clock\n", __func__);
1245 rk_clrsetreg(&cru->clksel_con[27], RMII_EXTCLK_SEL_MASK,
1246 RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT);
1247 }
1248 return 0;
1249 }
1250
rk1808_clk_set_parent(struct clk * clk,struct clk * parent)1251 static int rk1808_clk_set_parent(struct clk *clk, struct clk *parent)
1252 {
1253 switch (clk->id) {
1254 case SCLK_GMAC:
1255 return rk1808_gmac_set_parent(clk, parent);
1256 case SCLK_32K_IOE:
1257 return 0;
1258 default:
1259 return -ENOENT;
1260 }
1261 }
1262 #endif
1263
1264 static struct clk_ops rk1808_clk_ops = {
1265 .get_rate = rk1808_clk_get_rate,
1266 .set_rate = rk1808_clk_set_rate,
1267 .get_phase = rk1808_clk_get_phase,
1268 .set_phase = rk1808_clk_set_phase,
1269 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1270 .set_parent = rk1808_clk_set_parent,
1271 #endif
1272 };
1273
rk1808_clk_probe(struct udevice * dev)1274 static int rk1808_clk_probe(struct udevice *dev)
1275 {
1276 struct rk1808_clk_priv *priv = dev_get_priv(dev);
1277 int ret;
1278 #ifndef CONFIG_SPL_BUILD
1279 ulong crypto_rate, crypto_apk_rate;
1280 ulong emmc_rate, sdmmc_rate, sfc_rate;
1281 #endif
1282
1283 priv->sync_kernel = false;
1284 if (!priv->armclk_enter_hz) {
1285 priv->armclk_enter_hz =
1286 rockchip_pll_get_rate(&rk1808_pll_clks[APLL],
1287 priv->cru, APLL);
1288 priv->armclk_init_hz = priv->armclk_enter_hz;
1289 }
1290 if (rockchip_pll_get_rate(&rk1808_pll_clks[APLL],
1291 priv->cru, APLL) != APLL_HZ) {
1292 ret = rk1808_armclk_set_clk(priv, APLL_HZ);
1293 if (ret < 0)
1294 printf("%s failed to set armclk rate\n", __func__);
1295 priv->armclk_init_hz = APLL_HZ;
1296 }
1297 #ifdef CONFIG_SPL_BUILD
1298 /*
1299 * The eMMC clk is depended on gpll, and the eMMC is needed to
1300 * run 150MHz in HS200 mode. So set gpll to GPLL_HZ(594000000)
1301 * which can be divided near to 150MHz.
1302 */
1303 ret = rockchip_pll_set_rate(&rk1808_pll_clks[GPLL],
1304 priv->cru, GPLL, GPLL_HZ);
1305 if (ret < 0)
1306 printf("%s failed to set gpll rate\n", __func__);
1307 #endif
1308 priv->cpll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[CPLL],
1309 priv->cru, CPLL);
1310 priv->gpll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[GPLL],
1311 priv->cru, GPLL);
1312 priv->npll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL],
1313 priv->cru, NPLL);
1314
1315 #ifndef CONFIG_SPL_BUILD
1316 crypto_rate = rk1808_crypto_get_clk(priv, SCLK_CRYPTO);
1317 crypto_apk_rate = rk1808_crypto_get_clk(priv, SCLK_CRYPTO_APK);
1318 emmc_rate = rk1808_mmc_get_clk(priv, SCLK_EMMC);
1319 sdmmc_rate = rk1808_mmc_get_clk(priv, SCLK_SDMMC);
1320 sfc_rate = rk1808_sfc_get_clk(priv, SCLK_SFC);
1321 #endif
1322
1323 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1324 ret = clk_set_defaults(dev);
1325 if (ret)
1326 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1327 else
1328 priv->sync_kernel = true;
1329
1330 #ifndef CONFIG_SPL_BUILD
1331 rk1808_crypto_set_clk(priv, SCLK_CRYPTO, crypto_rate);
1332 rk1808_crypto_set_clk(priv, SCLK_CRYPTO_APK, crypto_apk_rate);
1333 rk1808_mmc_set_clk(priv, SCLK_EMMC, emmc_rate);
1334 rk1808_mmc_set_clk(priv, SCLK_SDMMC, sdmmc_rate);
1335 rk1808_sfc_set_clk(priv, SCLK_SFC, sfc_rate);
1336 #endif
1337
1338 return 0;
1339 }
1340
rk1808_clk_ofdata_to_platdata(struct udevice * dev)1341 static int rk1808_clk_ofdata_to_platdata(struct udevice *dev)
1342 {
1343 struct rk1808_clk_priv *priv = dev_get_priv(dev);
1344
1345 priv->cru = dev_read_addr_ptr(dev);
1346
1347 return 0;
1348 }
1349
rk1808_clk_bind(struct udevice * dev)1350 static int rk1808_clk_bind(struct udevice *dev)
1351 {
1352 int ret;
1353 struct udevice *sys_child, *sf_child;
1354 struct sysreset_reg *priv;
1355 struct softreset_reg *sf_priv;
1356
1357 /* The reset driver does not have a device node, so bind it here */
1358 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1359 &sys_child);
1360 if (ret) {
1361 debug("Warning: No sysreset driver: ret=%d\n", ret);
1362 } else {
1363 priv = malloc(sizeof(struct sysreset_reg));
1364 priv->glb_srst_fst_value = offsetof(struct rk1808_cru,
1365 glb_srst_fst);
1366 priv->glb_srst_snd_value = offsetof(struct rk1808_cru,
1367 glb_srst_snd);
1368 sys_child->priv = priv;
1369 }
1370
1371 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1372 dev_ofnode(dev), &sf_child);
1373 if (ret) {
1374 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1375 } else {
1376 sf_priv = malloc(sizeof(struct softreset_reg));
1377 sf_priv->sf_reset_offset = offsetof(struct rk1808_cru,
1378 softrst_con[0]);
1379 sf_priv->sf_reset_num = 16;
1380 sf_child->priv = sf_priv;
1381 }
1382
1383 return 0;
1384 }
1385
1386 static const struct udevice_id rk1808_clk_ids[] = {
1387 { .compatible = "rockchip,rk1808-cru" },
1388 { }
1389 };
1390
1391 U_BOOT_DRIVER(rockchip_rk1808_cru) = {
1392 .name = "rockchip_rk1808_cru",
1393 .id = UCLASS_CLK,
1394 .of_match = rk1808_clk_ids,
1395 .priv_auto_alloc_size = sizeof(struct rk1808_clk_priv),
1396 .ofdata_to_platdata = rk1808_clk_ofdata_to_platdata,
1397 .ops = &rk1808_clk_ops,
1398 .bind = rk1808_clk_bind,
1399 .probe = rk1808_clk_probe,
1400 };
1401
1402 #ifndef CONFIG_SPL_BUILD
1403 /**
1404 * soc_clk_dump() - Print clock frequencies
1405 * Returns zero on success
1406 *
1407 * Implementation for the clk dump command.
1408 */
soc_clk_dump(void)1409 int soc_clk_dump(void)
1410 {
1411 struct udevice *cru_dev;
1412 struct rk1808_clk_priv *priv;
1413 const struct rk1808_clk_info *clk_dump;
1414 struct clk clk;
1415 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1416 unsigned long rate;
1417 int i, ret;
1418
1419 ret = uclass_get_device_by_driver(UCLASS_CLK,
1420 DM_GET_DRIVER(rockchip_rk1808_cru),
1421 &cru_dev);
1422 if (ret) {
1423 printf("%s failed to get cru device\n", __func__);
1424 return ret;
1425 }
1426
1427 priv = dev_get_priv(cru_dev);
1428 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1429 priv->sync_kernel ? "sync kernel" : "uboot",
1430 priv->armclk_enter_hz / 1000,
1431 priv->armclk_init_hz / 1000,
1432 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1433 priv->set_armclk_rate ? " KHz" : "N/A");
1434
1435 for (i = 0; i < clk_count; i++) {
1436 clk_dump = &clks_dump[i];
1437 if (clk_dump->name) {
1438 clk.id = clk_dump->id;
1439 if (clk_dump->is_cru)
1440 ret = clk_request(cru_dev, &clk);
1441 if (ret < 0)
1442 return ret;
1443
1444 rate = clk_get_rate(&clk);
1445 clk_free(&clk);
1446 if (i == 0) {
1447 if (rate < 0)
1448 printf(" %s %s\n", clk_dump->name,
1449 "unknown");
1450 else
1451 printf(" %s %lu KHz\n", clk_dump->name,
1452 rate / 1000);
1453 } else {
1454 if (rate < 0)
1455 printf(" %s %s\n", clk_dump->name,
1456 "unknown");
1457 else
1458 printf(" %s %lu KHz\n", clk_dump->name,
1459 rate / 1000);
1460 }
1461 }
1462 }
1463
1464 return 0;
1465 }
1466 #endif
1467