xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3328.c (revision 5e8564cf419797f9095431e6eb6f0c00dfa423d2)
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 #ifndef CONFIG_SPL_BUILD
352 static ulong rk3328_pwm_get_clk(struct rk3328_clk_priv *priv)
353 {
354 	struct rk3328_cru *cru = priv->cru;
355 	u32 div, con;
356 
357 	con = readl(&cru->clksel_con[24]);
358 	div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
359 
360 	return DIV_TO_RATE(priv->gpll_hz, div);
361 }
362 
363 static ulong rk3328_pwm_set_clk(struct rk3328_clk_priv *priv, uint hz)
364 {
365 	struct rk3328_cru *cru = priv->cru;
366 	u32 div = priv->gpll_hz / hz;
367 
368 	rk_clrsetreg(&cru->clksel_con[24],
369 		     CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
370 		     CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT |
371 		     (div - 1) << CLK_PWM_DIV_CON_SHIFT);
372 
373 	return DIV_TO_RATE(priv->gpll_hz, div);
374 }
375 
376 static ulong rk3328_saradc_get_clk(struct rk3328_clk_priv *priv)
377 {
378 	struct rk3328_cru *cru = priv->cru;
379 	u32 div, val;
380 
381 	val = readl(&cru->clksel_con[23]);
382 	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
383 			       CLK_SARADC_DIV_CON_WIDTH);
384 
385 	return DIV_TO_RATE(OSC_HZ, div);
386 }
387 
388 static ulong rk3328_saradc_set_clk(struct rk3328_clk_priv *priv, uint hz)
389 {
390 	struct rk3328_cru *cru = priv->cru;
391 	int src_clk_div;
392 
393 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
394 	assert(src_clk_div < 128);
395 
396 	rk_clrsetreg(&cru->clksel_con[23],
397 		     CLK_SARADC_DIV_CON_MASK,
398 		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
399 
400 	return rk3328_saradc_get_clk(priv);
401 }
402 
403 static ulong rk3328_tsadc_get_clk(struct rk3328_clk_priv *priv)
404 {
405 	struct rk3328_cru *cru = priv->cru;
406 	u32 div, val;
407 
408 	val = readl(&cru->clksel_con[22]);
409 	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
410 			       CLK_SARADC_DIV_CON_WIDTH);
411 
412 	return DIV_TO_RATE(OSC_HZ, div);
413 }
414 
415 static ulong rk3328_tsadc_set_clk(struct rk3328_clk_priv *priv, uint hz)
416 {
417 	struct rk3328_cru *cru = priv->cru;
418 	int src_clk_div;
419 
420 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
421 	assert(src_clk_div < 128);
422 
423 	rk_clrsetreg(&cru->clksel_con[22],
424 		     CLK_SARADC_DIV_CON_MASK,
425 		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
426 
427 	return rk3328_tsadc_get_clk(priv);
428 }
429 
430 static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
431 {
432 	struct rk3328_cru *cru = priv->cru;
433 	u32 div, con, parent;
434 
435 	switch (clk_id) {
436 	case ACLK_VOP_PRE:
437 	case ACLK_VOP:
438 		con = readl(&cru->clksel_con[39]);
439 		div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT;
440 		parent = priv->cpll_hz;
441 		break;
442 	case ACLK_VIO_PRE:
443 	case ACLK_VIO:
444 		con = readl(&cru->clksel_con[37]);
445 		div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT;
446 		parent = priv->cpll_hz;
447 		break;
448 	case HCLK_VIO_PRE:
449 	case HCLK_VIO:
450 		parent = rk3328_vop_get_clk(priv, ACLK_VIO_PRE);
451 		con = readl(&cru->clksel_con[37]);
452 		div = (con & HCLK_VIO_DIV_CON_MASK) >> HCLK_VIO_DIV_CON_SHIFT;
453 		break;
454 	default:
455 		return -ENOENT;
456 	}
457 
458 	return DIV_TO_RATE(parent, div);
459 }
460 
461 static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv,
462 				ulong clk_id, uint hz)
463 {
464 	struct rk3328_cru *cru = priv->cru;
465 	int src_clk_div;
466 	u32 con, parent;
467 
468 	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
469 	assert(src_clk_div - 1 < 31);
470 
471 	switch (clk_id) {
472 	case ACLK_VOP_PRE:
473 	case ACLK_VOP:
474 		rk_clrsetreg(&cru->clksel_con[39],
475 			     ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
476 			     ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
477 			     (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT);
478 		break;
479 	case ACLK_VIO_PRE:
480 	case ACLK_VIO:
481 		rk_clrsetreg(&cru->clksel_con[37],
482 			     ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK,
483 			     ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT |
484 			     (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT);
485 		break;
486 	case HCLK_VIO_PRE:
487 	case HCLK_VIO:
488 		src_clk_div = DIV_ROUND_UP(rk3328_vop_get_clk(priv,
489 							      ACLK_VIO_PRE),
490 					   hz);
491 		rk_clrsetreg(&cru->clksel_con[37],
492 			     HCLK_VIO_DIV_CON_MASK,
493 			     (src_clk_div - 1) << HCLK_VIO_DIV_CON_SHIFT);
494 		break;
495 	case DCLK_LCDC:
496 		con = readl(&cru->clksel_con[40]);
497 		con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT;
498 		if (con) {
499 			parent = readl(&cru->clksel_con[40]);
500 			parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >>
501 				 DCLK_LCDC_PLL_SEL_SHIFT;
502 			if (parent)
503 				src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
504 			else
505 				src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
506 
507 			rk_clrsetreg(&cru->clksel_con[40],
508 				     DCLK_LCDC_DIV_CON_MASK,
509 				     (src_clk_div - 1) <<
510 				     DCLK_LCDC_DIV_CON_SHIFT);
511 		}
512 		break;
513 	default:
514 		printf("do not support this vop freq\n");
515 		return -EINVAL;
516 	}
517 
518 	return rk3328_vop_get_clk(priv, clk_id);
519 }
520 #endif
521 
522 static ulong rk3328_bus_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
523 {
524 	struct rk3328_cru *cru = priv->cru;
525 	u32 div, con, parent;
526 
527 	switch (clk_id) {
528 	case ACLK_BUS_PRE:
529 		con = readl(&cru->clksel_con[0]);
530 		div = (con & ACLK_BUS_DIV_CON_MASK) >> ACLK_BUS_DIV_CON_SHIFT;
531 		parent = priv->cpll_hz;
532 		break;
533 	case HCLK_BUS_PRE:
534 		con = readl(&cru->clksel_con[1]);
535 		div = (con & HCLK_BUS_DIV_CON_MASK) >> HCLK_BUS_DIV_CON_SHIFT;
536 		parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE);
537 		break;
538 	case PCLK_BUS_PRE:
539 		con = readl(&cru->clksel_con[1]);
540 		div = (con & PCLK_BUS_DIV_CON_MASK) >> PCLK_BUS_DIV_CON_SHIFT;
541 		parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE);
542 		break;
543 	default:
544 		return -ENOENT;
545 	}
546 
547 	return DIV_TO_RATE(parent, div);
548 }
549 
550 static ulong rk3328_bus_set_clk(struct rk3328_clk_priv *priv,
551 				ulong clk_id, ulong hz)
552 {
553 	struct rk3328_cru *cru = priv->cru;
554 	int src_clk_div;
555 
556 	/*
557 	 * select gpll as pd_bus bus clock source and
558 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
559 	 */
560 	switch (clk_id) {
561 	case ACLK_BUS_PRE:
562 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
563 		assert(src_clk_div - 1 < 31);
564 		rk_clrsetreg(&cru->clksel_con[0],
565 			     CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK,
566 			     CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT |
567 			     (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT);
568 		break;
569 	case HCLK_BUS_PRE:
570 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
571 							      ACLK_BUS_PRE),
572 					   hz);
573 		assert(src_clk_div - 1 < 3);
574 		rk_clrsetreg(&cru->clksel_con[1],
575 			     HCLK_BUS_DIV_CON_MASK,
576 			     (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT);
577 		break;
578 	case PCLK_BUS_PRE:
579 		src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv,
580 							      ACLK_BUS_PRE),
581 					   hz);
582 		assert(src_clk_div - 1 < 7);
583 		rk_clrsetreg(&cru->clksel_con[1],
584 			     PCLK_BUS_DIV_CON_MASK,
585 			     (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT);
586 		break;
587 	default:
588 		printf("do not support this bus freq\n");
589 		return -EINVAL;
590 	}
591 	return rk3328_bus_get_clk(priv, clk_id);
592 }
593 
594 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
595 {
596 	struct rk3328_cru *cru = priv->cru;
597 	u32 div, con, parent;
598 
599 	switch (clk_id) {
600 	case ACLK_PERI_PRE:
601 		con = readl(&cru->clksel_con[28]);
602 		div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT;
603 		parent = priv->cpll_hz;
604 		break;
605 	case HCLK_PERI:
606 		con = readl(&cru->clksel_con[29]);
607 		div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT;
608 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
609 		break;
610 	case PCLK_PERI:
611 		con = readl(&cru->clksel_con[29]);
612 		div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT;
613 		parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE);
614 		break;
615 	default:
616 		return -ENOENT;
617 	}
618 
619 	return DIV_TO_RATE(parent, div);
620 }
621 
622 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv,
623 				 ulong clk_id, ulong hz)
624 {
625 	struct rk3328_cru *cru = priv->cru;
626 	int src_clk_div;
627 
628 	/*
629 	 * select gpll as pd_bus bus clock source and
630 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
631 	 */
632 	switch (clk_id) {
633 	case ACLK_PERI_PRE:
634 		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz);
635 		assert(src_clk_div - 1 < 31);
636 		rk_clrsetreg(&cru->clksel_con[28],
637 			     CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK,
638 			     CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT |
639 			     (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT);
640 		break;
641 	case HCLK_PERI:
642 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
643 							       ACLK_PERI_PRE),
644 					   hz);
645 		assert(src_clk_div - 1 < 3);
646 		rk_clrsetreg(&cru->clksel_con[29],
647 			     HCLK_PERI_DIV_CON_MASK,
648 			     (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT);
649 		break;
650 	case PCLK_PERI:
651 		src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv,
652 							       ACLK_PERI_PRE),
653 					   hz);
654 		assert(src_clk_div - 1 < 7);
655 		rk_clrsetreg(&cru->clksel_con[29],
656 			     PCLK_PERI_DIV_CON_MASK,
657 			     (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT);
658 		break;
659 	default:
660 		printf("do not support this bus freq\n");
661 		return -EINVAL;
662 	}
663 
664 	return rk3328_peri_get_clk(priv, clk_id);
665 }
666 
667 #ifndef CONFIG_SPL_BUILD
668 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
669 {
670 	struct rk3328_cru *cru = priv->cru;
671 	u32 div, con, parent;
672 
673 	switch (clk_id) {
674 	case SCLK_CRYPTO:
675 		con = readl(&cru->clksel_con[20]);
676 		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
677 		parent = priv->gpll_hz;
678 		break;
679 	default:
680 		return -ENOENT;
681 	}
682 
683 	return DIV_TO_RATE(parent, div);
684 }
685 
686 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id,
687 				   ulong hz)
688 {
689 	struct rk3328_cru *cru = priv->cru;
690 	int src_clk_div;
691 
692 	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
693 	assert(src_clk_div - 1 <= 127);
694 
695 	/*
696 	 * select gpll as crypto clock source and
697 	 * set up dependent divisors for crypto clocks.
698 	 */
699 	switch (clk_id) {
700 	case SCLK_CRYPTO:
701 		rk_clrsetreg(&cru->clksel_con[20],
702 			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
703 			     CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
704 			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
705 		break;
706 	default:
707 		printf("do not support this peri freq\n");
708 		return -EINVAL;
709 	}
710 
711 	return rk3328_crypto_get_clk(priv, clk_id);
712 }
713 #endif
714 
715 static ulong rk3328_clk_get_rate(struct clk *clk)
716 {
717 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
718 	ulong rate = 0;
719 
720 #ifndef CONFIG_SPL_BUILD
721 	if (!priv->gpll_hz) {
722 		priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
723 						      priv->cru, GPLL);
724 		debug("%s gpll=%lu\n", __func__, priv->gpll_hz);
725 	}
726 	if (!priv->cpll_hz) {
727 		priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
728 						      priv->cru, CPLL);
729 		debug("%s cpll=%lu\n", __func__, priv->cpll_hz);
730 	}
731 #endif
732 
733 	switch (clk->id) {
734 	case PLL_APLL:
735 	case PLL_DPLL:
736 	case PLL_CPLL:
737 	case PLL_GPLL:
738 	case PLL_NPLL:
739 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1],
740 					     priv->cru, clk->id - 1);
741 		break;
742 	case ARMCLK:
743 		rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
744 					     priv->cru, NPLL);
745 		break;
746 	case ACLK_BUS_PRE:
747 	case HCLK_BUS_PRE:
748 	case PCLK_BUS_PRE:
749 		rate = rk3328_bus_get_clk(priv, clk->id);
750 		break;
751 	case ACLK_PERI_PRE:
752 	case HCLK_PERI:
753 	case PCLK_PERI:
754 		rate = rk3328_peri_get_clk(priv, clk->id);
755 		break;
756 	case HCLK_SDMMC:
757 	case HCLK_EMMC:
758 	case SCLK_SDMMC:
759 	case SCLK_EMMC:
760 	case SCLK_EMMC_SAMPLE:
761 		rate = rk3328_mmc_get_clk(priv, clk->id);
762 		break;
763 #ifndef CONFIG_SPL_BUILD
764 	case SCLK_I2C0:
765 	case SCLK_I2C1:
766 	case SCLK_I2C2:
767 	case SCLK_I2C3:
768 		rate = rk3328_i2c_get_clk(priv, clk->id);
769 		break;
770 	case SCLK_PWM:
771 		rate = rk3328_pwm_get_clk(priv);
772 		break;
773 	case SCLK_SARADC:
774 		rate = rk3328_saradc_get_clk(priv);
775 		break;
776 	case SCLK_TSADC:
777 		rate = rk3328_tsadc_get_clk(priv);
778 		break;
779 	case ACLK_VOP_PRE:
780 	case ACLK_VIO_PRE:
781 	case HCLK_VIO_PRE:
782 	case ACLK_VOP:
783 	case ACLK_VIO:
784 	case HCLK_VIO:
785 		rate = rk3328_vop_get_clk(priv, clk->id);
786 		break;
787 	case SCLK_CRYPTO:
788 		rate = rk3328_crypto_get_clk(priv, clk->id);
789 		break;
790 #endif
791 	default:
792 		return -ENOENT;
793 	}
794 
795 	return rate;
796 }
797 
798 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
799 {
800 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
801 	ulong ret = 0;
802 
803 	switch (clk->id) {
804 	case PLL_APLL:
805 	case PLL_DPLL:
806 	case PLL_NPLL:
807 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1],
808 					    priv->cru, clk->id - 1, rate);
809 		break;
810 	case PLL_CPLL:
811 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
812 					    priv->cru, CPLL, rate);
813 		priv->cpll_hz = rate;
814 		break;
815 	case PLL_GPLL:
816 		ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
817 					    priv->cru, GPLL, rate);
818 		priv->gpll_hz = rate;
819 		break;
820 	case ARMCLK:
821 		if (priv->armclk_hz)
822 			ret = rk3328_armclk_set_clk(priv, rate);
823 		priv->armclk_hz = rate;
824 		break;
825 	case ACLK_BUS_PRE:
826 	case HCLK_BUS_PRE:
827 	case PCLK_BUS_PRE:
828 		rate = rk3328_bus_set_clk(priv, clk->id, rate);
829 		break;
830 	case ACLK_PERI_PRE:
831 	case HCLK_PERI:
832 	case PCLK_PERI:
833 		rate = rk3328_peri_set_clk(priv, clk->id, rate);
834 		break;
835 	case HCLK_SDMMC:
836 	case HCLK_EMMC:
837 	case SCLK_SDMMC:
838 	case SCLK_EMMC:
839 		ret = rk3328_mmc_set_clk(priv, clk->id, rate);
840 		break;
841 #ifndef CONFIG_SPL_BUILD
842 	case SCLK_I2C0:
843 	case SCLK_I2C1:
844 	case SCLK_I2C2:
845 	case SCLK_I2C3:
846 		ret = rk3328_i2c_set_clk(priv, clk->id, rate);
847 		break;
848 	case SCLK_MAC2IO:
849 		ret = rk3328_gmac2io_set_clk(priv, rate);
850 		break;
851 	case SCLK_PWM:
852 		ret = rk3328_pwm_set_clk(priv, rate);
853 		break;
854 	case SCLK_SARADC:
855 		ret = rk3328_saradc_set_clk(priv, rate);
856 		break;
857 	case SCLK_TSADC:
858 		ret = rk3328_tsadc_set_clk(priv, rate);
859 		break;
860 	case DCLK_LCDC:
861 	case ACLK_VOP_PRE:
862 	case ACLK_VIO_PRE:
863 	case HCLK_VIO_PRE:
864 	case ACLK_VOP:
865 	case ACLK_VIO:
866 	case HCLK_VIO:
867 		rate = rk3328_vop_set_clk(priv, clk->id, rate);
868 		break;
869 	case SCLK_CRYPTO:
870 		rate = rk3328_crypto_set_clk(priv, clk->id, rate);
871 		break;
872 #endif
873 	case SCLK_PDM:
874 	case SCLK_RTC32K:
875 	case SCLK_UART0:
876 	case SCLK_UART1:
877 	case SCLK_UART2:
878 	case SCLK_SDIO:
879 	case SCLK_TSP:
880 	case SCLK_WIFI:
881 	case ACLK_RGA_PRE:
882 	case SCLK_RGA:
883 	case ACLK_RKVDEC_PRE:
884 	case ACLK_RKVENC:
885 	case ACLK_VPU_PRE:
886 	case SCLK_VDEC_CABAC:
887 	case SCLK_VDEC_CORE:
888 	case SCLK_VENC_CORE:
889 	case SCLK_VENC_DSP:
890 	case SCLK_EFUSE:
891 	case PCLK_DDR:
892 	case ACLK_GMAC:
893 	case PCLK_GMAC:
894 	case SCLK_USB3OTG_SUSPEND:
895 		return 0;
896 	default:
897 		return -ENOENT;
898 	}
899 
900 	return ret;
901 }
902 
903 #ifndef CONFIG_SPL_BUILD
904 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent)
905 {
906 	struct rk3328_grf_regs *grf;
907 	const char *clock_output_name;
908 	int ret;
909 
910 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
911 
912 	/*
913 	 * If the requested parent is in the same clock-controller and the id
914 	 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock.
915 	 */
916 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) {
917 		debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__);
918 		rk_clrreg(&grf->mac_con[1], BIT(10));
919 		return 0;
920 	}
921 
922 	/*
923 	 * Otherwise, we need to check the clock-output-names of the
924 	 * requested parent to see if the requested id is "gmac_clkin".
925 	 */
926 	ret = dev_read_string_index(parent->dev, "clock-output-names",
927 				    parent->id, &clock_output_name);
928 	if (ret < 0)
929 		return -ENODATA;
930 
931 	/* If this is "gmac_clkin", switch to the external clock input */
932 	if (!strcmp(clock_output_name, "gmac_clkin")) {
933 		debug("%s: switching RGMII to CLKIN\n", __func__);
934 		rk_setreg(&grf->mac_con[1], BIT(10));
935 		return 0;
936 	}
937 
938 	return -EINVAL;
939 }
940 
941 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent)
942 {
943 	struct rk3328_grf_regs *grf;
944 	const char *clock_output_name;
945 	int ret;
946 
947 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
948 
949 	/*
950 	 * If the requested parent is in the same clock-controller and the id
951 	 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock.
952 	 */
953 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) {
954 		debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__);
955 		rk_clrreg(&grf->soc_con[4], BIT(14));
956 		return 0;
957 	}
958 
959 	/*
960 	 * Otherwise, we need to check the clock-output-names of the
961 	 * requested parent to see if the requested id is "gmac_clkin".
962 	 */
963 	ret = dev_read_string_index(parent->dev, "clock-output-names",
964 				    parent->id, &clock_output_name);
965 	if (ret < 0)
966 		return -ENODATA;
967 
968 	/* If this is "gmac_clkin", switch to the external clock input */
969 	if (!strcmp(clock_output_name, "gmac_clkin")) {
970 		debug("%s: switching RGMII to CLKIN\n", __func__);
971 		rk_setreg(&grf->soc_con[4], BIT(14));
972 		return 0;
973 	}
974 
975 	return -EINVAL;
976 }
977 
978 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent)
979 {
980 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
981 
982 	if (parent->id == HDMIPHY)
983 		rk_clrsetreg(&priv->cru->clksel_con[40],
984 			     DCLK_LCDC_SEL_MASK,
985 			     DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT);
986 	else if (parent->id == PLL_CPLL)
987 		rk_clrsetreg(&priv->cru->clksel_con[40],
988 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
989 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
990 			     (DCLK_LCDC_PLL_SEL_CPLL <<
991 			     DCLK_LCDC_PLL_SEL_SHIFT));
992 	else
993 		rk_clrsetreg(&priv->cru->clksel_con[40],
994 			     DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK,
995 			     (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) |
996 			     (DCLK_LCDC_PLL_SEL_GPLL <<
997 			     DCLK_LCDC_PLL_SEL_SHIFT));
998 
999 	return 0;
1000 }
1001 #endif
1002 
1003 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent)
1004 {
1005 	switch (clk->id) {
1006 #ifndef CONFIG_SPL_BUILD
1007 	case SCLK_MAC2IO:
1008 		return rk3328_gmac2io_set_parent(clk, parent);
1009 	case SCLK_MAC2IO_EXT:
1010 		return rk3328_gmac2io_ext_set_parent(clk, parent);
1011 	case DCLK_LCDC:
1012 		return rk3328_lcdc_set_parent(clk, parent);
1013 #endif
1014 	case SCLK_PDM:
1015 	case SCLK_RTC32K:
1016 	case SCLK_UART0:
1017 	case SCLK_UART1:
1018 	case SCLK_UART2:
1019 		return 0;
1020 	}
1021 
1022 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
1023 	return -ENOENT;
1024 }
1025 
1026 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1027 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1028 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1029 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1030 
1031 #define PSECS_PER_SEC 1000000000000LL
1032 /*
1033  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1034  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1035  */
1036 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1037 
1038 int rk3328_mmc_get_phase(struct clk *clk)
1039 {
1040 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1041 	struct rk3328_cru *cru = priv->cru;
1042 	u32 raw_value, delay_num;
1043 	u16 degrees = 0;
1044 	ulong rate;
1045 
1046 	rate = rk3328_clk_get_rate(clk);
1047 
1048 	if (rate < 0)
1049 		return rate;
1050 
1051 	if (clk->id == SCLK_EMMC_SAMPLE)
1052 		raw_value = readl(&cru->emmc_con[1]);
1053 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1054 		raw_value = readl(&cru->sdmmc_con[1]);
1055 	else
1056 		raw_value = readl(&cru->sdio_con[1]);
1057 
1058 	raw_value >>= 1;
1059 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1060 
1061 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1062 		/* degrees/delaynum * 10000 */
1063 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1064 					36 * (rate / 1000000);
1065 
1066 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1067 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1068 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1069 	}
1070 
1071 	return degrees % 360;
1072 }
1073 
1074 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees)
1075 {
1076 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
1077 	struct rk3328_cru *cru = priv->cru;
1078 	u8 nineties, remainder, delay_num;
1079 	u32 raw_value, delay;
1080 	ulong rate;
1081 
1082 	rate = rk3328_clk_get_rate(clk);
1083 
1084 	if (rate < 0)
1085 		return rate;
1086 
1087 	nineties = degrees / 90;
1088 	remainder = (degrees % 90);
1089 
1090 	/*
1091 	 * Convert to delay; do a little extra work to make sure we
1092 	 * don't overflow 32-bit / 64-bit numbers.
1093 	 */
1094 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1095 	delay *= remainder;
1096 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1097 				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1098 
1099 	delay_num = (u8)min_t(u32, delay, 255);
1100 
1101 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1102 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1103 	raw_value |= nineties;
1104 
1105 	raw_value <<= 1;
1106 	if (clk->id == SCLK_EMMC_SAMPLE)
1107 		writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1108 	else if (clk->id == SCLK_SDMMC_SAMPLE)
1109 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1110 	else
1111 		writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1112 
1113 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1114 	      degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk));
1115 
1116 	return 0;
1117 }
1118 
1119 static int rk3328_clk_get_phase(struct clk *clk)
1120 {
1121 	int ret;
1122 
1123 	debug("%s %ld\n", __func__, clk->id);
1124 	switch (clk->id) {
1125 	case SCLK_EMMC_SAMPLE:
1126 	case SCLK_SDMMC_SAMPLE:
1127 	case SCLK_SDIO_SAMPLE:
1128 		ret = rk3328_mmc_get_phase(clk);
1129 		break;
1130 	default:
1131 		return -ENOENT;
1132 	}
1133 
1134 	return ret;
1135 }
1136 
1137 static int rk3328_clk_set_phase(struct clk *clk, int degrees)
1138 {
1139 	int ret;
1140 
1141 	debug("%s %ld\n", __func__, clk->id);
1142 	switch (clk->id) {
1143 	case SCLK_EMMC_SAMPLE:
1144 	case SCLK_SDMMC_SAMPLE:
1145 	case SCLK_SDIO_SAMPLE:
1146 		ret = rk3328_mmc_set_phase(clk, degrees);
1147 		break;
1148 	default:
1149 		return -ENOENT;
1150 	}
1151 
1152 	return ret;
1153 }
1154 
1155 static struct clk_ops rk3328_clk_ops = {
1156 	.get_rate = rk3328_clk_get_rate,
1157 	.set_rate = rk3328_clk_set_rate,
1158 	.set_parent = rk3328_clk_set_parent,
1159 	.get_phase = rk3328_clk_get_phase,
1160 	.set_phase = rk3328_clk_set_phase,
1161 };
1162 
1163 static void rkclk_init(struct rk3328_clk_priv *priv)
1164 {
1165 	if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1166 				  priv->cru, NPLL) != APLL_HZ)
1167 		rk3328_armclk_set_clk(priv, APLL_HZ);
1168 
1169 	priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL],
1170 					      priv->cru, GPLL);
1171 	priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL],
1172 					      priv->cru, CPLL);
1173 
1174 	/* before set pll set child div first */
1175 	rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0),
1176 		     (0x17 << 8) | (0x17 << 0));
1177 	rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0),
1178 		     (0x17 << 8) | (0x17 << 0));
1179 	rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0);
1180 	rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0);
1181 	rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8);
1182 
1183 	rockchip_pll_set_rate(&rk3328_pll_clks[GPLL],
1184 			      priv->cru, GPLL, GPLL_HZ);
1185 	priv->gpll_hz = GPLL_HZ;
1186 
1187 	rockchip_pll_set_rate(&rk3328_pll_clks[CPLL],
1188 			      priv->cru, CPLL, CPLL_HZ);
1189 	priv->cpll_hz = CPLL_HZ;
1190 
1191 	rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1192 	rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1193 	rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2);
1194 	rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1195 	rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2);
1196 	rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2);
1197 	/*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/
1198 
1199 	/* set usbphy and hdmiphy from phy */
1200 	rk_clrsetreg(&priv->cru->misc, (0x1 << 13) |
1201 		     (0x1 << 15), (0 << 15) | (0 << 13));
1202 }
1203 
1204 static int rk3328_clk_probe(struct udevice *dev)
1205 {
1206 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1207 	int ret = 0;
1208 
1209 	priv->sync_kernel = false;
1210 	if (!priv->armclk_enter_hz)
1211 		priv->armclk_enter_hz =
1212 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1213 				      priv->cru, NPLL);
1214 	rkclk_init(priv);
1215 	if (!priv->armclk_init_hz)
1216 		priv->armclk_init_hz =
1217 		rockchip_pll_get_rate(&rk3328_pll_clks[NPLL],
1218 				      priv->cru, NPLL);
1219 
1220 	ret = clk_set_defaults(dev);
1221 	if (ret)
1222 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1223 	else
1224 		priv->sync_kernel = true;
1225 
1226 	return 0;
1227 }
1228 
1229 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
1230 {
1231 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
1232 
1233 	priv->cru = dev_read_addr_ptr(dev);
1234 
1235 	return 0;
1236 }
1237 
1238 static int rk3328_clk_bind(struct udevice *dev)
1239 {
1240 	int ret;
1241 	struct udevice *sys_child, *sf_child;
1242 	struct sysreset_reg *priv;
1243 	struct softreset_reg *sf_priv;
1244 
1245 	/* The reset driver does not have a device node, so bind it here */
1246 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1247 				 &sys_child);
1248 	if (ret) {
1249 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1250 	} else {
1251 		priv = malloc(sizeof(struct sysreset_reg));
1252 		priv->glb_srst_fst_value = offsetof(struct rk3328_cru,
1253 						    glb_srst_fst_value);
1254 		priv->glb_srst_snd_value = offsetof(struct rk3328_cru,
1255 						    glb_srst_snd_value);
1256 		sys_child->priv = priv;
1257 	}
1258 
1259 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1260 					 dev_ofnode(dev), &sf_child);
1261 	if (ret) {
1262 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1263 	} else {
1264 		sf_priv = malloc(sizeof(struct softreset_reg));
1265 		sf_priv->sf_reset_offset = offsetof(struct rk3328_cru,
1266 						    softrst_con[0]);
1267 		sf_priv->sf_reset_num = 12;
1268 		sf_child->priv = sf_priv;
1269 	}
1270 
1271 	return 0;
1272 }
1273 
1274 static const struct udevice_id rk3328_clk_ids[] = {
1275 	{ .compatible = "rockchip,rk3328-cru" },
1276 	{ }
1277 };
1278 
1279 U_BOOT_DRIVER(rockchip_rk3328_cru) = {
1280 	.name		= "rockchip_rk3328_cru",
1281 	.id		= UCLASS_CLK,
1282 	.of_match	= rk3328_clk_ids,
1283 	.priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
1284 	.ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
1285 	.ops		= &rk3328_clk_ops,
1286 	.bind		= rk3328_clk_bind,
1287 	.probe		= rk3328_clk_probe,
1288 };
1289 
1290 #ifndef CONFIG_SPL_BUILD
1291 /**
1292  * soc_clk_dump() - Print clock frequencies
1293  * Returns zero on success
1294  *
1295  * Implementation for the clk dump command.
1296  */
1297 int soc_clk_dump(void)
1298 {
1299 	struct udevice *cru_dev;
1300 	struct rk3328_clk_priv *priv;
1301 	const struct rk3328_clk_info *clk_dump;
1302 	struct clk clk;
1303 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
1304 	unsigned long rate;
1305 	int i, ret;
1306 
1307 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1308 					  DM_GET_DRIVER(rockchip_rk3328_cru),
1309 					  &cru_dev);
1310 	if (ret) {
1311 		printf("%s failed to get cru device\n", __func__);
1312 		return ret;
1313 	}
1314 
1315 	priv = dev_get_priv(cru_dev);
1316 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1317 	       priv->sync_kernel ? "sync kernel" : "uboot",
1318 	       priv->armclk_enter_hz / 1000,
1319 	       priv->armclk_init_hz / 1000,
1320 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1321 	       priv->set_armclk_rate ? " KHz" : "N/A");
1322 	for (i = 0; i < clk_count; i++) {
1323 		clk_dump = &clks_dump[i];
1324 		if (clk_dump->name) {
1325 			clk.id = clk_dump->id;
1326 			if (clk_dump->is_cru)
1327 				ret = clk_request(cru_dev, &clk);
1328 			if (ret < 0)
1329 				return ret;
1330 
1331 			rate = clk_get_rate(&clk);
1332 			clk_free(&clk);
1333 			if (i == 0) {
1334 				if (rate < 0)
1335 					printf("  %s %s\n", clk_dump->name,
1336 					       "unknown");
1337 				else
1338 					printf("  %s %lu KHz\n", clk_dump->name,
1339 					       rate / 1000);
1340 			} else {
1341 				if (rate < 0)
1342 					printf("  %s %s\n", clk_dump->name,
1343 					       "unknown");
1344 				else
1345 					printf("  %s %lu KHz\n", clk_dump->name,
1346 					       rate / 1000);
1347 			}
1348 		}
1349 	}
1350 
1351 	return 0;
1352 }
1353 #endif
1354