xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk1808.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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