xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk3128.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <syscon.h>
12 #include <asm/io.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk3128.h>
15 #include <asm/arch/hardware.h>
16 #include <bitfield.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rk3128-cru.h>
19 #include <linux/log2.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
24 
25 #ifndef CONFIG_SPL_BUILD
26 #define RK3128_CLK_DUMP(_id, _name, _iscru)	\
27 {						\
28 	.id = _id,				\
29 	.name = _name,				\
30 	.is_cru = _iscru,			\
31 }
32 #endif
33 
34 static struct rockchip_pll_rate_table rk3128_pll_rates[] = {
35 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
36 #ifndef CONFIG_SPL_BUILD
37 	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
38 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
39 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
40 #endif
41 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
42 	RK3036_PLL_RATE(800000000, 1, 200, 6, 1, 1, 0),
43 	RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
44 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
45 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
46 	RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
47 	{ /* sentinel */ },
48 };
49 
50 #define RK3128_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
51 {								\
52 	.rate	= _rate##U,					\
53 	.aclk_div = _aclk_div,					\
54 	.pclk_div = _pclk_div,					\
55 }
56 
57 static struct rockchip_cpu_rate_table rk3128_cpu_rates[] = {
58 	RK3128_CPUCLK_RATE(1200000000, 1, 5),
59 	RK3128_CPUCLK_RATE(1008000000, 1, 5),
60 	RK3128_CPUCLK_RATE(816000000, 1, 3),
61 	RK3128_CPUCLK_RATE(600000000, 1, 3),
62 };
63 
64 #ifndef CONFIG_SPL_BUILD
65 static const struct rk3128_clk_info clks_dump[] = {
66 	RK3128_CLK_DUMP(PLL_APLL, "apll", true),
67 	RK3128_CLK_DUMP(PLL_DPLL, "dpll", true),
68 	RK3128_CLK_DUMP(PLL_CPLL, "cpll", true),
69 	RK3128_CLK_DUMP(PLL_GPLL, "gpll", true),
70 	RK3128_CLK_DUMP(ARMCLK, "armclk", true),
71 	RK3128_CLK_DUMP(ACLK_CPU, "aclk_cpu", true),
72 	RK3128_CLK_DUMP(HCLK_CPU, "hclk_cpu", true),
73 	RK3128_CLK_DUMP(PCLK_CPU, "pclk_cpu", true),
74 	RK3128_CLK_DUMP(ACLK_PERI, "aclk_peri", true),
75 	RK3128_CLK_DUMP(HCLK_PERI, "hclk_peri", true),
76 	RK3128_CLK_DUMP(PCLK_PERI, "pclk_peri", true),
77 };
78 #endif
79 
80 static struct rockchip_pll_clock rk3128_pll_clks[] = {
81 	[APLL] = PLL(pll_rk3036, PLL_APLL, RK2928_PLL_CON(0),
82 		     RK2928_MODE_CON, 0, 10, 0, rk3128_pll_rates),
83 	[DPLL] = PLL(pll_rk3036, PLL_DPLL, RK2928_PLL_CON(4),
84 		     RK2928_MODE_CON, 4, 10, 0, NULL),
85 	[CPLL] = PLL(pll_rk3036, PLL_CPLL, RK2928_PLL_CON(8),
86 		    RK2928_MODE_CON, 8, 10, 0, rk3128_pll_rates),
87 	[GPLL] = PLL(pll_rk3036, PLL_GPLL, RK2928_PLL_CON(12),
88 		     RK2928_MODE_CON, 12, 10, 0, rk3128_pll_rates),
89 };
90 
rk3128_armclk_set_clk(struct rk3128_clk_priv * priv,ulong hz)91 static ulong rk3128_armclk_set_clk(struct rk3128_clk_priv *priv, ulong hz)
92 {
93 	struct rk3128_cru *cru = priv->cru;
94 	const struct rockchip_cpu_rate_table *rate;
95 	ulong old_rate;
96 
97 	rate = rockchip_get_cpu_settings(rk3128_cpu_rates, hz);
98 	if (!rate) {
99 		printf("%s unsupported rate\n", __func__);
100 		return -EINVAL;
101 	}
102 
103 	/*
104 	 * select apll as cpu/core clock pll source and
105 	 * set up dependent divisors for PERI and ACLK clocks.
106 	 * core hz : apll = 1:1
107 	 */
108 	old_rate = rockchip_pll_get_rate(&rk3128_pll_clks[APLL],
109 					 priv->cru, APLL);
110 	if (old_rate > hz) {
111 		if (rockchip_pll_set_rate(&rk3128_pll_clks[APLL],
112 					  priv->cru, APLL, hz))
113 			return -EINVAL;
114 		rk_clrsetreg(&cru->cru_clksel_con[0],
115 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
116 			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
117 			     0 << CORE_DIV_CON_SHIFT);
118 		rk_clrsetreg(&cru->cru_clksel_con[1],
119 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
120 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
121 			     rate->pclk_div << CORE_DBG_DIV_SHIFT);
122 	} else if (old_rate < hz) {
123 		rk_clrsetreg(&cru->cru_clksel_con[1],
124 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
125 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
126 			     rate->pclk_div << CORE_DBG_DIV_SHIFT);
127 		rk_clrsetreg(&cru->cru_clksel_con[0],
128 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
129 			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
130 			     0 << CORE_DIV_CON_SHIFT);
131 		if (rockchip_pll_set_rate(&rk3128_pll_clks[APLL],
132 					  priv->cru, APLL, hz))
133 			return -EINVAL;
134 	}
135 
136 	return rockchip_pll_get_rate(&rk3128_pll_clks[APLL], priv->cru, APLL);
137 }
138 
rockchip_mmc_get_clk(struct rk3128_clk_priv * priv,int periph)139 static ulong rockchip_mmc_get_clk(struct rk3128_clk_priv *priv,
140 				  int periph)
141 {
142 	struct rk3128_cru *cru = priv->cru;
143 	uint src_rate;
144 	uint div, mux;
145 	u32 con;
146 
147 	switch (periph) {
148 	case HCLK_EMMC:
149 	case SCLK_EMMC:
150 	case SCLK_EMMC_SAMPLE:
151 		con = readl(&cru->cru_clksel_con[12]);
152 		mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
153 		div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
154 		break;
155 	case HCLK_SDMMC:
156 	case SCLK_SDMMC:
157 	case SCLK_SDMMC_SAMPLE:
158 		con = readl(&cru->cru_clksel_con[11]);
159 		mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
160 		div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
161 		break;
162 	case HCLK_SDIO:
163 	case SCLK_SDIO:
164 	case SCLK_SDIO_SAMPLE:
165 		con = readl(&cru->cru_clksel_con[12]);
166 		mux = (con & SDIO_PLL_MASK) >> SDIO_PLL_SHIFT;
167 		div = (con & SDIO_DIV_MASK) >> SDIO_DIV_SHIFT;
168 		break;
169 	default:
170 		return -EINVAL;
171 	}
172 
173 	src_rate = mux == EMMC_SEL_24M ? OSC_HZ : priv->gpll_hz;
174 	return DIV_TO_RATE(src_rate, div);
175 }
176 
rockchip_mmc_set_clk(struct rk3128_clk_priv * priv,int periph,uint freq)177 static ulong rockchip_mmc_set_clk(struct rk3128_clk_priv *priv,
178 				  int periph, uint freq)
179 {
180 	struct rk3128_cru *cru = priv->cru;
181 	int src_clk_div;
182 	int mux;
183 
184 	/* mmc clock defaulg div 2 internal, need provide double in cru */
185 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, freq);
186 
187 	if (src_clk_div > 128) {
188 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
189 		mux = EMMC_SEL_24M;
190 	} else {
191 		mux = EMMC_SEL_GPLL;
192 	}
193 
194 	switch (periph) {
195 	case HCLK_EMMC:
196 	case SCLK_EMMC:
197 		rk_clrsetreg(&cru->cru_clksel_con[12],
198 			     EMMC_PLL_MASK | EMMC_DIV_MASK,
199 			     mux << EMMC_PLL_SHIFT |
200 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
201 		break;
202 	case HCLK_SDMMC:
203 	case SCLK_SDMMC:
204 		rk_clrsetreg(&cru->cru_clksel_con[11],
205 			     MMC0_PLL_MASK | MMC0_DIV_MASK,
206 			     mux << MMC0_PLL_SHIFT |
207 			     (src_clk_div - 1) << MMC0_DIV_SHIFT);
208 		break;
209 	case HCLK_SDIO:
210 	case SCLK_SDIO:
211 		rk_clrsetreg(&cru->cru_clksel_con[12],
212 			     SDIO_PLL_MASK | SDIO_DIV_MASK,
213 			     mux << SDIO_PLL_SHIFT |
214 			     (src_clk_div - 1) << SDIO_DIV_SHIFT);
215 		break;
216 	default:
217 		return -EINVAL;
218 	}
219 
220 	return rockchip_mmc_get_clk(priv, periph);
221 }
222 
rk3128_peri_get_clk(struct rk3128_clk_priv * priv,ulong clk_id)223 static ulong rk3128_peri_get_clk(struct rk3128_clk_priv *priv, ulong clk_id)
224 {
225 	struct rk3128_cru *cru = priv->cru;
226 	u32 div, con, parent;
227 
228 	switch (clk_id) {
229 	case ACLK_PERI:
230 		con = readl(&cru->cru_clksel_con[10]);
231 		div = (con & ACLK_PERI_DIV_MASK) >> ACLK_PERI_DIV_SHIFT;
232 		parent = priv->gpll_hz;
233 		break;
234 	case PCLK_PERI:
235 	case PCLK_I2C0:
236 	case PCLK_I2C1:
237 	case PCLK_I2C2:
238 	case PCLK_I2C3:
239 	case PCLK_PWM:
240 	case PCLK_WDT:
241 		con = readl(&cru->cru_clksel_con[10]);
242 		div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
243 		parent = rk3128_peri_get_clk(priv, ACLK_PERI);
244 		break;
245 	case HCLK_PERI:
246 		con = readl(&cru->cru_clksel_con[10]);
247 		div = (con & HCLK_PERI_DIV_MASK) >> HCLK_PERI_DIV_SHIFT;
248 		parent = rk3128_peri_get_clk(priv, ACLK_PERI);
249 		break;
250 	default:
251 		printf("do not support this peripheral bus\n");
252 		return -EINVAL;
253 	}
254 
255 	return DIV_TO_RATE(parent, div);
256 }
257 
rk3128_peri_set_clk(struct rk3128_clk_priv * priv,ulong clk_id,uint hz)258 static ulong rk3128_peri_set_clk(struct rk3128_clk_priv *priv,
259 				 ulong clk_id, uint hz)
260 {
261 	struct rk3128_cru *cru = priv->cru;
262 	int src_clk_div;
263 
264 	switch (clk_id) {
265 	case ACLK_PERI:
266 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
267 		assert(src_clk_div - 1 < 32);
268 		rk_clrsetreg(&cru->cru_clksel_con[10],
269 			     PERI_PLL_SEL_MASK | ACLK_PERI_DIV_MASK,
270 			     PERI_PLL_SEL_GPLL << PERI_PLL_SEL_SHIFT |
271 			     (src_clk_div - 1) << ACLK_PERI_DIV_SHIFT);
272 		break;
273 	case PCLK_I2C0:
274 	case PCLK_I2C1:
275 	case PCLK_I2C2:
276 	case PCLK_I2C3:
277 	case PCLK_PWM:
278 	case PCLK_PERI:
279 		src_clk_div = DIV_ROUND_UP(rk3128_peri_get_clk(priv,
280 							       ACLK_PERI),
281 					   hz);
282 		assert(src_clk_div - 1 < 3);
283 		rk_clrsetreg(&cru->cru_clksel_con[10],
284 			     PCLK_PERI_DIV_MASK,
285 			     (src_clk_div - 1) << PCLK_PERI_DIV_SHIFT);
286 		break;
287 	case HCLK_PERI:
288 		src_clk_div = DIV_ROUND_UP(rk3128_peri_get_clk(priv,
289 							       ACLK_PERI),
290 					   hz);
291 		assert(src_clk_div - 1 < 7);
292 		rk_clrsetreg(&cru->cru_clksel_con[10],
293 			     HCLK_PERI_DIV_MASK,
294 			     (src_clk_div - 1) << HCLK_PERI_DIV_SHIFT);
295 		break;
296 	default:
297 		printf("do not support this peripheral bus\n");
298 		return -EINVAL;
299 	}
300 
301 	return rk3128_peri_get_clk(priv, clk_id);
302 }
303 
rk3128_bus_get_clk(struct rk3128_clk_priv * priv,ulong clk_id)304 static ulong rk3128_bus_get_clk(struct rk3128_clk_priv *priv, ulong clk_id)
305 {
306 	struct rk3128_cru *cru = priv->cru;
307 	u32 div, con, parent;
308 
309 	switch (clk_id) {
310 	case ACLK_CPU:
311 		con = readl(&cru->cru_clksel_con[0]);
312 		div = (con & ACLK_BUS_DIV_MASK) >> ACLK_BUS_DIV_SHIFT;
313 		parent = priv->gpll_hz;
314 		break;
315 	case PCLK_CPU:
316 		con = readl(&cru->cru_clksel_con[1]);
317 		div = (con & PCLK_BUS_DIV_MASK) >> PCLK_BUS_DIV_SHIFT;
318 		parent = rk3128_bus_get_clk(priv, ACLK_CPU);
319 		break;
320 	case HCLK_CPU:
321 		con = readl(&cru->cru_clksel_con[1]);
322 		div = (con & HCLK_BUS_DIV_MASK) >> HCLK_BUS_DIV_SHIFT;
323 		parent = rk3128_bus_get_clk(priv, ACLK_CPU);
324 		break;
325 	default:
326 		printf("do not support this peripheral bus\n");
327 		return -EINVAL;
328 	}
329 
330 	return DIV_TO_RATE(parent, div);
331 }
332 
rk3128_bus_set_clk(struct rk3128_clk_priv * priv,ulong clk_id,uint hz)333 static ulong rk3128_bus_set_clk(struct rk3128_clk_priv *priv,
334 				ulong clk_id, uint hz)
335 {
336 	struct rk3128_cru *cru = priv->cru;
337 	int src_clk_div;
338 
339 	switch (clk_id) {
340 	case ACLK_CPU:
341 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
342 		assert(src_clk_div - 1 < 32);
343 		rk_clrsetreg(&cru->cru_clksel_con[0],
344 			     BUS_PLL_SEL_MASK | ACLK_BUS_DIV_MASK,
345 			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
346 			     (src_clk_div - 1) << ACLK_BUS_DIV_SHIFT);
347 		break;
348 	case PCLK_CPU:
349 		src_clk_div = DIV_ROUND_UP(rk3128_bus_get_clk(priv,
350 							      ACLK_CPU),
351 					   hz);
352 		assert(src_clk_div - 1 < 3);
353 		rk_clrsetreg(&cru->cru_clksel_con[1],
354 			     PCLK_BUS_DIV_MASK,
355 			     (src_clk_div - 1) << PCLK_BUS_DIV_SHIFT);
356 		break;
357 	case HCLK_CPU:
358 		src_clk_div = DIV_ROUND_UP(rk3128_bus_get_clk(priv,
359 							      ACLK_CPU),
360 					   hz);
361 		assert(src_clk_div - 1 < 7);
362 		rk_clrsetreg(&cru->cru_clksel_con[1],
363 			     HCLK_BUS_DIV_MASK,
364 			     (src_clk_div - 1) << HCLK_BUS_DIV_SHIFT);
365 		break;
366 	default:
367 		printf("do not support this peripheral bus\n");
368 		return -EINVAL;
369 	}
370 
371 	return rk3128_bus_get_clk(priv, clk_id);
372 }
373 
rk3128_spi_get_clk(struct rk3128_clk_priv * priv)374 static ulong rk3128_spi_get_clk(struct rk3128_clk_priv *priv)
375 {
376 	struct rk3128_cru *cru = priv->cru;
377 	u32 div, con, parent;
378 
379 	con = readl(&cru->cru_clksel_con[25]);
380 	div = (con & SPI_DIV_MASK) >> SPI_DIV_SHIFT;
381 	parent = priv->gpll_hz;
382 
383 	return DIV_TO_RATE(parent, div);
384 }
385 
rk3128_spi_set_clk(struct rk3128_clk_priv * priv,ulong hz)386 static ulong rk3128_spi_set_clk(struct rk3128_clk_priv *priv, ulong hz)
387 {
388 	struct rk3128_cru *cru = priv->cru;
389 	int div;
390 
391 	div = DIV_ROUND_UP(priv->gpll_hz, hz);
392 	assert(div - 1 < 128);
393 	rk_clrsetreg(&cru->cru_clksel_con[25],
394 		     SPI_PLL_SEL_MASK | SPI_DIV_MASK,
395 		     SPI_PLL_SEL_GPLL << SPI_PLL_SEL_SHIFT |
396 		     (div - 1) << SPI_DIV_SHIFT);
397 	return rk3128_spi_get_clk(priv);
398 }
399 
400 #ifndef CONFIG_SPL_BUILD
rk3128_saradc_get_clk(struct rk3128_clk_priv * priv)401 static ulong rk3128_saradc_get_clk(struct rk3128_clk_priv *priv)
402 {
403 	struct rk3128_cru *cru = priv->cru;
404 	u32 div, val;
405 
406 	val = readl(&cru->cru_clksel_con[24]);
407 	div = bitfield_extract(val, SARADC_DIV_CON_SHIFT,
408 			       SARADC_DIV_CON_WIDTH);
409 
410 	return DIV_TO_RATE(OSC_HZ, div);
411 }
412 
rk3128_saradc_set_clk(struct rk3128_clk_priv * priv,uint hz)413 static ulong rk3128_saradc_set_clk(struct rk3128_clk_priv *priv, uint hz)
414 {
415 	struct rk3128_cru *cru = priv->cru;
416 	int src_clk_div;
417 
418 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
419 	assert(src_clk_div < 128);
420 
421 	rk_clrsetreg(&cru->cru_clksel_con[24],
422 		     SARADC_DIV_CON_MASK,
423 		     src_clk_div << SARADC_DIV_CON_SHIFT);
424 
425 	return rk3128_saradc_get_clk(priv);
426 }
427 
428 #define RK3128_LCDC_PLL_LIMIT			600000000
429 
rk3128_vop_set_clk(struct rk3128_clk_priv * priv,ulong clk_id,uint hz)430 static ulong rk3128_vop_set_clk(struct rk3128_clk_priv *priv,
431 				ulong clk_id, uint hz)
432 {
433 	struct rk3128_cru *cru = priv->cru;
434 	int src_clk_div;
435 
436 	src_clk_div = GPLL_HZ / hz;
437 	assert(src_clk_div - 1 < 31);
438 
439 	switch (clk_id) {
440 	case ACLK_LCDC0:
441 	case ACLK_VIO0:
442 		rk_clrsetreg(&cru->cru_clksel_con[31],
443 			     VIO0_PLL_MASK | VIO0_DIV_MASK,
444 			     VIO0_SEL_GPLL << VIO0_PLL_SHIFT |
445 			     (src_clk_div - 1) << VIO0_DIV_SHIFT);
446 		break;
447 	case ACLK_VIO1:
448 		rk_clrsetreg(&cru->cru_clksel_con[31],
449 			     VIO1_PLL_MASK | VIO1_DIV_MASK,
450 			     VIO1_SEL_GPLL << VIO1_PLL_SHIFT |
451 			     (src_clk_div - 1) << VIO1_DIV_SHIFT);
452 		break;
453 	case DCLK_VOP:
454 		src_clk_div = DIV_ROUND_UP(RK3128_LCDC_PLL_LIMIT, hz);
455 		rockchip_pll_set_rate(&rk3128_pll_clks[CPLL],
456 				      priv->cru, CPLL, src_clk_div * hz);
457 		rk_clrsetreg(&cru->cru_clksel_con[27],
458 			      DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_CON_MASK,
459 			     DCLK_VOP_PLL_SEL_CPLL << DCLK_VOP_SEL_SHIFT |
460 			     (src_clk_div - 1) << DCLK_VOP_DIV_CON_SHIFT);
461 		break;
462 	default:
463 		printf("do not support this vop freq\n");
464 		return -EINVAL;
465 	}
466 
467 	return hz;
468 }
469 
rk3128_vop_get_rate(struct rk3128_clk_priv * priv,ulong clk_id)470 static ulong rk3128_vop_get_rate(struct rk3128_clk_priv *priv, ulong clk_id)
471 {
472 	struct rk3128_cru *cru = priv->cru;
473 	u32 div, con, parent;
474 
475 	switch (clk_id) {
476 	case ACLK_LCDC0:
477 	case ACLK_VIO0:
478 		con = readl(&cru->cru_clksel_con[31]);
479 		div = con  & 0x1f;
480 		parent = GPLL_HZ;
481 		break;
482 	case ACLK_VIO1:
483 		con = readl(&cru->cru_clksel_con[31]);
484 		div = (con >> 8) & 0x1f;
485 		parent = GPLL_HZ;
486 		break;
487 	case DCLK_VOP:
488 		con = readl(&cru->cru_clksel_con[27]);
489 		div = (con & DCLK_VOP_DIV_CON_MASK) >> DCLK_VOP_DIV_CON_SHIFT;
490 		parent = rockchip_pll_get_rate(&rk3128_pll_clks[CPLL],
491 					       priv->cru, CPLL);
492 		break;
493 	default:
494 		return -ENOENT;
495 	}
496 	return DIV_TO_RATE(parent, div);
497 }
498 
rk3128_crypto_get_rate(struct rk3128_clk_priv * priv)499 static ulong rk3128_crypto_get_rate(struct rk3128_clk_priv *priv)
500 {
501 	struct rk3128_cru *cru = priv->cru;
502 	u32 div, val;
503 
504 	val = readl(&cru->cru_clksel_con[24]);
505 	div = (val & CLK_CRYPTO_DIV_CON_MASK) >> CLK_CRYPTO_DIV_CON_SHIFT;
506 
507 	return DIV_TO_RATE(rk3128_bus_get_clk(priv, ACLK_CPU), div);
508 }
509 
rk3128_crypto_set_rate(struct rk3128_clk_priv * priv,uint hz)510 static ulong rk3128_crypto_set_rate(struct rk3128_clk_priv *priv,
511 				    uint hz)
512 {
513 	struct rk3128_cru *cru = priv->cru;
514 	int src_clk_div;
515 	uint p_rate;
516 
517 	p_rate = rk3128_bus_get_clk(priv, ACLK_CPU);
518 	src_clk_div = DIV_ROUND_UP(p_rate, hz) - 1;
519 	assert(src_clk_div < 3);
520 
521 	rk_clrsetreg(&cru->cru_clksel_con[24],
522 		     CLK_CRYPTO_DIV_CON_MASK,
523 		     src_clk_div << CLK_CRYPTO_DIV_CON_SHIFT);
524 
525 	return rk3128_crypto_get_rate(priv);
526 }
527 #endif
528 
rk3128_clk_get_rate(struct clk * clk)529 static ulong rk3128_clk_get_rate(struct clk *clk)
530 {
531 	struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
532 	ulong rate = 0;
533 
534 	switch (clk->id) {
535 	case PLL_APLL:
536 	case PLL_DPLL:
537 	case PLL_CPLL:
538 	case PLL_GPLL:
539 		rate =  rockchip_pll_get_rate(&rk3128_pll_clks[clk->id - 1],
540 					      priv->cru, clk->id - 1);
541 		break;
542 	case ARMCLK:
543 		rate = rockchip_pll_get_rate(&rk3128_pll_clks[APLL],
544 					     priv->cru, APLL);
545 		break;
546 	case HCLK_EMMC:
547 	case SCLK_EMMC:
548 	case HCLK_SDMMC:
549 	case SCLK_SDMMC:
550 	case HCLK_SDIO:
551 	case SCLK_SDIO:
552 		rate = rockchip_mmc_get_clk(priv, clk->id);
553 		break;
554 	case ACLK_PERI:
555 	case HCLK_PERI:
556 	case PCLK_PERI:
557 	case PCLK_I2C0:
558 	case PCLK_I2C1:
559 	case PCLK_I2C2:
560 	case PCLK_I2C3:
561 	case PCLK_PWM:
562 	case PCLK_WDT:
563 		rate = rk3128_peri_get_clk(priv, clk->id);
564 		break;
565 	case ACLK_CPU:
566 	case HCLK_CPU:
567 	case PCLK_CPU:
568 		rate = rk3128_bus_get_clk(priv, clk->id);
569 		break;
570 	case SCLK_SPI0:
571 		rate = rk3128_spi_get_clk(priv);
572 		break;
573 #ifndef CONFIG_SPL_BUILD
574 	case SCLK_SARADC:
575 		rate = rk3128_saradc_get_clk(priv);
576 		break;
577 	case DCLK_VOP:
578 	case ACLK_VIO0:
579 	case ACLK_VIO1:
580 	case ACLK_LCDC0:
581 		rate = rk3128_vop_get_rate(priv, clk->id);
582 		break;
583 	case SCLK_CRYPTO:
584 		rate = rk3128_crypto_get_rate(priv);
585 		break;
586 #endif
587 	default:
588 		return -ENOENT;
589 	}
590 	return rate;
591 }
592 
rk3128_clk_set_rate(struct clk * clk,ulong rate)593 static ulong rk3128_clk_set_rate(struct clk *clk, ulong rate)
594 {
595 	struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
596 	ulong ret = 0;
597 
598 	switch (clk->id) {
599 	case PLL_APLL:
600 	case PLL_DPLL:
601 	case PLL_CPLL:
602 		ret = rockchip_pll_set_rate(&rk3128_pll_clks[clk->id - 1],
603 					    priv->cru, clk->id - 1, rate);
604 	case PLL_GPLL:
605 		ret = rockchip_pll_set_rate(&rk3128_pll_clks[GPLL],
606 					    priv->cru, GPLL, rate);
607 		priv->gpll_hz = rate;
608 		break;
609 	case ARMCLK:
610 		if (priv->armclk_hz)
611 			ret = rk3128_armclk_set_clk(priv, rate);
612 		priv->armclk_hz = rate;
613 		break;
614 	case HCLK_EMMC:
615 	case SCLK_EMMC:
616 	case SCLK_EMMC_SAMPLE:
617 	case HCLK_SDMMC:
618 	case SCLK_SDMMC:
619 	case SCLK_SDMMC_SAMPLE:
620 	case HCLK_SDIO:
621 	case SCLK_SDIO:
622 	case SCLK_SDIO_SAMPLE:
623 		ret = rockchip_mmc_set_clk(priv, clk->id, rate);
624 		break;
625 	case ACLK_PERI:
626 	case PCLK_PERI:
627 	case HCLK_PERI:
628 	case PCLK_I2C0:
629 	case PCLK_I2C1:
630 	case PCLK_I2C2:
631 	case PCLK_I2C3:
632 	case PCLK_PWM:
633 		ret = rk3128_peri_set_clk(priv, clk->id, rate);
634 		break;
635 	case ACLK_CPU:
636 	case HCLK_CPU:
637 	case PCLK_CPU:
638 		ret = rk3128_bus_set_clk(priv, clk->id, rate);
639 		break;
640 	case SCLK_SPI0:
641 		rate = rk3128_spi_set_clk(priv, rate);
642 		break;
643 #ifndef CONFIG_SPL_BUILD
644 	case SCLK_SARADC:
645 		ret = rk3128_saradc_set_clk(priv, rate);
646 		break;
647 	case DCLK_VOP:
648 	case ACLK_VIO0:
649 	case ACLK_VIO1:
650 	case ACLK_LCDC0:
651 		ret = rk3128_vop_set_clk(priv, clk->id, rate);
652 		break;
653 	case SCLK_CRYPTO:
654 		ret = rk3128_crypto_set_rate(priv, rate);
655 		break;
656 #endif
657 	default:
658 		return -ENOENT;
659 	}
660 	return ret;
661 }
662 
663 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
664 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
665 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
666 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
667 
668 #define PSECS_PER_SEC 1000000000000LL
669 /*
670  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
671  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
672  */
673 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
674 
rk3128_mmc_get_phase(struct clk * clk)675 int rk3128_mmc_get_phase(struct clk *clk)
676 {
677 	struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
678 	struct rk3128_cru *cru = priv->cru;
679 	u32 raw_value, delay_num;
680 	u16 degrees = 0;
681 	ulong rate;
682 
683 	rate = rk3128_clk_get_rate(clk);
684 
685 	if (rate < 0)
686 		return rate;
687 
688 	if (clk->id == SCLK_EMMC_SAMPLE)
689 		raw_value = readl(&cru->cru_emmc_con[1]);
690 	else if (clk->id == SCLK_SDMMC_SAMPLE)
691 		raw_value = readl(&cru->cru_sdmmc_con[1]);
692 	else
693 		raw_value = readl(&cru->cru_sdio_con[1]);
694 
695 	raw_value >>= 1;
696 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
697 
698 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
699 		/* degrees/delaynum * 10000 */
700 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
701 					36 * (rate / 1000000);
702 
703 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
704 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
705 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
706 	}
707 
708 	return degrees % 360;
709 }
710 
rk3128_mmc_set_phase(struct clk * clk,u32 degrees)711 int rk3128_mmc_set_phase(struct clk *clk, u32 degrees)
712 {
713 	struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
714 	struct rk3128_cru *cru = priv->cru;
715 	u8 nineties, remainder, delay_num;
716 	u32 raw_value, delay;
717 	ulong rate;
718 
719 	rate = rk3128_clk_get_rate(clk);
720 
721 	if (rate < 0)
722 		return rate;
723 
724 	nineties = degrees / 90;
725 	remainder = (degrees % 90);
726 
727 	/*
728 	 * Convert to delay; do a little extra work to make sure we
729 	 * don't overflow 32-bit / 64-bit numbers.
730 	 */
731 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
732 	delay *= remainder;
733 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
734 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
735 
736 	delay_num = (u8)min_t(u32, delay, 255);
737 
738 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
739 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
740 	raw_value |= nineties;
741 
742 	raw_value <<= 1;
743 	if (clk->id == SCLK_EMMC_SAMPLE)
744 		writel(raw_value | 0xffff0000, &cru->cru_emmc_con[1]);
745 	else if (clk->id == SCLK_SDMMC_SAMPLE)
746 		writel(raw_value | 0xffff0000, &cru->cru_sdmmc_con[1]);
747 	else
748 		writel(raw_value | 0xffff0000, &cru->cru_sdio_con[1]);
749 
750 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
751 	      degrees, delay_num, raw_value, rk3128_mmc_get_phase(clk));
752 
753 	return 0;
754 }
755 
rk3128_clk_get_phase(struct clk * clk)756 static int rk3128_clk_get_phase(struct clk *clk)
757 {
758 	int ret;
759 
760 	debug("%s %ld\n", __func__, clk->id);
761 	switch (clk->id) {
762 	case SCLK_EMMC_SAMPLE:
763 	case SCLK_SDMMC_SAMPLE:
764 	case SCLK_SDIO_SAMPLE:
765 		ret = rk3128_mmc_get_phase(clk);
766 		break;
767 	default:
768 		return -ENOENT;
769 	}
770 
771 	return ret;
772 }
773 
rk3128_clk_set_phase(struct clk * clk,int degrees)774 static int rk3128_clk_set_phase(struct clk *clk, int degrees)
775 {
776 	int ret;
777 
778 	debug("%s %ld\n", __func__, clk->id);
779 	switch (clk->id) {
780 	case SCLK_EMMC_SAMPLE:
781 	case SCLK_SDMMC_SAMPLE:
782 	case SCLK_SDIO_SAMPLE:
783 		ret = rk3128_mmc_set_phase(clk, degrees);
784 		break;
785 	default:
786 		return -ENOENT;
787 	}
788 
789 	return ret;
790 }
791 
792 static struct clk_ops rk3128_clk_ops = {
793 	.get_rate	= rk3128_clk_get_rate,
794 	.set_rate	= rk3128_clk_set_rate,
795 	.get_phase	= rk3128_clk_get_phase,
796 	.set_phase	= rk3128_clk_set_phase,
797 };
798 
rk3128_clk_ofdata_to_platdata(struct udevice * dev)799 static int rk3128_clk_ofdata_to_platdata(struct udevice *dev)
800 {
801 	struct rk3128_clk_priv *priv = dev_get_priv(dev);
802 
803 	priv->cru = dev_read_addr_ptr(dev);
804 
805 	return 0;
806 }
807 
rkclk_init(struct rk3128_clk_priv * priv)808 static void rkclk_init(struct rk3128_clk_priv *priv)
809 {
810 	if (rockchip_pll_get_rate(&rk3128_pll_clks[APLL],
811 				  priv->cru, APLL) != APLL_HZ)
812 		rk3128_armclk_set_clk(priv, APLL_HZ);
813 
814 	priv->gpll_hz = rockchip_pll_get_rate(&rk3128_pll_clks[GPLL],
815 					      priv->cru, GPLL);
816 	rk3128_bus_set_clk(priv, ACLK_CPU, ACLK_BUS_HZ / 2);
817 	rk3128_peri_set_clk(priv, ACLK_PERI, ACLK_PERI_HZ / 2);
818 	rockchip_pll_set_rate(&rk3128_pll_clks[GPLL],
819 			      priv->cru, GPLL, GPLL_HZ);
820 	priv->gpll_hz = GPLL_HZ;
821 	rk_clrsetreg(&priv->cru->cru_clksel_con[2],
822 		     NANDC_PLL_SEL_MASK | NANDC_CLK_DIV_MASK,
823 		     NANDC_PLL_SEL_GPLL << NANDC_PLL_SEL_SHIFT |
824 		     3 << NANDC_CLK_DIV_SHIFT);
825 	rk_clrsetreg(&priv->cru->cru_clksel_con[11],
826 		     SFC_PLL_SEL_MASK | SFC_CLK_DIV_MASK,
827 		     SFC_PLL_SEL_GPLL << SFC_PLL_SEL_SHIFT |
828 		     9 << SFC_CLK_DIV_SHIFT);
829 
830 	rk3128_bus_set_clk(priv, ACLK_CPU, ACLK_BUS_HZ);
831 	rk3128_bus_set_clk(priv, HCLK_CPU, ACLK_BUS_HZ / 2);
832 	rk3128_bus_set_clk(priv, PCLK_CPU, ACLK_BUS_HZ / 2);
833 	rk3128_peri_set_clk(priv, ACLK_PERI, ACLK_PERI_HZ);
834 	rk3128_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2);
835 	rk3128_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2);
836 
837 	rockchip_pll_set_rate(&rk3128_pll_clks[CPLL],
838 			      priv->cru, CPLL, CPLL_HZ);
839 }
840 
rk3128_clk_probe(struct udevice * dev)841 static int rk3128_clk_probe(struct udevice *dev)
842 {
843 	struct rk3128_clk_priv *priv = dev_get_priv(dev);
844 
845 	priv->sync_kernel = false;
846 	if (!priv->armclk_enter_hz)
847 		priv->armclk_enter_hz =
848 		rockchip_pll_get_rate(&rk3128_pll_clks[APLL],
849 				      priv->cru, APLL);
850 	rkclk_init(priv);
851 	if (!priv->armclk_init_hz)
852 		priv->armclk_init_hz =
853 		rockchip_pll_get_rate(&rk3128_pll_clks[APLL],
854 				      priv->cru, APLL);
855 
856 	return 0;
857 }
858 
rk3128_clk_bind(struct udevice * dev)859 static int rk3128_clk_bind(struct udevice *dev)
860 {
861 	int ret;
862 	struct udevice *sys_child, *sf_child;
863 	struct sysreset_reg *priv;
864 	struct softreset_reg *sf_priv;
865 
866 	/* The reset driver does not have a device node, so bind it here */
867 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
868 				 &sys_child);
869 	if (ret) {
870 		debug("Warning: No sysreset driver: ret=%d\n", ret);
871 	} else {
872 		priv = malloc(sizeof(struct sysreset_reg));
873 		priv->glb_srst_fst_value = offsetof(struct rk3128_cru,
874 						    cru_glb_srst_fst_value);
875 		priv->glb_srst_snd_value = offsetof(struct rk3128_cru,
876 						    cru_glb_srst_snd_value);
877 		sys_child->priv = priv;
878 	}
879 
880 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
881 					 dev_ofnode(dev), &sf_child);
882 	if (ret) {
883 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
884 	} else {
885 		sf_priv = malloc(sizeof(struct softreset_reg));
886 		sf_priv->sf_reset_offset = offsetof(struct rk3128_cru,
887 						    cru_softrst_con[0]);
888 		sf_priv->sf_reset_num = 9;
889 		sf_child->priv = sf_priv;
890 	}
891 
892 	return 0;
893 }
894 
895 static const struct udevice_id rk3128_clk_ids[] = {
896 	{ .compatible = "rockchip,rk3128-cru" },
897 	{ .compatible = "rockchip,rk3126-cru" },
898 	{ }
899 };
900 
901 U_BOOT_DRIVER(rockchip_rk3128_cru) = {
902 	.name		= "clk_rk3128",
903 	.id		= UCLASS_CLK,
904 	.of_match	= rk3128_clk_ids,
905 	.priv_auto_alloc_size = sizeof(struct rk3128_clk_priv),
906 	.ofdata_to_platdata = rk3128_clk_ofdata_to_platdata,
907 	.ops		= &rk3128_clk_ops,
908 	.bind		= rk3128_clk_bind,
909 	.probe		= rk3128_clk_probe,
910 };
911 
912 #ifndef CONFIG_SPL_BUILD
913 /**
914  * soc_clk_dump() - Print clock frequencies
915  * Returns zero on success
916  *
917  * Implementation for the clk dump command.
918  */
soc_clk_dump(void)919 int soc_clk_dump(void)
920 {
921 	struct udevice *cru_dev;
922 	struct rk3128_clk_priv *priv;
923 	const struct rk3128_clk_info *clk_dump;
924 	struct clk clk;
925 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
926 	unsigned long rate;
927 	int i, ret;
928 
929 	ret = uclass_get_device_by_driver(UCLASS_CLK,
930 					  DM_GET_DRIVER(rockchip_rk3128_cru),
931 					  &cru_dev);
932 	if (ret) {
933 		printf("%s failed to get cru device\n", __func__);
934 		return ret;
935 	}
936 
937 	priv = dev_get_priv(cru_dev);
938 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
939 	       priv->sync_kernel ? "sync kernel" : "uboot",
940 	       priv->armclk_enter_hz / 1000,
941 	       priv->armclk_init_hz / 1000,
942 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
943 	       priv->set_armclk_rate ? " KHz" : "N/A");
944 	for (i = 0; i < clk_count; i++) {
945 		clk_dump = &clks_dump[i];
946 		if (clk_dump->name) {
947 			clk.id = clk_dump->id;
948 			if (clk_dump->is_cru)
949 				ret = clk_request(cru_dev, &clk);
950 			if (ret < 0)
951 				return ret;
952 
953 			rate = clk_get_rate(&clk);
954 			clk_free(&clk);
955 			if (i == 0) {
956 				if (rate < 0)
957 					printf("  %s %s\n", clk_dump->name,
958 					       "unknown");
959 				else
960 					printf("  %s %lu KHz\n", clk_dump->name,
961 					       rate / 1000);
962 			} else {
963 				if (rate < 0)
964 					printf("  %s %s\n", clk_dump->name,
965 					       "unknown");
966 				else
967 					printf("  %s %lu KHz\n", clk_dump->name,
968 					       rate / 1000);
969 			}
970 		}
971 	}
972 
973 	return 0;
974 }
975 #endif
976 
977