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