xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3328.c (revision 73b4df6a98d2d973cbf1e2b18947abbdbdb82bc1)
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 <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk3328.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/grf_rk3328.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rk3328-cru.h>
20 
21 DECLARE_GLOBAL_DATA_PTR;
22 
23 #define RATE_TO_DIV(input_rate, output_rate) \
24 	((input_rate) / (output_rate) - 1);
25 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
26 
27 #ifndef CONFIG_SPL_BUILD
28 #define RK3328_CLK_DUMP(_id, _name, _iscru)	\
29 {						\
30 	.id = _id,				\
31 	.name = _name,				\
32 	.is_cru = _iscru,			\
33 }
34 #endif
35 
36 static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
37 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
38 	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
39 #ifndef CONFIG_SPL_BUILD
40 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
41 	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
42 #endif
43 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
44 	RK3036_PLL_RATE(800000000, 1, 200, 6, 1, 1, 0),
45 	RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
46 #ifndef CONFIG_SPL_BUILD
47 	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
48 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
49 #endif
50 	{ /* sentinel */ },
51 };
52 
53 static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
54 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
55 #ifndef CONFIG_SPL_BUILD
56 	RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217),
57 	/* vco = 1016064000 */
58 	RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088),
59 	/* vco = 983040000 */
60 #endif
61 	RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088),
62 	/* vco = 983040000 */
63 #ifndef CONFIG_SPL_BUILD
64 	RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088),
65 	/* vco = 860156000 */
66 	RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894),
67 	/* vco = 903168000 */
68 	RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329),
69 	/* vco = 819200000 */
70 #endif
71 	{ /* sentinel */ },
72 };
73 
74 #define RK3328_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
75 {								\
76 	.rate	= _rate##U,					\
77 	.aclk_div = _aclk_div,					\
78 	.pclk_div = _pclk_div,					\
79 }
80 
81 static struct rockchip_cpu_rate_table rk3328_cpu_rates[] = {
82 	RK3328_CPUCLK_RATE(1200000000, 1, 5),
83 	RK3328_CPUCLK_RATE(1008000000, 1, 5),
84 	RK3328_CPUCLK_RATE(816000000, 1, 3),
85 	RK3328_CPUCLK_RATE(600000000, 1, 3),
86 };
87 
88 #ifndef CONFIG_SPL_BUILD
89 static const struct rk3328_clk_info clks_dump[] = {
90 	RK3328_CLK_DUMP(PLL_APLL, "apll", true),
91 	RK3328_CLK_DUMP(PLL_DPLL, "dpll", true),
92 	RK3328_CLK_DUMP(PLL_CPLL, "cpll", true),
93 	RK3328_CLK_DUMP(PLL_GPLL, "gpll", true),
94 	RK3328_CLK_DUMP(PLL_NPLL, "npll", true),
95 	RK3328_CLK_DUMP(ARMCLK, "armclk", true),
96 	RK3328_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true),
97 	RK3328_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true),
98 	RK3328_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true),
99 	RK3328_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true),
100 	RK3328_CLK_DUMP(HCLK_PERI, "hclk_peri", true),
101 	RK3328_CLK_DUMP(PCLK_PERI, "pclk_peri", true),
102 };
103 #endif
104 
105 static struct rockchip_pll_clock rk3328_pll_clks[] = {
106 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3328_PLL_CON(0),
107 		     RK3328_MODE_CON, 0, 10, 0, rk3328_pll_frac_rates),
108 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3328_PLL_CON(8),
109 		     RK3328_MODE_CON, 4, 10, 0, NULL),
110 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3328_PLL_CON(16),
111 		    RK3328_MODE_CON, 8, 10, 0, rk3328_pll_rates),
112 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3328_PLL_CON(24),
113 		     RK3328_MODE_CON, 12, 10, 0, rk3328_pll_frac_rates),
114 	[NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3328_PLL_CON(40),
115 		     RK3328_MODE_CON, 1, 10, 0, rk3328_pll_rates),
116 };
117 
118 static ulong rk3328_armclk_set_clk(struct rk3328_clk_priv *priv, ulong hz)
119 {
120 	struct rk3328_cru *cru = priv->cru;
121 	const struct rockchip_cpu_rate_table *rate;
122 	ulong old_rate;
123 
124 	rate = rockchip_get_cpu_settings(rk3328_cpu_rates, hz);
125 	if (!rate) {
126 		printf("%s unsupported rate\n", __func__);
127 		return -EINVAL;
128 	}
129 
130 	/*
131 	 * select apll as cpu/core clock pll source and
132 	 * set up dependent divisors for PERI and ACLK clocks.
133 	 * core hz : apll = 1:1
134 	 */
135 	old_rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
136 					 priv->cru, NPLL);
137 	if (old_rate > hz) {
138 		if (rockchip_pll_set_rate(&rk3328_pll_clks[NPLL],
139 					  priv->cru, NPLL, hz))
140 			return -EINVAL;
141 		rk_clrsetreg(&cru->clksel_con[0],
142 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
143 			     CORE_CLK_PLL_SEL_NPLL << CORE_CLK_PLL_SEL_SHIFT |
144 			     0 << CORE_DIV_CON_SHIFT);
145 		rk_clrsetreg(&cru->clksel_con[1],
146 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
147 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
148 			     rate->pclk_div << CORE_DBG_DIV_SHIFT);
149 	} else if (old_rate < hz) {
150 		rk_clrsetreg(&cru->clksel_con[1],
151 			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
152 			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
153 			     rate->pclk_div << CORE_DBG_DIV_SHIFT);
154 		rk_clrsetreg(&cru->clksel_con[0],
155 			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
156 			     CORE_CLK_PLL_SEL_NPLL << CORE_CLK_PLL_SEL_SHIFT |
157 			     0 << CORE_DIV_CON_SHIFT);
158 		if (rockchip_pll_set_rate(&rk3328_pll_clks[NPLL],
159 					  priv->cru, NPLL, hz))
160 			return -EINVAL;
161 	}
162 
163 	return rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], priv->cru, NPLL);
164 }
165 
166 #ifndef CONFIG_SPL_BUILD
167 static ulong rk3328_i2c_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
168 {
169 	struct rk3328_cru *cru = priv->cru;
170 	u32 div, con;
171 
172 	switch (clk_id) {
173 	case SCLK_I2C0:
174 		con = readl(&cru->clksel_con[34]);
175 		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
176 		break;
177 	case SCLK_I2C1:
178 		con = readl(&cru->clksel_con[34]);
179 		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
180 		break;
181 	case SCLK_I2C2:
182 		con = readl(&cru->clksel_con[35]);
183 		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
184 		break;
185 	case SCLK_I2C3:
186 		con = readl(&cru->clksel_con[35]);
187 		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
188 		break;
189 	default:
190 		printf("do not support this i2c bus\n");
191 		return -EINVAL;
192 	}
193 
194 	return DIV_TO_RATE(priv->gpll_hz, div);
195 }
196 
197 static ulong rk3328_i2c_set_clk(struct rk3328_clk_priv *priv,
198 				ulong clk_id, uint hz)
199 {
200 	struct rk3328_cru *cru = priv->cru;
201 	int src_clk_div;
202 
203 	src_clk_div = priv->gpll_hz / hz;
204 	assert(src_clk_div - 1 < 127);
205 
206 	switch (clk_id) {
207 	case SCLK_I2C0:
208 		rk_clrsetreg(&cru->clksel_con[34],
209 			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
210 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
211 			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
212 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
213 		break;
214 	case SCLK_I2C1:
215 		rk_clrsetreg(&cru->clksel_con[34],
216 			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
217 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
218 			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
219 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
220 		break;
221 	case SCLK_I2C2:
222 		rk_clrsetreg(&cru->clksel_con[35],
223 			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
224 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
225 			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
226 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
227 		break;
228 	case SCLK_I2C3:
229 		rk_clrsetreg(&cru->clksel_con[35],
230 			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
231 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
232 			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
233 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
234 		break;
235 	default:
236 		printf("do not support this i2c bus\n");
237 		return -EINVAL;
238 	}
239 
240 	return DIV_TO_RATE(priv->gpll_hz, src_clk_div);
241 }
242 
243 static ulong rk3328_gmac2io_set_clk(struct rk3328_clk_priv *priv, ulong rate)
244 {
245 	struct rk3328_cru *cru = priv->cru;
246 	struct rk3328_grf_regs *grf;
247 	ulong ret;
248 
249 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
250 
251 	/*
252 	 * The RGMII CLK can be derived either from an external "clkin"
253 	 * or can be generated from internally by a divider from SCLK_MAC.
254 	 */
255 	if (readl(&grf->mac_con[1]) & BIT(10) &&
256 	    readl(&grf->soc_con[4]) & BIT(14)) {
257 		/* An external clock will always generate the right rate... */
258 		ret = rate;
259 	} else {
260 		u32 con = readl(&cru->clksel_con[27]);
261 		ulong pll_rate;
262 		u8 div;
263 
264 		if ((con >> GMAC2IO_PLL_SEL_SHIFT) & GMAC2IO_PLL_SEL_GPLL)
265 			pll_rate = priv->gpll_hz;
266 		else
267 			pll_rate = priv->cpll_hz;
268 
269 		div = DIV_ROUND_UP(pll_rate, rate) - 1;
270 		if (div <= 0x1f)
271 			rk_clrsetreg(&cru->clksel_con[27], GMAC2IO_CLK_DIV_MASK,
272 				     div << GMAC2IO_CLK_DIV_SHIFT);
273 		else
274 			debug("Unsupported div for gmac:%d\n", div);
275 
276 		return DIV_TO_RATE(pll_rate, div);
277 	}
278 
279 	return ret;
280 }
281 #endif
282 
283 static ulong rk3328_mmc_get_clk(struct rk3328_clk_priv *priv, uint clk_id)
284 {
285 	struct rk3328_cru *cru = priv->cru;
286 	u32 div, con, con_id;
287 
288 	switch (clk_id) {
289 	case HCLK_SDMMC:
290 	case SCLK_SDMMC:
291 		con_id = 30;
292 		break;
293 	case HCLK_EMMC:
294 	case SCLK_EMMC:
295 	case SCLK_EMMC_SAMPLE:
296 		con_id = 32;
297 		break;
298 	default:
299 		return -EINVAL;
300 	}
301 	con = readl(&cru->clksel_con[con_id]);
302 	div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
303 
304 	if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
305 	    == CLK_EMMC_PLL_SEL_24M)
306 		return DIV_TO_RATE(OSC_HZ, div) / 2;
307 	else
308 		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
309 }
310 
311 static ulong rk3328_mmc_set_clk(struct rk3328_clk_priv *priv,
312 				ulong clk_id, ulong set_rate)
313 {
314 	struct rk3328_cru *cru = priv->cru;
315 	int src_clk_div;
316 	u32 con_id;
317 
318 	switch (clk_id) {
319 	case HCLK_SDMMC:
320 	case SCLK_SDMMC:
321 		con_id = 30;
322 		break;
323 	case HCLK_EMMC:
324 	case SCLK_EMMC:
325 		con_id = 32;
326 		break;
327 	default:
328 		return -EINVAL;
329 	}
330 	/* Select clk_sdmmc/emmc source from GPLL by default */
331 	/* mmc clock defaulg div 2 internal, need provide double in cru */
332 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
333 
334 	if (src_clk_div > 127) {
335 		/* use 24MHz source for 400KHz clock */
336 		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
337 		rk_clrsetreg(&cru->clksel_con[con_id],
338 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
339 			     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
340 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
341 	} else {
342 		rk_clrsetreg(&cru->clksel_con[con_id],
343 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
344 			     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
345 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
346 	}
347 
348 	return rk3328_mmc_get_clk(priv, clk_id);
349 }
350 
351 static ulong rk3328_spi_get_clk(struct rk3328_clk_priv *priv)
352 {
353 	struct rk3328_cru *cru = priv->cru;
354 	u32 div, con, mux, p_rate;
355 
356 	con = readl(&cru->clksel_con[24]);
357 	div = (con & CLK_SPI_DIV_CON_MASK) >> CLK_SPI_DIV_CON_SHIFT;
358 	mux = (con & CLK_SPI_PLL_SEL_MASK) >> CLK_SPI_PLL_SEL_SHIFT;
359 	if (mux)
360 		p_rate = priv->gpll_hz;
361 	else
362 		p_rate = priv->cpll_hz;
363 
364 	return DIV_TO_RATE(p_rate, div);
365 }
366 
367 static ulong rk3328_spi_set_clk(struct rk3328_clk_priv *priv, uint hz)
368 {
369 	struct rk3328_cru *cru = priv->cru;
370 	u32 div = priv->gpll_hz / hz;
371 
372 	rk_clrsetreg(&cru->clksel_con[24],
373 		     CLK_SPI_PLL_SEL_MASK | CLK_SPI_DIV_CON_MASK,
374 		     CLK_SPI_PLL_SEL_GPLL << CLK_SPI_PLL_SEL_SHIFT |
375 		     (div - 1) << CLK_SPI_DIV_CON_SHIFT);
376 
377 	return DIV_TO_RATE(priv->gpll_hz, div);
378 }
379 
380 #ifndef CONFIG_SPL_BUILD
381 static ulong rk3328_pwm_get_clk(struct rk3328_clk_priv *priv)
382 {
383 	struct rk3328_cru *cru = priv->cru;
384 	u32 div, con;
385 
386 	con = readl(&cru->clksel_con[24]);
387 	div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
388 
389 	return DIV_TO_RATE(priv->gpll_hz, div);
390 }
391 
392 static ulong rk3328_pwm_set_clk(struct rk3328_clk_priv *priv, uint hz)
393 {
394 	struct rk3328_cru *cru = priv->cru;
395 	u32 div = priv->gpll_hz / hz;
396 
397 	rk_clrsetreg(&cru->clksel_con[24],
398 		     CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
399 		     CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT |
400 		     (div - 1) << CLK_PWM_DIV_CON_SHIFT);
401 
402 	return DIV_TO_RATE(priv->gpll_hz, div);
403 }
404 
405 static ulong rk3328_saradc_get_clk(struct rk3328_clk_priv *priv)
406 {
407 	struct rk3328_cru *cru = priv->cru;
408 	u32 div, val;
409 
410 	val = readl(&cru->clksel_con[23]);
411 	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
412 			       CLK_SARADC_DIV_CON_WIDTH);
413 
414 	return DIV_TO_RATE(OSC_HZ, div);
415 }
416 
417 static ulong rk3328_saradc_set_clk(struct rk3328_clk_priv *priv, uint hz)
418 {
419 	struct rk3328_cru *cru = priv->cru;
420 	int src_clk_div;
421 
422 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
423 	assert(src_clk_div < 128);
424 
425 	rk_clrsetreg(&cru->clksel_con[23],
426 		     CLK_SARADC_DIV_CON_MASK,
427 		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
428 
429 	return rk3328_saradc_get_clk(priv);
430 }
431 
432 static ulong rk3328_tsadc_get_clk(struct rk3328_clk_priv *priv)
433 {
434 	struct rk3328_cru *cru = priv->cru;
435 	u32 div, val;
436 
437 	val = readl(&cru->clksel_con[22]);
438 	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
439 			       CLK_SARADC_DIV_CON_WIDTH);
440 
441 	return DIV_TO_RATE(OSC_HZ, div);
442 }
443 
444 static ulong rk3328_tsadc_set_clk(struct rk3328_clk_priv *priv, uint hz)
445 {
446 	struct rk3328_cru *cru = priv->cru;
447 	int src_clk_div;
448 
449 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
450 	assert(src_clk_div < 128);
451 
452 	rk_clrsetreg(&cru->clksel_con[22],
453 		     CLK_SARADC_DIV_CON_MASK,
454 		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
455 
456 	return rk3328_tsadc_get_clk(priv);
457 }
458 
459 static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
460 {
461 	struct rk3328_cru *cru = priv->cru;
462 	u32 div, con, parent;
463 
464 	switch (clk_id) {
465 	case ACLK_VOP_PRE:
466 	case ACLK_VOP:
467 		con = readl(&cru->clksel_con[39]);
468 		div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT;
469 		parent = priv->cpll_hz;
470 		break;
471 	case ACLK_VIO_PRE:
472 	case ACLK_VIO:
473 		con = readl(&cru->clksel_con[37]);
474 		div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT;
475 		parent = priv->cpll_hz;
476 		break;
477 	case HCLK_VIO_PRE:
478 	case HCLK_VIO:
479 		parent = rk3328_vop_get_clk(priv, ACLK_VIO_PRE);
480 		con = readl(&cru->clksel_con[37]);
481 		div = (con & HCLK_VIO_DIV_CON_MASK) >> HCLK_VIO_DIV_CON_SHIFT;
482 		break;
483 	default:
484 		return -ENOENT;
485 	}
486 
487 	return DIV_TO_RATE(parent, div);
488 }
489 
490 static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv,
491 				ulong clk_id, uint hz)
492 {
493 	struct rk3328_cru *cru = priv->cru;
494 	int src_clk_div;
495 	u32 con, parent;
496 
497 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
498 	assert(src_clk_div - 1 < 31);
499 
500 	switch (clk_id) {
501 	case ACLK_VOP_PRE:
502 	case ACLK_VOP:
503 		rk_clrsetreg(&cru->clksel_con[39],
504 			     ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
505 			     ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
506 			     (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT);
507 		break;
508 	case ACLK_VIO_PRE:
509 	case ACLK_VIO:
510 		rk_clrsetreg(&cru->clksel_con[37],
511 			     ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK,
512 			     ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT |
513 			     (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT);
514 		break;
515 	case HCLK_VIO_PRE:
516 	case HCLK_VIO:
517 		src_clk_div = DIV_ROUND_UP(rk3328_vop_get_clk(priv,
518 							      ACLK_VIO_PRE),
519 					   hz);
520 		rk_clrsetreg(&cru->clksel_con[37],
521 			     HCLK_VIO_DIV_CON_MASK,
522 			     (src_clk_div - 1) << HCLK_VIO_DIV_CON_SHIFT);
523 		break;
524 	case DCLK_LCDC:
525 		con = readl(&cru->clksel_con[40]);
526 		con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT;
527 		if (con) {
528 			parent = readl(&cru->clksel_con[40]);
529 			parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >>
530 				 DCLK_LCDC_PLL_SEL_SHIFT;
531 			if (parent)
532 				src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
533 			else
534 				src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
535 
536 			rk_clrsetreg(&cru->clksel_con[40],
537 				     DCLK_LCDC_DIV_CON_MASK,
538 				     (src_clk_div - 1) <<
539 				     DCLK_LCDC_DIV_CON_SHIFT);
540 		}
541 		break;
542 	default:
543 		printf("do not support this vop freq\n");
544 		return -EINVAL;
545 	}
546 
547 	return rk3328_vop_get_clk(priv, clk_id);
548 }
549 #endif
550 
551 static ulong rk3328_bus_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
552 {
553 	struct rk3328_cru *cru = priv->cru;
554 	u32 div, con, parent;
555 
556 	switch (clk_id) {
557 	case ACLK_BUS_PRE:
558 		con = readl(&cru->clksel_con[0]);
559 		div = (con & ACLK_BUS_DIV_CON_MASK) >> ACLK_BUS_DIV_CON_SHIFT;
560 		parent = priv->cpll_hz;
561 		break;
562 	case HCLK_BUS_PRE:
563 		con = readl(&cru->clksel_con[1]);
564 		div = (con & HCLK_BUS_DIV_CON_MASK) >> HCLK_BUS_DIV_CON_SHIFT;
565 		parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE);
566 		break;
567 	case PCLK_BUS_PRE:
568 		con = readl(&cru->clksel_con[1]);
569 		div = (con & PCLK_BUS_DIV_CON_MASK) >> PCLK_BUS_DIV_CON_SHIFT;
570 		parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE);
571 		break;
572 	default:
573 		return -ENOENT;
574 	}
575 
576 	return DIV_TO_RATE(parent, div);
577 }
578 
579 static ulong rk3328_bus_set_clk(struct rk3328_clk_priv *priv,
580 				ulong clk_id, ulong hz)
581 {
582 	struct rk3328_cru *cru = priv->cru;
583 	int src_clk_div;
584 
585 	/*
586 	 * select gpll as pd_bus bus clock source and
587 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
588 	 */
589 	switch (clk_id) {
590 	case ACLK_BUS_PRE:
591 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
592 		assert(src_clk_div - 1 < 31);
593 		rk_clrsetreg(&cru->clksel_con[0],
594 			     CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK,
595 			     CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT |
596 			     (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT);
597 		break;
598 	case HCLK_BUS_PRE:
599 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
600 							      ACLK_BUS_PRE),
601 					   hz);
602 		assert(src_clk_div - 1 < 3);
603 		rk_clrsetreg(&cru->clksel_con[1],
604 			     HCLK_BUS_DIV_CON_MASK,
605 			     (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT);
606 		break;
607 	case PCLK_BUS_PRE:
608 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
609 							      ACLK_BUS_PRE),
610 					   hz);
611 		assert(src_clk_div - 1 < 7);
612 		rk_clrsetreg(&cru->clksel_con[1],
613 			     PCLK_BUS_DIV_CON_MASK,
614 			     (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT);
615 		break;
616 	default:
617 		printf("do not support this bus freq\n");
618 		return -EINVAL;
619 	}
620 	return rk3328_bus_get_clk(priv, clk_id);
621 }
622 
623 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
624 {
625 	struct rk3328_cru *cru = priv->cru;
626 	u32 div, con, parent;
627 
628 	switch (clk_id) {
629 	case ACLK_PERI_PRE:
630 		con = readl(&cru->clksel_con[28]);
631 		div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT;
632 		parent = priv->cpll_hz;
633 		break;
634 	case HCLK_PERI:
635 		con = readl(&cru->clksel_con[29]);
636 		div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT;
637 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
638 		break;
639 	case PCLK_PERI:
640 		con = readl(&cru->clksel_con[29]);
641 		div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT;
642 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
643 		break;
644 	default:
645 		return -ENOENT;
646 	}
647 
648 	return DIV_TO_RATE(parent, div);
649 }
650 
651 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv,
652 				 ulong clk_id, ulong hz)
653 {
654 	struct rk3328_cru *cru = priv->cru;
655 	int src_clk_div;
656 
657 	/*
658 	 * select gpll as pd_bus bus clock source and
659 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
660 	 */
661 	switch (clk_id) {
662 	case ACLK_PERI_PRE:
663 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
664 		assert(src_clk_div - 1 < 31);
665 		rk_clrsetreg(&cru->clksel_con[28],
666 			     CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK,
667 			     CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT |
668 			     (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT);
669 		break;
670 	case HCLK_PERI:
671 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
672 							       ACLK_PERI_PRE),
673 					   hz);
674 		assert(src_clk_div - 1 < 3);
675 		rk_clrsetreg(&cru->clksel_con[29],
676 			     HCLK_PERI_DIV_CON_MASK,
677 			     (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT);
678 		break;
679 	case PCLK_PERI:
680 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
681 							       ACLK_PERI_PRE),
682 					   hz);
683 		assert(src_clk_div - 1 < 7);
684 		rk_clrsetreg(&cru->clksel_con[29],
685 			     PCLK_PERI_DIV_CON_MASK,
686 			     (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT);
687 		break;
688 	default:
689 		printf("do not support this bus freq\n");
690 		return -EINVAL;
691 	}
692 
693 	return rk3328_peri_get_clk(priv, clk_id);
694 }
695 
696 #ifndef CONFIG_SPL_BUILD
697 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
698 {
699 	struct rk3328_cru *cru = priv->cru;
700 	u32 div, con, parent;
701 
702 	switch (clk_id) {
703 	case SCLK_CRYPTO:
704 		con = readl(&cru->clksel_con[20]);
705 		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
706 		parent = priv->gpll_hz;
707 		break;
708 	default:
709 		return -ENOENT;
710 	}
711 
712 	return DIV_TO_RATE(parent, div);
713 }
714 
715 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id,
716 				   ulong hz)
717 {
718 	struct rk3328_cru *cru = priv->cru;
719 	int src_clk_div;
720 
721 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
722 	assert(src_clk_div - 1 <= 127);
723 
724 	/*
725 	 * select gpll as crypto clock source and
726 	 * set up dependent divisors for crypto clocks.
727 	 */
728 	switch (clk_id) {
729 	case SCLK_CRYPTO:
730 		rk_clrsetreg(&cru->clksel_con[20],
731 			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
732 			     CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
733 			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
734 		break;
735 	default:
736 		printf("do not support this peri freq\n");
737 		return -EINVAL;
738 	}
739 
740 	return rk3328_crypto_get_clk(priv, clk_id);
741 }
742 #endif
743 
744 static ulong rk3328_clk_get_rate(struct clk *clk)
745 {
746 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
747 	ulong rate = 0;
748 
749 #ifndef CONFIG_SPL_BUILD
750 	if (!priv->gpll_hz) {
751 		priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
752 						      priv->cru, GPLL);
753 		debug("%s gpll=%lu\n", __func__, priv->gpll_hz);
754 	}
755 	if (!priv->cpll_hz) {
756 		priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
757 						      priv->cru, CPLL);
758 		debug("%s cpll=%lu\n", __func__, priv->cpll_hz);
759 	}
760 #endif
761 
762 	switch (clk->id) {
763 	case PLL_APLL:
764 	case PLL_DPLL:
765 	case PLL_CPLL:
766 	case PLL_GPLL:
767 	case PLL_NPLL:
768 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1],
769 					     priv->cru, clk->id - 1);
770 		break;
771 	case ARMCLK:
772 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
773 					     priv->cru, NPLL);
774 		break;
775 	case ACLK_BUS_PRE:
776 	case HCLK_BUS_PRE:
777 	case PCLK_BUS_PRE:
778 		rate = rk3328_bus_get_clk(priv, clk->id);
779 		break;
780 	case ACLK_PERI_PRE:
781 	case HCLK_PERI:
782 	case PCLK_PERI:
783 		rate = rk3328_peri_get_clk(priv, clk->id);
784 		break;
785 	case HCLK_SDMMC:
786 	case HCLK_EMMC:
787 	case SCLK_SDMMC:
788 	case SCLK_EMMC:
789 	case SCLK_EMMC_SAMPLE:
790 		rate = rk3328_mmc_get_clk(priv, clk->id);
791 		break;
792 	case SCLK_SPI:
793 		rate = rk3328_spi_get_clk(priv);
794 		break;
795 #ifndef CONFIG_SPL_BUILD
796 	case SCLK_I2C0:
797 	case SCLK_I2C1:
798 	case SCLK_I2C2:
799 	case SCLK_I2C3:
800 		rate = rk3328_i2c_get_clk(priv, clk->id);
801 		break;
802 	case SCLK_PWM:
803 		rate = rk3328_pwm_get_clk(priv);
804 		break;
805 	case SCLK_SARADC:
806 		rate = rk3328_saradc_get_clk(priv);
807 		break;
808 	case SCLK_TSADC:
809 		rate = rk3328_tsadc_get_clk(priv);
810 		break;
811 	case ACLK_VOP_PRE:
812 	case ACLK_VIO_PRE:
813 	case HCLK_VIO_PRE:
814 	case ACLK_VOP:
815 	case ACLK_VIO:
816 	case HCLK_VIO:
817 		rate = rk3328_vop_get_clk(priv, clk->id);
818 		break;
819 	case SCLK_CRYPTO:
820 		rate = rk3328_crypto_get_clk(priv, clk->id);
821 		break;
822 #endif
823 	default:
824 		return -ENOENT;
825 	}
826 
827 	return rate;
828 }
829 
830 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
831 {
832 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
833 	ulong ret = 0;
834 
835 	switch (clk->id) {
836 	case PLL_APLL:
837 	case PLL_DPLL:
838 	case PLL_NPLL:
839 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1],
840 					    priv->cru, clk->id - 1, rate);
841 		break;
842 	case PLL_CPLL:
843 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
844 					    priv->cru, CPLL, rate);
845 		priv->cpll_hz = rate;
846 		break;
847 	case PLL_GPLL:
848 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
849 					    priv->cru, GPLL, rate);
850 		priv->gpll_hz = rate;
851 		break;
852 	case ARMCLK:
853 		if (priv->armclk_hz)
854 			ret = rk3328_armclk_set_clk(priv, rate);
855 		priv->armclk_hz = rate;
856 		break;
857 	case ACLK_BUS_PRE:
858 	case HCLK_BUS_PRE:
859 	case PCLK_BUS_PRE:
860 		rate = rk3328_bus_set_clk(priv, clk->id, rate);
861 		break;
862 	case ACLK_PERI_PRE:
863 	case HCLK_PERI:
864 	case PCLK_PERI:
865 		rate = rk3328_peri_set_clk(priv, clk->id, rate);
866 		break;
867 	case HCLK_SDMMC:
868 	case HCLK_EMMC:
869 	case SCLK_SDMMC:
870 	case SCLK_EMMC:
871 		ret = rk3328_mmc_set_clk(priv, clk->id, rate);
872 		break;
873 	case SCLK_SPI:
874 		ret = rk3328_spi_set_clk(priv, rate);
875 		break;
876 #ifndef CONFIG_SPL_BUILD
877 	case SCLK_I2C0:
878 	case SCLK_I2C1:
879 	case SCLK_I2C2:
880 	case SCLK_I2C3:
881 		ret = rk3328_i2c_set_clk(priv, clk->id, rate);
882 		break;
883 	case SCLK_MAC2IO:
884 		ret = rk3328_gmac2io_set_clk(priv, rate);
885 		break;
886 	case SCLK_PWM:
887 		ret = rk3328_pwm_set_clk(priv, rate);
888 		break;
889 	case SCLK_SARADC:
890 		ret = rk3328_saradc_set_clk(priv, rate);
891 		break;
892 	case SCLK_TSADC:
893 		ret = rk3328_tsadc_set_clk(priv, rate);
894 		break;
895 	case DCLK_LCDC:
896 	case ACLK_VOP_PRE:
897 	case ACLK_VIO_PRE:
898 	case HCLK_VIO_PRE:
899 	case ACLK_VOP:
900 	case ACLK_VIO:
901 	case HCLK_VIO:
902 		rate = rk3328_vop_set_clk(priv, clk->id, rate);
903 		break;
904 	case SCLK_CRYPTO:
905 		rate = rk3328_crypto_set_clk(priv, clk->id, rate);
906 		break;
907 #endif
908 	case SCLK_PDM:
909 	case SCLK_RTC32K:
910 	case SCLK_UART0:
911 	case SCLK_UART1:
912 	case SCLK_UART2:
913 	case SCLK_SDIO:
914 	case SCLK_TSP:
915 	case SCLK_WIFI:
916 	case ACLK_RGA_PRE:
917 	case SCLK_RGA:
918 	case ACLK_RKVDEC_PRE:
919 	case ACLK_RKVENC:
920 	case ACLK_VPU_PRE:
921 	case SCLK_VDEC_CABAC:
922 	case SCLK_VDEC_CORE:
923 	case SCLK_VENC_CORE:
924 	case SCLK_VENC_DSP:
925 	case SCLK_EFUSE:
926 	case PCLK_DDR:
927 	case ACLK_GMAC:
928 	case PCLK_GMAC:
929 	case SCLK_USB3OTG_SUSPEND:
930 		return 0;
931 	default:
932 		return -ENOENT;
933 	}
934 
935 	return ret;
936 }
937 
938 #ifndef CONFIG_SPL_BUILD
939 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent)
940 {
941 	struct rk3328_grf_regs *grf;
942 	const char *clock_output_name;
943 	int ret;
944 
945 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
946 
947 	/*
948 	 * If the requested parent is in the same clock-controller and the id
949 	 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock.
950 	 */
951 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) {
952 		debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__);
953 		rk_clrreg(&grf->mac_con[1], BIT(10));
954 		return 0;
955 	}
956 
957 	/*
958 	 * Otherwise, we need to check the clock-output-names of the
959 	 * requested parent to see if the requested id is "gmac_clkin".
960 	 */
961 	ret = dev_read_string_index(parent->dev, "clock-output-names",
962 				    parent->id, &clock_output_name);
963 	if (ret < 0)
964 		return -ENODATA;
965 
966 	/* If this is "gmac_clkin", switch to the external clock input */
967 	if (!strcmp(clock_output_name, "gmac_clkin")) {
968 		debug("%s: switching RGMII to CLKIN\n", __func__);
969 		rk_setreg(&grf->mac_con[1], BIT(10));
970 		return 0;
971 	}
972 
973 	return -EINVAL;
974 }
975 
976 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent)
977 {
978 	struct rk3328_grf_regs *grf;
979 	const char *clock_output_name;
980 	int ret;
981 
982 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
983 
984 	/*
985 	 * If the requested parent is in the same clock-controller and the id
986 	 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock.
987 	 */
988 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) {
989 		debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__);
990 		rk_clrreg(&grf->soc_con[4], BIT(14));
991 		return 0;
992 	}
993 
994 	/*
995 	 * Otherwise, we need to check the clock-output-names of the
996 	 * requested parent to see if the requested id is "gmac_clkin".
997 	 */
998 	ret = dev_read_string_index(parent->dev, "clock-output-names",
999 				    parent->id, &clock_output_name);
1000 	if (ret < 0)
1001 		return -ENODATA;
1002 
1003 	/* If this is "gmac_clkin", switch to the external clock input */
1004 	if (!strcmp(clock_output_name, "gmac_clkin")) {
1005 		debug("%s: switching RGMII to CLKIN\n", __func__);
1006 		rk_setreg(&grf->soc_con[4], BIT(14));
1007 		return 0;
1008 	}
1009 
1010 	return -EINVAL;
1011 }
1012 
1013 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent)
1014 {
1015 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1016 
1017 	if (parent->id == HDMIPHY)
1018 		rk_clrsetreg(&priv->cru->clksel_con[40],
1019 			     DCLK_LCDC_SEL_MASK,
1020 			     DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT);
1021 	else if (parent->id == PLL_CPLL)
1022 		rk_clrsetreg(&priv->cru->clksel_con[40],
1023 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
1024 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
1025 			     (DCLK_LCDC_PLL_SEL_CPLL <<
1026 			     DCLK_LCDC_PLL_SEL_SHIFT));
1027 	else
1028 		rk_clrsetreg(&priv->cru->clksel_con[40],
1029 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
1030 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
1031 			     (DCLK_LCDC_PLL_SEL_GPLL <<
1032 			     DCLK_LCDC_PLL_SEL_SHIFT));
1033 
1034 	return 0;
1035 }
1036 #endif
1037 
1038 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent)
1039 {
1040 	switch (clk->id) {
1041 #ifndef CONFIG_SPL_BUILD
1042 	case SCLK_MAC2IO:
1043 		return rk3328_gmac2io_set_parent(clk, parent);
1044 	case SCLK_MAC2IO_EXT:
1045 		return rk3328_gmac2io_ext_set_parent(clk, parent);
1046 	case DCLK_LCDC:
1047 		return rk3328_lcdc_set_parent(clk, parent);
1048 #endif
1049 	case SCLK_PDM:
1050 	case SCLK_RTC32K:
1051 	case SCLK_UART0:
1052 	case SCLK_UART1:
1053 	case SCLK_UART2:
1054 		return 0;
1055 	}
1056 
1057 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
1058 	return -ENOENT;
1059 }
1060 
1061 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1062 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1063 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1064 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1065 
1066 #define PSECS_PER_SEC 1000000000000LL
1067 /*
1068  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1069  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1070  */
1071 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1072 
1073 int rk3328_mmc_get_phase(struct clk *clk)
1074 {
1075 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1076 	struct rk3328_cru *cru = priv->cru;
1077 	u32 raw_value, delay_num;
1078 	u16 degrees = 0;
1079 	ulong rate;
1080 
1081 	rate = rk3328_clk_get_rate(clk);
1082 
1083 	if (rate < 0)
1084 		return rate;
1085 
1086 	if (clk->id == SCLK_EMMC_SAMPLE)
1087 		raw_value = readl(&cru->emmc_con[1]);
1088 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1089 		raw_value = readl(&cru->sdmmc_con[1]);
1090 	else
1091 		raw_value = readl(&cru->sdio_con[1]);
1092 
1093 	raw_value >>= 1;
1094 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1095 
1096 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1097 		/* degrees/delaynum * 10000 */
1098 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1099 					36 * (rate / 1000000);
1100 
1101 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1102 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1103 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1104 	}
1105 
1106 	return degrees % 360;
1107 }
1108 
1109 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees)
1110 {
1111 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1112 	struct rk3328_cru *cru = priv->cru;
1113 	u8 nineties, remainder, delay_num;
1114 	u32 raw_value, delay;
1115 	ulong rate;
1116 
1117 	rate = rk3328_clk_get_rate(clk);
1118 
1119 	if (rate < 0)
1120 		return rate;
1121 
1122 	nineties = degrees / 90;
1123 	remainder = (degrees % 90);
1124 
1125 	/*
1126 	 * Convert to delay; do a little extra work to make sure we
1127 	 * don't overflow 32-bit / 64-bit numbers.
1128 	 */
1129 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1130 	delay *= remainder;
1131 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1132 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1133 
1134 	delay_num = (u8)min_t(u32, delay, 255);
1135 
1136 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1137 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1138 	raw_value |= nineties;
1139 
1140 	raw_value <<= 1;
1141 	if (clk->id == SCLK_EMMC_SAMPLE)
1142 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1143 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1144 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1145 	else
1146 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1147 
1148 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1149 	      degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk));
1150 
1151 	return 0;
1152 }
1153 
1154 static int rk3328_clk_get_phase(struct clk *clk)
1155 {
1156 	int ret;
1157 
1158 	debug("%s %ld\n", __func__, clk->id);
1159 	switch (clk->id) {
1160 	case SCLK_EMMC_SAMPLE:
1161 	case SCLK_SDMMC_SAMPLE:
1162 	case SCLK_SDIO_SAMPLE:
1163 		ret = rk3328_mmc_get_phase(clk);
1164 		break;
1165 	default:
1166 		return -ENOENT;
1167 	}
1168 
1169 	return ret;
1170 }
1171 
1172 static int rk3328_clk_set_phase(struct clk *clk, int degrees)
1173 {
1174 	int ret;
1175 
1176 	debug("%s %ld\n", __func__, clk->id);
1177 	switch (clk->id) {
1178 	case SCLK_EMMC_SAMPLE:
1179 	case SCLK_SDMMC_SAMPLE:
1180 	case SCLK_SDIO_SAMPLE:
1181 		ret = rk3328_mmc_set_phase(clk, degrees);
1182 		break;
1183 	default:
1184 		return -ENOENT;
1185 	}
1186 
1187 	return ret;
1188 }
1189 
1190 static struct clk_ops rk3328_clk_ops = {
1191 	.get_rate = rk3328_clk_get_rate,
1192 	.set_rate = rk3328_clk_set_rate,
1193 	.set_parent = rk3328_clk_set_parent,
1194 	.get_phase = rk3328_clk_get_phase,
1195 	.set_phase = rk3328_clk_set_phase,
1196 };
1197 
1198 static void rkclk_init(struct rk3328_clk_priv *priv)
1199 {
1200 	if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1201 				  priv->cru, NPLL) != APLL_HZ)
1202 		rk3328_armclk_set_clk(priv, APLL_HZ);
1203 
1204 	priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
1205 					      priv->cru, GPLL);
1206 	priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
1207 					      priv->cru, CPLL);
1208 
1209 	/* before set pll set child div first */
1210 	rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0),
1211 		     (0x17 << 8) | (0x17 << 0));
1212 	rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0),
1213 		     (0x17 << 8) | (0x17 << 0));
1214 	rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0);
1215 	rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0);
1216 	rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8);
1217 
1218 	rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
1219 			      priv->cru, GPLL, GPLL_HZ);
1220 	priv->gpll_hz = GPLL_HZ;
1221 
1222 	rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
1223 			      priv->cru, CPLL, CPLL_HZ);
1224 	priv->cpll_hz = CPLL_HZ;
1225 
1226 	rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1227 	rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1228 	rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1229 	rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1230 	rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2);
1231 	rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2);
1232 	/*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/
1233 
1234 	/* set usbphy and hdmiphy from phy */
1235 	rk_clrsetreg(&priv->cru->misc, (0x1 << 13) |
1236 		     (0x1 << 15), (0 << 15) | (0 << 13));
1237 }
1238 
1239 static int rk3328_clk_probe(struct udevice *dev)
1240 {
1241 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1242 	int ret = 0;
1243 
1244 	priv->sync_kernel = false;
1245 	if (!priv->armclk_enter_hz)
1246 		priv->armclk_enter_hz =
1247 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1248 				      priv->cru, NPLL);
1249 	rkclk_init(priv);
1250 	if (!priv->armclk_init_hz)
1251 		priv->armclk_init_hz =
1252 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1253 				      priv->cru, NPLL);
1254 
1255 	ret = clk_set_defaults(dev);
1256 	if (ret)
1257 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1258 	else
1259 		priv->sync_kernel = true;
1260 
1261 	return 0;
1262 }
1263 
1264 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
1265 {
1266 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1267 
1268 	priv->cru = dev_read_addr_ptr(dev);
1269 
1270 	return 0;
1271 }
1272 
1273 static int rk3328_clk_bind(struct udevice *dev)
1274 {
1275 	int ret;
1276 	struct udevice *sys_child, *sf_child;
1277 	struct sysreset_reg *priv;
1278 	struct softreset_reg *sf_priv;
1279 
1280 	/* The reset driver does not have a device node, so bind it here */
1281 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1282 				 &sys_child);
1283 	if (ret) {
1284 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1285 	} else {
1286 		priv = malloc(sizeof(struct sysreset_reg));
1287 		priv->glb_srst_fst_value = offsetof(struct rk3328_cru,
1288 						    glb_srst_fst_value);
1289 		priv->glb_srst_snd_value = offsetof(struct rk3328_cru,
1290 						    glb_srst_snd_value);
1291 		sys_child->priv = priv;
1292 	}
1293 
1294 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1295 					 dev_ofnode(dev), &sf_child);
1296 	if (ret) {
1297 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1298 	} else {
1299 		sf_priv = malloc(sizeof(struct softreset_reg));
1300 		sf_priv->sf_reset_offset = offsetof(struct rk3328_cru,
1301 						    softrst_con[0]);
1302 		sf_priv->sf_reset_num = 12;
1303 		sf_child->priv = sf_priv;
1304 	}
1305 
1306 	return 0;
1307 }
1308 
1309 static const struct udevice_id rk3328_clk_ids[] = {
1310 	{ .compatible = "rockchip,rk3328-cru" },
1311 	{ }
1312 };
1313 
1314 U_BOOT_DRIVER(rockchip_rk3328_cru) = {
1315 	.name		= "rockchip_rk3328_cru",
1316 	.id		= UCLASS_CLK,
1317 	.of_match	= rk3328_clk_ids,
1318 	.priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
1319 	.ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
1320 	.ops		= &rk3328_clk_ops,
1321 	.bind		= rk3328_clk_bind,
1322 	.probe		= rk3328_clk_probe,
1323 };
1324 
1325 #ifndef CONFIG_SPL_BUILD
1326 /**
1327  * soc_clk_dump() - Print clock frequencies
1328  * Returns zero on success
1329  *
1330  * Implementation for the clk dump command.
1331  */
1332 int soc_clk_dump(void)
1333 {
1334 	struct udevice *cru_dev;
1335 	struct rk3328_clk_priv *priv;
1336 	const struct rk3328_clk_info *clk_dump;
1337 	struct clk clk;
1338 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1339 	unsigned long rate;
1340 	int i, ret;
1341 
1342 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1343 					  DM_GET_DRIVER(rockchip_rk3328_cru),
1344 					  &cru_dev);
1345 	if (ret) {
1346 		printf("%s failed to get cru device\n", __func__);
1347 		return ret;
1348 	}
1349 
1350 	priv = dev_get_priv(cru_dev);
1351 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1352 	       priv->sync_kernel ? "sync kernel" : "uboot",
1353 	       priv->armclk_enter_hz / 1000,
1354 	       priv->armclk_init_hz / 1000,
1355 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1356 	       priv->set_armclk_rate ? " KHz" : "N/A");
1357 	for (i = 0; i < clk_count; i++) {
1358 		clk_dump = &clks_dump[i];
1359 		if (clk_dump->name) {
1360 			clk.id = clk_dump->id;
1361 			if (clk_dump->is_cru)
1362 				ret = clk_request(cru_dev, &clk);
1363 			if (ret < 0)
1364 				return ret;
1365 
1366 			rate = clk_get_rate(&clk);
1367 			clk_free(&clk);
1368 			if (i == 0) {
1369 				if (rate < 0)
1370 					printf("  %s %s\n", clk_dump->name,
1371 					       "unknown");
1372 				else
1373 					printf("  %s %lu KHz\n", clk_dump->name,
1374 					       rate / 1000);
1375 			} else {
1376 				if (rate < 0)
1377 					printf("  %s %s\n", clk_dump->name,
1378 					       "unknown");
1379 				else
1380 					printf("  %s %lu KHz\n", clk_dump->name,
1381 					       rate / 1000);
1382 			}
1383 		}
1384 	}
1385 
1386 	return 0;
1387 }
1388 #endif
1389