xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3328.c (revision 2a3fb7bb049d69d96f3bc7dae8caa756fdc8a613)
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 		if (src_clk_div > 32)
594 			src_clk_div = 32;
595 		rk_clrsetreg(&cru->clksel_con[0],
596 			     CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK,
597 			     CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT |
598 			     (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT);
599 		break;
600 	case HCLK_BUS_PRE:
601 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
602 							      ACLK_BUS_PRE),
603 					   hz);
604 		assert(src_clk_div - 1 < 3);
605 		rk_clrsetreg(&cru->clksel_con[1],
606 			     HCLK_BUS_DIV_CON_MASK,
607 			     (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT);
608 		break;
609 	case PCLK_BUS_PRE:
610 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
611 							      ACLK_BUS_PRE),
612 					   hz);
613 		assert(src_clk_div - 1 < 7);
614 		rk_clrsetreg(&cru->clksel_con[1],
615 			     PCLK_BUS_DIV_CON_MASK,
616 			     (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT);
617 		break;
618 	default:
619 		printf("do not support this bus freq\n");
620 		return -EINVAL;
621 	}
622 	return rk3328_bus_get_clk(priv, clk_id);
623 }
624 
625 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
626 {
627 	struct rk3328_cru *cru = priv->cru;
628 	u32 div, con, parent;
629 
630 	switch (clk_id) {
631 	case ACLK_PERI_PRE:
632 		con = readl(&cru->clksel_con[28]);
633 		div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT;
634 		parent = priv->cpll_hz;
635 		break;
636 	case HCLK_PERI:
637 		con = readl(&cru->clksel_con[29]);
638 		div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT;
639 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
640 		break;
641 	case PCLK_PERI:
642 		con = readl(&cru->clksel_con[29]);
643 		div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT;
644 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
645 		break;
646 	default:
647 		return -ENOENT;
648 	}
649 
650 	return DIV_TO_RATE(parent, div);
651 }
652 
653 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv,
654 				 ulong clk_id, ulong hz)
655 {
656 	struct rk3328_cru *cru = priv->cru;
657 	int src_clk_div;
658 
659 	/*
660 	 * select gpll as pd_bus bus clock source and
661 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
662 	 */
663 	switch (clk_id) {
664 	case ACLK_PERI_PRE:
665 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
666 		assert(src_clk_div - 1 < 31);
667 		if (src_clk_div > 32)
668 			src_clk_div = 32;
669 		rk_clrsetreg(&cru->clksel_con[28],
670 			     CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK,
671 			     CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT |
672 			     (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT);
673 		break;
674 	case HCLK_PERI:
675 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
676 							       ACLK_PERI_PRE),
677 					   hz);
678 		assert(src_clk_div - 1 < 3);
679 		rk_clrsetreg(&cru->clksel_con[29],
680 			     HCLK_PERI_DIV_CON_MASK,
681 			     (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT);
682 		break;
683 	case PCLK_PERI:
684 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
685 							       ACLK_PERI_PRE),
686 					   hz);
687 		assert(src_clk_div - 1 < 7);
688 		rk_clrsetreg(&cru->clksel_con[29],
689 			     PCLK_PERI_DIV_CON_MASK,
690 			     (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT);
691 		break;
692 	default:
693 		printf("do not support this bus freq\n");
694 		return -EINVAL;
695 	}
696 
697 	return rk3328_peri_get_clk(priv, clk_id);
698 }
699 
700 #ifndef CONFIG_SPL_BUILD
701 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
702 {
703 	struct rk3328_cru *cru = priv->cru;
704 	u32 div, con, parent;
705 
706 	switch (clk_id) {
707 	case SCLK_CRYPTO:
708 		con = readl(&cru->clksel_con[20]);
709 		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
710 		parent = priv->gpll_hz;
711 		break;
712 	default:
713 		return -ENOENT;
714 	}
715 
716 	return DIV_TO_RATE(parent, div);
717 }
718 
719 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id,
720 				   ulong hz)
721 {
722 	struct rk3328_cru *cru = priv->cru;
723 	int src_clk_div;
724 
725 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
726 	assert(src_clk_div - 1 <= 127);
727 
728 	/*
729 	 * select gpll as crypto clock source and
730 	 * set up dependent divisors for crypto clocks.
731 	 */
732 	switch (clk_id) {
733 	case SCLK_CRYPTO:
734 		rk_clrsetreg(&cru->clksel_con[20],
735 			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
736 			     CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
737 			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
738 		break;
739 	default:
740 		printf("do not support this peri freq\n");
741 		return -EINVAL;
742 	}
743 
744 	return rk3328_crypto_get_clk(priv, clk_id);
745 }
746 #endif
747 
748 static ulong rk3328_clk_get_rate(struct clk *clk)
749 {
750 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
751 	ulong rate = 0;
752 
753 #ifndef CONFIG_SPL_BUILD
754 	if (!priv->gpll_hz) {
755 		priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
756 						      priv->cru, GPLL);
757 		debug("%s gpll=%lu\n", __func__, priv->gpll_hz);
758 	}
759 	if (!priv->cpll_hz) {
760 		priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
761 						      priv->cru, CPLL);
762 		debug("%s cpll=%lu\n", __func__, priv->cpll_hz);
763 	}
764 #endif
765 
766 	switch (clk->id) {
767 	case PLL_APLL:
768 	case PLL_DPLL:
769 	case PLL_CPLL:
770 	case PLL_GPLL:
771 	case PLL_NPLL:
772 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1],
773 					     priv->cru, clk->id - 1);
774 		break;
775 	case ARMCLK:
776 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
777 					     priv->cru, NPLL);
778 		break;
779 	case ACLK_BUS_PRE:
780 	case HCLK_BUS_PRE:
781 	case PCLK_BUS_PRE:
782 		rate = rk3328_bus_get_clk(priv, clk->id);
783 		break;
784 	case ACLK_PERI_PRE:
785 	case HCLK_PERI:
786 	case PCLK_PERI:
787 		rate = rk3328_peri_get_clk(priv, clk->id);
788 		break;
789 	case HCLK_SDMMC:
790 	case HCLK_EMMC:
791 	case SCLK_SDMMC:
792 	case SCLK_EMMC:
793 	case SCLK_EMMC_SAMPLE:
794 		rate = rk3328_mmc_get_clk(priv, clk->id);
795 		break;
796 	case SCLK_SPI:
797 		rate = rk3328_spi_get_clk(priv);
798 		break;
799 #ifndef CONFIG_SPL_BUILD
800 	case SCLK_I2C0:
801 	case SCLK_I2C1:
802 	case SCLK_I2C2:
803 	case SCLK_I2C3:
804 		rate = rk3328_i2c_get_clk(priv, clk->id);
805 		break;
806 	case SCLK_PWM:
807 		rate = rk3328_pwm_get_clk(priv);
808 		break;
809 	case SCLK_SARADC:
810 		rate = rk3328_saradc_get_clk(priv);
811 		break;
812 	case SCLK_TSADC:
813 		rate = rk3328_tsadc_get_clk(priv);
814 		break;
815 	case ACLK_VOP_PRE:
816 	case ACLK_VIO_PRE:
817 	case HCLK_VIO_PRE:
818 	case ACLK_VOP:
819 	case ACLK_VIO:
820 	case HCLK_VIO:
821 		rate = rk3328_vop_get_clk(priv, clk->id);
822 		break;
823 	case SCLK_CRYPTO:
824 		rate = rk3328_crypto_get_clk(priv, clk->id);
825 		break;
826 #endif
827 	default:
828 		return -ENOENT;
829 	}
830 
831 	return rate;
832 }
833 
834 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
835 {
836 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
837 	ulong ret = 0;
838 
839 	switch (clk->id) {
840 	case PLL_APLL:
841 	case PLL_DPLL:
842 	case PLL_NPLL:
843 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1],
844 					    priv->cru, clk->id - 1, rate);
845 		break;
846 	case PLL_CPLL:
847 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
848 					    priv->cru, CPLL, rate);
849 		priv->cpll_hz = rate;
850 		break;
851 	case PLL_GPLL:
852 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
853 					    priv->cru, GPLL, rate);
854 		priv->gpll_hz = rate;
855 		break;
856 	case ARMCLK:
857 		if (priv->armclk_hz)
858 			ret = rk3328_armclk_set_clk(priv, rate);
859 		priv->armclk_hz = rate;
860 		break;
861 	case ACLK_BUS_PRE:
862 	case HCLK_BUS_PRE:
863 	case PCLK_BUS_PRE:
864 		rate = rk3328_bus_set_clk(priv, clk->id, rate);
865 		break;
866 	case ACLK_PERI_PRE:
867 	case HCLK_PERI:
868 	case PCLK_PERI:
869 		rate = rk3328_peri_set_clk(priv, clk->id, rate);
870 		break;
871 	case HCLK_SDMMC:
872 	case HCLK_EMMC:
873 	case SCLK_SDMMC:
874 	case SCLK_EMMC:
875 		ret = rk3328_mmc_set_clk(priv, clk->id, rate);
876 		break;
877 	case SCLK_SPI:
878 		ret = rk3328_spi_set_clk(priv, rate);
879 		break;
880 #ifndef CONFIG_SPL_BUILD
881 	case SCLK_I2C0:
882 	case SCLK_I2C1:
883 	case SCLK_I2C2:
884 	case SCLK_I2C3:
885 		ret = rk3328_i2c_set_clk(priv, clk->id, rate);
886 		break;
887 	case SCLK_MAC2IO:
888 		ret = rk3328_gmac2io_set_clk(priv, rate);
889 		break;
890 	case SCLK_PWM:
891 		ret = rk3328_pwm_set_clk(priv, rate);
892 		break;
893 	case SCLK_SARADC:
894 		ret = rk3328_saradc_set_clk(priv, rate);
895 		break;
896 	case SCLK_TSADC:
897 		ret = rk3328_tsadc_set_clk(priv, rate);
898 		break;
899 	case DCLK_LCDC:
900 	case ACLK_VOP_PRE:
901 	case ACLK_VIO_PRE:
902 	case HCLK_VIO_PRE:
903 	case ACLK_VOP:
904 	case ACLK_VIO:
905 	case HCLK_VIO:
906 		rate = rk3328_vop_set_clk(priv, clk->id, rate);
907 		break;
908 	case SCLK_CRYPTO:
909 		rate = rk3328_crypto_set_clk(priv, clk->id, rate);
910 		break;
911 #endif
912 	case SCLK_PDM:
913 	case SCLK_RTC32K:
914 	case SCLK_UART0:
915 	case SCLK_UART1:
916 	case SCLK_UART2:
917 	case SCLK_SDIO:
918 	case SCLK_TSP:
919 	case SCLK_WIFI:
920 	case ACLK_RGA_PRE:
921 	case SCLK_RGA:
922 	case ACLK_RKVDEC_PRE:
923 	case ACLK_RKVENC:
924 	case ACLK_VPU_PRE:
925 	case SCLK_VDEC_CABAC:
926 	case SCLK_VDEC_CORE:
927 	case SCLK_VENC_CORE:
928 	case SCLK_VENC_DSP:
929 	case SCLK_EFUSE:
930 	case PCLK_DDR:
931 	case ACLK_GMAC:
932 	case PCLK_GMAC:
933 	case SCLK_USB3OTG_SUSPEND:
934 		return 0;
935 	default:
936 		return -ENOENT;
937 	}
938 
939 	return ret;
940 }
941 
942 #ifndef CONFIG_SPL_BUILD
943 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent)
944 {
945 	struct rk3328_grf_regs *grf;
946 	const char *clock_output_name;
947 	int ret;
948 
949 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
950 
951 	/*
952 	 * If the requested parent is in the same clock-controller and the id
953 	 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock.
954 	 */
955 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) {
956 		debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__);
957 		rk_clrreg(&grf->mac_con[1], BIT(10));
958 		return 0;
959 	}
960 
961 	/*
962 	 * Otherwise, we need to check the clock-output-names of the
963 	 * requested parent to see if the requested id is "gmac_clkin".
964 	 */
965 	ret = dev_read_string_index(parent->dev, "clock-output-names",
966 				    parent->id, &clock_output_name);
967 	if (ret < 0)
968 		return -ENODATA;
969 
970 	/* If this is "gmac_clkin", switch to the external clock input */
971 	if (!strcmp(clock_output_name, "gmac_clkin")) {
972 		debug("%s: switching RGMII to CLKIN\n", __func__);
973 		rk_setreg(&grf->mac_con[1], BIT(10));
974 		return 0;
975 	}
976 
977 	return -EINVAL;
978 }
979 
980 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent)
981 {
982 	struct rk3328_grf_regs *grf;
983 	const char *clock_output_name;
984 	int ret;
985 
986 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
987 
988 	/*
989 	 * If the requested parent is in the same clock-controller and the id
990 	 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock.
991 	 */
992 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) {
993 		debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__);
994 		rk_clrreg(&grf->soc_con[4], BIT(14));
995 		return 0;
996 	}
997 
998 	/*
999 	 * Otherwise, we need to check the clock-output-names of the
1000 	 * requested parent to see if the requested id is "gmac_clkin".
1001 	 */
1002 	ret = dev_read_string_index(parent->dev, "clock-output-names",
1003 				    parent->id, &clock_output_name);
1004 	if (ret < 0)
1005 		return -ENODATA;
1006 
1007 	/* If this is "gmac_clkin", switch to the external clock input */
1008 	if (!strcmp(clock_output_name, "gmac_clkin")) {
1009 		debug("%s: switching RGMII to CLKIN\n", __func__);
1010 		rk_setreg(&grf->soc_con[4], BIT(14));
1011 		return 0;
1012 	}
1013 
1014 	return -EINVAL;
1015 }
1016 
1017 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent)
1018 {
1019 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1020 
1021 	if (parent->id == HDMIPHY)
1022 		rk_clrsetreg(&priv->cru->clksel_con[40],
1023 			     DCLK_LCDC_SEL_MASK,
1024 			     DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT);
1025 	else if (parent->id == PLL_CPLL)
1026 		rk_clrsetreg(&priv->cru->clksel_con[40],
1027 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
1028 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
1029 			     (DCLK_LCDC_PLL_SEL_CPLL <<
1030 			     DCLK_LCDC_PLL_SEL_SHIFT));
1031 	else
1032 		rk_clrsetreg(&priv->cru->clksel_con[40],
1033 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
1034 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
1035 			     (DCLK_LCDC_PLL_SEL_GPLL <<
1036 			     DCLK_LCDC_PLL_SEL_SHIFT));
1037 
1038 	return 0;
1039 }
1040 #endif
1041 
1042 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent)
1043 {
1044 	switch (clk->id) {
1045 #ifndef CONFIG_SPL_BUILD
1046 	case SCLK_MAC2IO:
1047 		return rk3328_gmac2io_set_parent(clk, parent);
1048 	case SCLK_MAC2IO_EXT:
1049 		return rk3328_gmac2io_ext_set_parent(clk, parent);
1050 	case DCLK_LCDC:
1051 		return rk3328_lcdc_set_parent(clk, parent);
1052 #endif
1053 	case SCLK_PDM:
1054 	case SCLK_RTC32K:
1055 	case SCLK_UART0:
1056 	case SCLK_UART1:
1057 	case SCLK_UART2:
1058 		return 0;
1059 	}
1060 
1061 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
1062 	return -ENOENT;
1063 }
1064 
1065 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1066 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1067 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1068 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1069 
1070 #define PSECS_PER_SEC 1000000000000LL
1071 /*
1072  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1073  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1074  */
1075 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1076 
1077 int rk3328_mmc_get_phase(struct clk *clk)
1078 {
1079 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1080 	struct rk3328_cru *cru = priv->cru;
1081 	u32 raw_value, delay_num;
1082 	u16 degrees = 0;
1083 	ulong rate;
1084 
1085 	rate = rk3328_clk_get_rate(clk);
1086 
1087 	if (rate < 0)
1088 		return rate;
1089 
1090 	if (clk->id == SCLK_EMMC_SAMPLE)
1091 		raw_value = readl(&cru->emmc_con[1]);
1092 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1093 		raw_value = readl(&cru->sdmmc_con[1]);
1094 	else
1095 		raw_value = readl(&cru->sdio_con[1]);
1096 
1097 	raw_value >>= 1;
1098 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1099 
1100 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1101 		/* degrees/delaynum * 10000 */
1102 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1103 					36 * (rate / 1000000);
1104 
1105 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1106 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1107 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1108 	}
1109 
1110 	return degrees % 360;
1111 }
1112 
1113 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees)
1114 {
1115 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1116 	struct rk3328_cru *cru = priv->cru;
1117 	u8 nineties, remainder, delay_num;
1118 	u32 raw_value, delay;
1119 	ulong rate;
1120 
1121 	rate = rk3328_clk_get_rate(clk);
1122 
1123 	if (rate < 0)
1124 		return rate;
1125 
1126 	nineties = degrees / 90;
1127 	remainder = (degrees % 90);
1128 
1129 	/*
1130 	 * Convert to delay; do a little extra work to make sure we
1131 	 * don't overflow 32-bit / 64-bit numbers.
1132 	 */
1133 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1134 	delay *= remainder;
1135 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1136 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1137 
1138 	delay_num = (u8)min_t(u32, delay, 255);
1139 
1140 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1141 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1142 	raw_value |= nineties;
1143 
1144 	raw_value <<= 1;
1145 	if (clk->id == SCLK_EMMC_SAMPLE)
1146 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1147 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1148 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1149 	else
1150 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1151 
1152 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1153 	      degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk));
1154 
1155 	return 0;
1156 }
1157 
1158 static int rk3328_clk_get_phase(struct clk *clk)
1159 {
1160 	int ret;
1161 
1162 	debug("%s %ld\n", __func__, clk->id);
1163 	switch (clk->id) {
1164 	case SCLK_EMMC_SAMPLE:
1165 	case SCLK_SDMMC_SAMPLE:
1166 	case SCLK_SDIO_SAMPLE:
1167 		ret = rk3328_mmc_get_phase(clk);
1168 		break;
1169 	default:
1170 		return -ENOENT;
1171 	}
1172 
1173 	return ret;
1174 }
1175 
1176 static int rk3328_clk_set_phase(struct clk *clk, int degrees)
1177 {
1178 	int ret;
1179 
1180 	debug("%s %ld\n", __func__, clk->id);
1181 	switch (clk->id) {
1182 	case SCLK_EMMC_SAMPLE:
1183 	case SCLK_SDMMC_SAMPLE:
1184 	case SCLK_SDIO_SAMPLE:
1185 		ret = rk3328_mmc_set_phase(clk, degrees);
1186 		break;
1187 	default:
1188 		return -ENOENT;
1189 	}
1190 
1191 	return ret;
1192 }
1193 
1194 static struct clk_ops rk3328_clk_ops = {
1195 	.get_rate = rk3328_clk_get_rate,
1196 	.set_rate = rk3328_clk_set_rate,
1197 	.set_parent = rk3328_clk_set_parent,
1198 	.get_phase = rk3328_clk_get_phase,
1199 	.set_phase = rk3328_clk_set_phase,
1200 };
1201 
1202 static void rkclk_init(struct rk3328_clk_priv *priv)
1203 {
1204 	if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1205 				  priv->cru, NPLL) != APLL_HZ)
1206 		rk3328_armclk_set_clk(priv, APLL_HZ);
1207 
1208 	priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
1209 					      priv->cru, GPLL);
1210 	priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
1211 					      priv->cru, CPLL);
1212 
1213 	/* before set pll set child div first */
1214 	rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0),
1215 		     (0x17 << 8) | (0x17 << 0));
1216 	rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0),
1217 		     (0x17 << 8) | (0x17 << 0));
1218 	rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0);
1219 	rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0);
1220 	rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8);
1221 
1222 	rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
1223 			      priv->cru, GPLL, GPLL_HZ);
1224 	priv->gpll_hz = GPLL_HZ;
1225 
1226 	rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
1227 			      priv->cru, CPLL, CPLL_HZ);
1228 	priv->cpll_hz = CPLL_HZ;
1229 
1230 	rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1231 	rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1232 	rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1233 	rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1234 	rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2);
1235 	rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2);
1236 	/*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/
1237 
1238 	/* set usbphy and hdmiphy from phy */
1239 	rk_clrsetreg(&priv->cru->misc, (0x1 << 13) |
1240 		     (0x1 << 15), (0 << 15) | (0 << 13));
1241 }
1242 
1243 static int rk3328_clk_probe(struct udevice *dev)
1244 {
1245 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1246 	int ret = 0;
1247 
1248 	priv->sync_kernel = false;
1249 	if (!priv->armclk_enter_hz)
1250 		priv->armclk_enter_hz =
1251 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1252 				      priv->cru, NPLL);
1253 	rkclk_init(priv);
1254 	if (!priv->armclk_init_hz)
1255 		priv->armclk_init_hz =
1256 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1257 				      priv->cru, NPLL);
1258 
1259 	ret = clk_set_defaults(dev);
1260 	if (ret)
1261 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1262 	else
1263 		priv->sync_kernel = true;
1264 
1265 	return 0;
1266 }
1267 
1268 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
1269 {
1270 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1271 
1272 	priv->cru = dev_read_addr_ptr(dev);
1273 
1274 	return 0;
1275 }
1276 
1277 static int rk3328_clk_bind(struct udevice *dev)
1278 {
1279 	int ret;
1280 	struct udevice *sys_child, *sf_child;
1281 	struct sysreset_reg *priv;
1282 	struct softreset_reg *sf_priv;
1283 
1284 	/* The reset driver does not have a device node, so bind it here */
1285 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1286 				 &sys_child);
1287 	if (ret) {
1288 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1289 	} else {
1290 		priv = malloc(sizeof(struct sysreset_reg));
1291 		priv->glb_srst_fst_value = offsetof(struct rk3328_cru,
1292 						    glb_srst_fst_value);
1293 		priv->glb_srst_snd_value = offsetof(struct rk3328_cru,
1294 						    glb_srst_snd_value);
1295 		sys_child->priv = priv;
1296 	}
1297 
1298 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1299 					 dev_ofnode(dev), &sf_child);
1300 	if (ret) {
1301 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1302 	} else {
1303 		sf_priv = malloc(sizeof(struct softreset_reg));
1304 		sf_priv->sf_reset_offset = offsetof(struct rk3328_cru,
1305 						    softrst_con[0]);
1306 		sf_priv->sf_reset_num = 12;
1307 		sf_child->priv = sf_priv;
1308 	}
1309 
1310 	return 0;
1311 }
1312 
1313 static const struct udevice_id rk3328_clk_ids[] = {
1314 	{ .compatible = "rockchip,rk3328-cru" },
1315 	{ }
1316 };
1317 
1318 U_BOOT_DRIVER(rockchip_rk3328_cru) = {
1319 	.name		= "rockchip_rk3328_cru",
1320 	.id		= UCLASS_CLK,
1321 	.of_match	= rk3328_clk_ids,
1322 	.priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
1323 	.ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
1324 	.ops		= &rk3328_clk_ops,
1325 	.bind		= rk3328_clk_bind,
1326 	.probe		= rk3328_clk_probe,
1327 };
1328 
1329 #ifndef CONFIG_SPL_BUILD
1330 /**
1331  * soc_clk_dump() - Print clock frequencies
1332  * Returns zero on success
1333  *
1334  * Implementation for the clk dump command.
1335  */
1336 int soc_clk_dump(void)
1337 {
1338 	struct udevice *cru_dev;
1339 	struct rk3328_clk_priv *priv;
1340 	const struct rk3328_clk_info *clk_dump;
1341 	struct clk clk;
1342 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1343 	unsigned long rate;
1344 	int i, ret;
1345 
1346 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1347 					  DM_GET_DRIVER(rockchip_rk3328_cru),
1348 					  &cru_dev);
1349 	if (ret) {
1350 		printf("%s failed to get cru device\n", __func__);
1351 		return ret;
1352 	}
1353 
1354 	priv = dev_get_priv(cru_dev);
1355 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1356 	       priv->sync_kernel ? "sync kernel" : "uboot",
1357 	       priv->armclk_enter_hz / 1000,
1358 	       priv->armclk_init_hz / 1000,
1359 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1360 	       priv->set_armclk_rate ? " KHz" : "N/A");
1361 	for (i = 0; i < clk_count; i++) {
1362 		clk_dump = &clks_dump[i];
1363 		if (clk_dump->name) {
1364 			clk.id = clk_dump->id;
1365 			if (clk_dump->is_cru)
1366 				ret = clk_request(cru_dev, &clk);
1367 			if (ret < 0)
1368 				return ret;
1369 
1370 			rate = clk_get_rate(&clk);
1371 			clk_free(&clk);
1372 			if (i == 0) {
1373 				if (rate < 0)
1374 					printf("  %s %s\n", clk_dump->name,
1375 					       "unknown");
1376 				else
1377 					printf("  %s %lu KHz\n", clk_dump->name,
1378 					       rate / 1000);
1379 			} else {
1380 				if (rate < 0)
1381 					printf("  %s %s\n", clk_dump->name,
1382 					       "unknown");
1383 				else
1384 					printf("  %s %lu KHz\n", clk_dump->name,
1385 					       rate / 1000);
1386 			}
1387 		}
1388 	}
1389 
1390 	return 0;
1391 }
1392 #endif
1393