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