xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk3528.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Joseph Chen <chenjh@rock-chips.com>
5  */
6 
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <syscon.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/cru_rk3528.h>
13 #include <asm/arch/grf_rk3528.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/io.h>
16 #include <dm/lists.h>
17 #include <dt-bindings/clock/rk3528-cru.h>
18 
19 DECLARE_GLOBAL_DATA_PTR;
20 
21 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
22 
23 /*
24  *	PLL attention.
25  *
26  * [FRAC PLL]: GPLL, PPLL, DPLL
27  *   - frac mode: refdiv can be 1 or 2 only
28  *   - int mode:  refdiv has no special limit
29  *   - VCO range: [950, 3800] MHZ
30  *
31  * [INT PLL]:  CPLL, APLL
32  *   - int mode:  refdiv can be 1 or 2 only
33  *   - VCO range: [475, 1900] MHZ
34  *
35  * [PPLL]: normal mode only.
36  *
37  */
38 static struct rockchip_pll_rate_table rk3528_pll_rates[] = {
39 	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
40 	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
41 	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
42 	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
43 	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
44 	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
45 	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
46 	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
47 	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
48 	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),		/* GPLL */
49 	RK3036_PLL_RATE(1092000000, 2, 91, 1, 1, 1, 0),
50 	RK3036_PLL_RATE(1008000000, 1, 42, 1, 1, 1, 0),
51 	RK3036_PLL_RATE(1000000000, 1, 125, 3, 1, 1, 0), 	/* PPLL */
52 	RK3036_PLL_RATE(996000000, 2, 83, 1, 1, 1, 0),		/* CPLL */
53 	RK3036_PLL_RATE(960000000, 1, 40, 1, 1, 1, 0),
54 	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
55 	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
56 	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
57 	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
58 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
59 	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
60 	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
61 	RK3036_PLL_RATE(96000000, 1, 24, 3, 2, 1, 0),
62 	{ /* sentinel */ },
63 };
64 
65 static struct rockchip_pll_clock rk3528_pll_clks[] = {
66 	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3528_PLL_CON(0),
67 		     RK3528_MODE_CON, 0, 10, 0, rk3528_pll_rates),
68 
69 	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3528_PLL_CON(8),
70 		     RK3528_MODE_CON, 2, 10, 0, rk3528_pll_rates),
71 
72 	[GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3528_PLL_CON(24),
73 		     RK3528_MODE_CON, 4, 10, 0, rk3528_pll_rates),
74 
75 	[PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3528_PCIE_PLL_CON(32),
76 		     RK3528_MODE_CON, 6, 10, ROCKCHIP_PLL_FIXED_MODE, rk3528_pll_rates),
77 
78 	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3528_DDRPHY_PLL_CON(16),
79 		     RK3528_DDRPHY_MODE_CON, 0, 10, 0, rk3528_pll_rates),
80 };
81 
82 #define RK3528_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg)	\
83 {								\
84 	.rate = _rate##U,					\
85 	.aclk_div = (_aclk_m_core),				\
86 	.pclk_div = (_pclk_dbg),				\
87 }
88 
89 /* sign-off: _aclk_m_core: 550M, _pclk_dbg: 137.5M, */
90 static struct rockchip_cpu_rate_table rk3528_cpu_rates[] = {
91 	RK3528_CPUCLK_RATE(1896000000, 1, 13),
92 	RK3528_CPUCLK_RATE(1800000000, 1, 12),
93 	RK3528_CPUCLK_RATE(1704000000, 1, 11),
94 	RK3528_CPUCLK_RATE(1608000000, 1, 11),
95 	RK3528_CPUCLK_RATE(1512000000, 1, 11),
96 	RK3528_CPUCLK_RATE(1416000000, 1, 9),
97 	RK3528_CPUCLK_RATE(1296000000, 1, 8),
98 	RK3528_CPUCLK_RATE(1200000000, 1, 8),
99 	RK3528_CPUCLK_RATE(1188000000, 1, 8),
100 	RK3528_CPUCLK_RATE(1092000000, 1, 7),
101 	RK3528_CPUCLK_RATE(1008000000, 1, 6),
102 	RK3528_CPUCLK_RATE(1000000000, 1, 6),
103 	RK3528_CPUCLK_RATE(996000000, 1, 6),
104 	RK3528_CPUCLK_RATE(960000000, 1, 6),
105 	RK3528_CPUCLK_RATE(912000000, 1, 6),
106 	RK3528_CPUCLK_RATE(816000000, 1, 5),
107 	RK3528_CPUCLK_RATE(600000000, 1, 3),
108 	RK3528_CPUCLK_RATE(594000000, 1, 3),
109 	RK3528_CPUCLK_RATE(408000000, 1, 2),
110 	RK3528_CPUCLK_RATE(312000000, 1, 2),
111 	RK3528_CPUCLK_RATE(216000000, 1, 1),
112 	RK3528_CPUCLK_RATE(96000000, 1, 0),
113 };
114 
115 #ifndef CONFIG_SPL_BUILD
116 #define RK3528_CLK_DUMP(_id, _name)		\
117 {						\
118 	.id = _id,				\
119 	.name = _name,				\
120 }
121 
122 static const struct rk3528_clk_info clks_dump[] = {
123 	RK3528_CLK_DUMP(PLL_APLL, "apll"),
124 	RK3528_CLK_DUMP(PLL_GPLL, "gpll"),
125 	RK3528_CLK_DUMP(PLL_CPLL, "cpll"),
126 	RK3528_CLK_DUMP(PLL_DPLL, "dpll"),
127 	RK3528_CLK_DUMP(PLL_PPLL, "ppll"),
128 	RK3528_CLK_DUMP(CLK_MATRIX_50M_SRC,   "clk_50m"),
129 	RK3528_CLK_DUMP(CLK_MATRIX_100M_SRC,  "clk_100m"),
130 	RK3528_CLK_DUMP(CLK_MATRIX_150M_SRC,  "clk_150m"),
131 	RK3528_CLK_DUMP(CLK_MATRIX_200M_SRC,  "clk_200m"),
132 	RK3528_CLK_DUMP(CLK_MATRIX_250M_SRC,  "clk_250m"),
133 	RK3528_CLK_DUMP(CLK_MATRIX_300M_SRC,  "clk_300m"),
134 	RK3528_CLK_DUMP(CLK_MATRIX_339M_SRC,  "clk_339m"),
135 	RK3528_CLK_DUMP(CLK_MATRIX_400M_SRC,  "clk_400m"),
136 	RK3528_CLK_DUMP(CLK_MATRIX_500M_SRC,  "clk_500m"),
137 	RK3528_CLK_DUMP(CLK_MATRIX_600M_SRC,  "clk_600m"),
138 	RK3528_CLK_DUMP(CLK_PPLL_50M_MATRIX,  "clk_ppll_50m"),
139 	RK3528_CLK_DUMP(CLK_PPLL_100M_MATRIX, "clk_ppll_100m"),
140 	RK3528_CLK_DUMP(CLK_PPLL_125M_MATRIX, "clk_ppll_125m"),
141 };
142 #endif
143 
144 /*
145  *
146  * rational_best_approximation(31415, 10000,
147  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
148  *
149  * you may look at given_numerator as a fixed point number,
150  * with the fractional part size described in given_denominator.
151  *
152  * for theoretical background, see:
153  * http://en.wikipedia.org/wiki/Continued_fraction
154  */
rational_best_approximation(unsigned long given_numerator,unsigned long given_denominator,unsigned long max_numerator,unsigned long max_denominator,unsigned long * best_numerator,unsigned long * best_denominator)155 static void rational_best_approximation(unsigned long given_numerator,
156 					unsigned long given_denominator,
157 					unsigned long max_numerator,
158 					unsigned long max_denominator,
159 					unsigned long *best_numerator,
160 					unsigned long *best_denominator)
161 {
162 	unsigned long n, d, n0, d0, n1, d1;
163 
164 	n = given_numerator;
165 	d = given_denominator;
166 	n0 = 0;
167 	d1 = 0;
168 	n1 = 1;
169 	d0 = 1;
170 	for (;;) {
171 		unsigned long t, a;
172 
173 		if (n1 > max_numerator || d1 > max_denominator) {
174 			n1 = n0;
175 			d1 = d0;
176 			break;
177 		}
178 		if (d == 0)
179 			break;
180 		t = d;
181 		a = n / d;
182 		d = n % d;
183 		n = t;
184 		t = n0 + a * n1;
185 		n0 = n1;
186 		n1 = t;
187 		t = d0 + a * d1;
188 		d0 = d1;
189 		d1 = t;
190 	}
191 	*best_numerator = n1;
192 	*best_denominator = d1;
193 }
194 
rk3528_armclk_set_clk(struct rk3528_clk_priv * priv,ulong new_rate)195 static int rk3528_armclk_set_clk(struct rk3528_clk_priv *priv, ulong new_rate)
196 {
197 	const struct rockchip_cpu_rate_table *rate;
198 	struct rk3528_cru *cru = priv->cru;
199 	ulong old_rate;
200 
201 	rate = rockchip_get_cpu_settings(rk3528_cpu_rates, new_rate);
202 	if (!rate) {
203 		printf("%s unsupported rate\n", __func__);
204 		return -EINVAL;
205 	}
206 
207 	/*
208 	 * set up dependent divisors for DBG and ACLK clocks.
209 	 */
210 	old_rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, APLL);
211 	if (old_rate > new_rate) {
212 		if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL],
213 					  priv->cru, APLL, new_rate))
214 			return -EINVAL;
215 
216 		rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK,
217 			     rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT);
218 
219 		rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK,
220 			     rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT);
221 	} else if (old_rate < new_rate) {
222 		rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK,
223 			     rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT);
224 
225 		rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK,
226 			     rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT);
227 
228 		if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL],
229 					  priv->cru, APLL, new_rate))
230 			return -EINVAL;
231 	}
232 
233 	return 0;
234 }
235 
rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)236 static ulong rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv *priv,
237 				      ulong clk_id)
238 {
239 	struct rk3528_cru *cru = priv->cru;
240 	u32 div, mask, shift;
241 	void *reg;
242 
243 	switch (clk_id) {
244 	case CLK_PPLL_50M_MATRIX:
245 	case CLK_GMAC1_RMII_VPU:
246 		mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK;
247 		shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT;
248 		reg = &cru->pcieclksel_con[1];
249 		break;
250 
251 	case CLK_PPLL_100M_MATRIX:
252 		mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK;
253 		shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT;
254 		reg = &cru->pcieclksel_con[1];
255 		break;
256 
257 	case CLK_PPLL_125M_MATRIX:
258 	case CLK_GMAC1_SRC_VPU:
259 		mask = CLK_MATRIX_125M_SRC_DIV_MASK;
260 		shift = CLK_MATRIX_125M_SRC_DIV_SHIFT;
261 		reg = &cru->clksel_con[60];
262 		break;
263 
264 	case CLK_GMAC1_VPU_25M:
265 		mask = CLK_MATRIX_25M_SRC_DIV_MASK;
266 		shift = CLK_MATRIX_25M_SRC_DIV_SHIFT;
267 		reg = &cru->clksel_con[60];
268 		break;
269 	default:
270 		return -ENOENT;
271 	}
272 
273 	div = (readl(reg) & mask) >> shift;
274 
275 	return DIV_TO_RATE(priv->ppll_hz, div);
276 }
277 
rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)278 static ulong rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv *priv,
279 				      ulong clk_id, ulong rate)
280 {
281 	struct rk3528_cru *cru = priv->cru;
282 	u32 id, div, mask, shift;
283 	u8 is_pciecru = 0;
284 
285 	switch (clk_id) {
286 	case CLK_PPLL_50M_MATRIX:
287 		id = 1;
288 		mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK;
289 		shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT;
290 		is_pciecru = 1;
291 		break;
292 
293 	case CLK_PPLL_100M_MATRIX:
294 		id = 1;
295 		mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK;
296 		shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT;
297 		is_pciecru = 1;
298 		break;
299 
300 	case CLK_PPLL_125M_MATRIX:
301 		id = 60;
302 		mask = CLK_MATRIX_125M_SRC_DIV_MASK;
303 		shift = CLK_MATRIX_125M_SRC_DIV_SHIFT;
304 		break;
305 	case CLK_GMAC1_VPU_25M:
306 		id = 60;
307 		mask = CLK_MATRIX_25M_SRC_DIV_MASK;
308 		shift = CLK_MATRIX_25M_SRC_DIV_SHIFT;
309 		break;
310 	default:
311 		return -ENOENT;
312 	}
313 
314 	div = DIV_ROUND_UP(priv->ppll_hz, rate);
315 	if (is_pciecru)
316 		rk_clrsetreg(&cru->pcieclksel_con[id], mask, (div - 1) << shift);
317 	else
318 		rk_clrsetreg(&cru->clksel_con[id], mask, (div - 1) << shift);
319 
320 	return rk3528_ppll_matrix_get_rate(priv, clk_id);
321 }
322 
rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)323 static ulong rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv *priv,
324 				      ulong clk_id)
325 {
326 	struct rk3528_cru *cru = priv->cru;
327 	u32 sel, div, mask, shift, con;
328 	u32 sel_mask = 0, sel_shift;
329 	u8 is_gpll_parent = 1;
330 	u8 is_halfdiv = 0;
331 	ulong prate;
332 
333 	switch (clk_id) {
334 	case CLK_MATRIX_50M_SRC:
335 		con = 0;
336 		mask = CLK_MATRIX_50M_SRC_DIV_MASK;
337 		shift = CLK_MATRIX_50M_SRC_DIV_SHIFT;
338 		is_gpll_parent = 0;
339 		break;
340 
341 	case CLK_MATRIX_100M_SRC:
342 		con = 0;
343 		mask = CLK_MATRIX_100M_SRC_DIV_MASK;
344 		shift = CLK_MATRIX_100M_SRC_DIV_SHIFT;
345 		is_gpll_parent = 0;
346 		break;
347 
348 	case CLK_MATRIX_150M_SRC:
349 		con = 1;
350 		mask = CLK_MATRIX_150M_SRC_DIV_MASK;
351 		shift = CLK_MATRIX_150M_SRC_DIV_SHIFT;
352 		break;
353 
354 	case CLK_MATRIX_200M_SRC:
355 		con = 1;
356 		mask = CLK_MATRIX_200M_SRC_DIV_MASK;
357 		shift = CLK_MATRIX_200M_SRC_DIV_SHIFT;
358 		break;
359 
360 	case CLK_MATRIX_250M_SRC:
361 		con = 1;
362 		mask = CLK_MATRIX_250M_SRC_DIV_MASK;
363 		shift = CLK_MATRIX_250M_SRC_DIV_SHIFT;
364 		sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK;
365 		sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT;
366 		break;
367 
368 	case CLK_MATRIX_300M_SRC:
369 		con = 2;
370 		mask = CLK_MATRIX_300M_SRC_DIV_MASK;
371 		shift = CLK_MATRIX_300M_SRC_DIV_SHIFT;
372 		break;
373 
374 	case CLK_MATRIX_339M_SRC:
375 		con = 2;
376 		mask = CLK_MATRIX_339M_SRC_DIV_MASK;
377 		shift = CLK_MATRIX_339M_SRC_DIV_SHIFT;
378 		is_halfdiv = 1;
379 		break;
380 
381 	case CLK_MATRIX_400M_SRC:
382 		con = 2;
383 		mask = CLK_MATRIX_400M_SRC_DIV_MASK;
384 		shift = CLK_MATRIX_400M_SRC_DIV_SHIFT;
385 		break;
386 
387 	case CLK_MATRIX_500M_SRC:
388 		con = 3;
389 		mask = CLK_MATRIX_500M_SRC_DIV_MASK;
390 		shift = CLK_MATRIX_500M_SRC_DIV_SHIFT;
391 		sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK;
392 		sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT;
393 		break;
394 
395 	case CLK_MATRIX_600M_SRC:
396 		con = 4;
397 		mask = CLK_MATRIX_600M_SRC_DIV_MASK;
398 		shift = CLK_MATRIX_600M_SRC_DIV_SHIFT;
399 		break;
400 
401 	case ACLK_BUS_VOPGL_ROOT:
402 	case ACLK_BUS_VOPGL_BIU:
403 		con = 43;
404 		mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK;
405 		shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT;
406 		break;
407 
408 	default:
409 		return -ENOENT;
410 	}
411 
412 	if (sel_mask) {
413 		sel = (readl(&cru->clksel_con[con]) & sel_mask) >> sel_shift;
414 		if (sel == CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX) // TODO
415 			prate = priv->gpll_hz;
416 		else
417 			prate = priv->cpll_hz;
418 	} else {
419 		if (is_gpll_parent)
420 			prate = priv->gpll_hz;
421 		else
422 			prate = priv->cpll_hz;
423 	}
424 
425 	div = (readl(&cru->clksel_con[con]) & mask) >> shift;
426 
427 	/* NOTE: '-1' to balance the DIV_TO_RATE() 'div+1' */
428 	return is_halfdiv ? DIV_TO_RATE(prate * 2, (3 + 2 * div) - 1) : DIV_TO_RATE(prate, div);
429 }
430 
rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)431 static ulong rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv *priv,
432 				      ulong clk_id, ulong rate)
433 {
434 	struct rk3528_cru *cru = priv->cru;
435 	u32 sel, div, mask, shift, con;
436 	u32 sel_mask = 0, sel_shift;
437 	u8 is_gpll_parent = 1;
438 	u8 is_halfdiv = 0;
439 	ulong prate = 0;
440 
441 	switch (clk_id) {
442 	case CLK_MATRIX_50M_SRC:
443 		con = 0;
444 		mask = CLK_MATRIX_50M_SRC_DIV_MASK;
445 		shift = CLK_MATRIX_50M_SRC_DIV_SHIFT;
446 		is_gpll_parent = 0;
447 		break;
448 
449 	case CLK_MATRIX_100M_SRC:
450 		con = 0;
451 		mask = CLK_MATRIX_100M_SRC_DIV_MASK;
452 		shift = CLK_MATRIX_100M_SRC_DIV_SHIFT;
453 		is_gpll_parent = 0;
454 		break;
455 
456 	case CLK_MATRIX_150M_SRC:
457 		con = 1;
458 		mask = CLK_MATRIX_150M_SRC_DIV_MASK;
459 		shift = CLK_MATRIX_150M_SRC_DIV_SHIFT;
460 		break;
461 
462 	case CLK_MATRIX_200M_SRC:
463 		con = 1;
464 		mask = CLK_MATRIX_200M_SRC_DIV_MASK;
465 		shift = CLK_MATRIX_200M_SRC_DIV_SHIFT;
466 		break;
467 
468 	case CLK_MATRIX_250M_SRC:
469 		con = 1;
470 		mask = CLK_MATRIX_250M_SRC_DIV_MASK;
471 		shift = CLK_MATRIX_250M_SRC_DIV_SHIFT;
472 		sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK;
473 		sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT;
474 		break;
475 
476 	case CLK_MATRIX_300M_SRC:
477 		con = 2;
478 		mask = CLK_MATRIX_300M_SRC_DIV_MASK;
479 		shift = CLK_MATRIX_300M_SRC_DIV_SHIFT;
480 		break;
481 
482 	case CLK_MATRIX_339M_SRC:
483 		con = 2;
484 		mask = CLK_MATRIX_339M_SRC_DIV_MASK;
485 		shift = CLK_MATRIX_339M_SRC_DIV_SHIFT;
486 		is_halfdiv = 1;
487 		break;
488 
489 	case CLK_MATRIX_400M_SRC:
490 		con = 2;
491 		mask = CLK_MATRIX_400M_SRC_DIV_MASK;
492 		shift = CLK_MATRIX_400M_SRC_DIV_SHIFT;
493 		break;
494 
495 	case CLK_MATRIX_500M_SRC:
496 		con = 3;
497 		mask = CLK_MATRIX_500M_SRC_DIV_MASK;
498 		shift = CLK_MATRIX_500M_SRC_DIV_SHIFT;
499 		sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK;
500 		sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT;
501 		break;
502 
503 	case CLK_MATRIX_600M_SRC:
504 		con = 4;
505 		mask = CLK_MATRIX_600M_SRC_DIV_MASK;
506 		shift = CLK_MATRIX_600M_SRC_DIV_SHIFT;
507 		break;
508 
509 	case ACLK_BUS_VOPGL_ROOT:
510 	case ACLK_BUS_VOPGL_BIU:
511 		con = 43;
512 		mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK;
513 		shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT;
514 		break;
515 
516 	default:
517 		return -ENOENT;
518 	}
519 
520 	if (sel_mask) {
521 		if (priv->gpll_hz % rate == 0) {
522 			sel = CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX; // TODO
523 			prate = priv->gpll_hz;
524 		} else {
525 			sel = CLK_MATRIX_250M_SRC_SEL_CLK_CPLL_MUX;
526 			prate = priv->cpll_hz;
527 		}
528 	} else {
529 		if (is_gpll_parent)
530 			prate = priv->gpll_hz;
531 		else
532 			prate = priv->cpll_hz;
533 	}
534 
535 	if (is_halfdiv)
536 		/* NOTE: '+1' to balance the following rk_clrsetreg() 'div-1' */
537 		div = DIV_ROUND_UP((prate * 2) - (3 * rate), 2 * rate) + 1;
538 	else
539 		div = DIV_ROUND_UP(prate, rate);
540 
541 	rk_clrsetreg(&cru->clksel_con[con], mask, (div - 1) << shift);
542 	if (sel_mask)
543 		rk_clrsetreg(&cru->clksel_con[con], sel_mask, sel << sel_shift);
544 
545 	return rk3528_cgpll_matrix_get_rate(priv, clk_id);
546 }
547 
rk3528_i2c_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)548 static ulong rk3528_i2c_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
549 {
550 	struct rk3528_cru *cru = priv->cru;
551 	u32 id, sel, con, mask, shift;
552 	u8 is_pmucru = 0;
553 	ulong rate;
554 
555 	switch (clk_id) {
556 	case CLK_I2C0:
557 		id = 79;
558 		mask = CLK_I2C0_SEL_MASK;
559 		shift = CLK_I2C0_SEL_SHIFT;
560 		break;
561 
562 	case CLK_I2C1:
563 		id = 79;
564 		mask = CLK_I2C1_SEL_MASK;
565 		shift = CLK_I2C1_SEL_SHIFT;
566 		break;
567 
568 	case CLK_I2C2:
569 		id = 0;
570 		mask = CLK_I2C2_SEL_MASK;
571 		shift = CLK_I2C2_SEL_SHIFT;
572 		is_pmucru = 1;
573 		break;
574 
575 	case CLK_I2C3:
576 		id = 63;
577 		mask = CLK_I2C3_SEL_MASK;
578 		shift = CLK_I2C3_SEL_SHIFT;
579 		break;
580 
581 	case CLK_I2C4:
582 		id = 85;
583 		mask = CLK_I2C4_SEL_MASK;
584 		shift = CLK_I2C4_SEL_SHIFT;
585 		break;
586 
587 	case CLK_I2C5:
588 		id = 63;
589 		mask = CLK_I2C5_SEL_MASK;
590 		shift = CLK_I2C5_SEL_SHIFT;
591 		break;
592 
593 	case CLK_I2C6:
594 		id = 64;
595 		mask = CLK_I2C6_SEL_MASK;
596 		shift = CLK_I2C6_SEL_SHIFT;
597 		break;
598 
599 	case CLK_I2C7:
600 		id = 86;
601 		mask = CLK_I2C7_SEL_MASK;
602 		shift = CLK_I2C7_SEL_SHIFT;
603 		break;
604 
605 	default:
606 		return -ENOENT;
607 	}
608 
609 	if (is_pmucru)
610 		con = readl(&cru->pmuclksel_con[id]);
611 	else
612 		con = readl(&cru->clksel_con[id]);
613 	sel = (con & mask) >> shift;
614 	if (sel == CLK_I2C3_SEL_CLK_MATRIX_200M_SRC)
615 		rate = 200 * MHz;
616 	else if (sel == CLK_I2C3_SEL_CLK_MATRIX_100M_SRC)
617 		rate = 100 * MHz;
618 	else if (sel == CLK_I2C3_SEL_CLK_MATRIX_50M_SRC)
619 		rate = 50 * MHz;
620 	else
621 		rate = OSC_HZ;
622 
623 	return rate;
624 }
625 
rk3528_i2c_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)626 static ulong rk3528_i2c_set_clk(struct rk3528_clk_priv *priv, ulong clk_id,
627 				ulong rate)
628 {
629 	struct rk3528_cru *cru = priv->cru;
630 	u32 id, sel, mask, shift;
631 	u8 is_pmucru = 0;
632 
633 	if (rate == 200 * MHz)
634 		sel = CLK_I2C3_SEL_CLK_MATRIX_200M_SRC;
635 	else if (rate == 100 * MHz)
636 		sel = CLK_I2C3_SEL_CLK_MATRIX_100M_SRC;
637 	else if (rate == 50 * MHz)
638 		sel = CLK_I2C3_SEL_CLK_MATRIX_50M_SRC;
639 	else
640 		sel = CLK_I2C3_SEL_XIN_OSC0_FUNC;
641 
642 	switch (clk_id) {
643 	case CLK_I2C0:
644 		id = 79;
645 		mask = CLK_I2C0_SEL_MASK;
646 		shift = CLK_I2C0_SEL_SHIFT;
647 		break;
648 
649 	case CLK_I2C1:
650 		id = 79;
651 		mask = CLK_I2C1_SEL_MASK;
652 		shift = CLK_I2C1_SEL_SHIFT;
653 		break;
654 
655 	case CLK_I2C2:
656 		id = 0;
657 		mask = CLK_I2C2_SEL_MASK;
658 		shift = CLK_I2C2_SEL_SHIFT;
659 		is_pmucru = 1;
660 		break;
661 
662 	case CLK_I2C3:
663 		id = 63;
664 		mask = CLK_I2C3_SEL_MASK;
665 		shift = CLK_I2C3_SEL_SHIFT;
666 		break;
667 
668 	case CLK_I2C4:
669 		id = 85;
670 		mask = CLK_I2C4_SEL_MASK;
671 		shift = CLK_I2C4_SEL_SHIFT;
672 		break;
673 
674 	case CLK_I2C5:
675 		id = 63;
676 		mask = CLK_I2C5_SEL_MASK;
677 		shift = CLK_I2C5_SEL_SHIFT;
678 
679 	case CLK_I2C6:
680 		id = 64;
681 		mask = CLK_I2C6_SEL_MASK;
682 		shift = CLK_I2C6_SEL_SHIFT;
683 		break;
684 
685 	case CLK_I2C7:
686 		id = 86;
687 		mask = CLK_I2C7_SEL_MASK;
688 		shift = CLK_I2C7_SEL_SHIFT;
689 		break;
690 
691 	default:
692 		return -ENOENT;
693 	}
694 
695 	if (is_pmucru)
696 		rk_clrsetreg(&cru->pmuclksel_con[id], mask, sel << shift);
697 	else
698 		rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
699 
700 	return rk3528_i2c_get_clk(priv, clk_id);
701 }
702 
rk3528_spi_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)703 static ulong rk3528_spi_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
704 {
705 	struct rk3528_cru *cru = priv->cru;
706 	u32 id, sel, con, mask, shift;
707 	ulong rate;
708 
709 	switch (clk_id) {
710 	case CLK_SPI0:
711 		id = 79;
712 		mask = CLK_SPI0_SEL_MASK;
713 		shift = CLK_SPI0_SEL_SHIFT;
714 		break;
715 
716 	case CLK_SPI1:
717 		id = 63;
718 		mask = CLK_SPI1_SEL_MASK;
719 		shift = CLK_SPI1_SEL_SHIFT;
720 		break;
721 	default:
722 		return -ENOENT;
723 	}
724 
725 	con = readl(&cru->clksel_con[id]);
726 	sel = (con & mask) >> shift;
727 	if (sel == CLK_SPI1_SEL_CLK_MATRIX_200M_SRC)
728 		rate = 200 * MHz;
729 	else if (sel == CLK_SPI1_SEL_CLK_MATRIX_100M_SRC)
730 		rate = 100 * MHz;
731 	else if (sel == CLK_SPI1_SEL_CLK_MATRIX_50M_SRC)
732 		rate = 50 * MHz;
733 	else
734 		rate = OSC_HZ;
735 
736 	return rate;
737 }
738 
rk3528_spi_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)739 static ulong rk3528_spi_set_clk(struct rk3528_clk_priv *priv,
740 				ulong clk_id, ulong rate)
741 {
742 	struct rk3528_cru *cru = priv->cru;
743 	u32 id, sel, mask, shift;
744 
745 	if (rate == 200 * MHz)
746 		sel = CLK_SPI1_SEL_CLK_MATRIX_200M_SRC;
747 	else if (rate == 100 * MHz)
748 		sel = CLK_SPI1_SEL_CLK_MATRIX_100M_SRC;
749 	else if (rate == 50 * MHz)
750 		sel = CLK_SPI1_SEL_CLK_MATRIX_50M_SRC;
751 	else
752 		sel = CLK_SPI1_SEL_XIN_OSC0_FUNC;
753 
754 	switch (clk_id) {
755 	case CLK_SPI0:
756 		id = 79;
757 		mask = CLK_SPI0_SEL_MASK;
758 		shift = CLK_SPI0_SEL_SHIFT;
759 		break;
760 
761 	case CLK_SPI1:
762 		id = 63;
763 		mask = CLK_SPI1_SEL_MASK;
764 		shift = CLK_SPI1_SEL_SHIFT;
765 		break;
766 	default:
767 		return -ENOENT;
768 	}
769 
770 	rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
771 
772 	return rk3528_spi_get_clk(priv, clk_id);
773 }
774 
rk3528_pwm_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)775 static ulong rk3528_pwm_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
776 {
777 	struct rk3528_cru *cru = priv->cru;
778 	u32 id, sel, con, mask, shift;
779 	ulong rate;
780 
781 	switch (clk_id) {
782 	case CLK_PWM0:
783 		id = 44;
784 		mask = CLK_PWM0_SEL_MASK;
785 		shift = CLK_PWM0_SEL_SHIFT;
786 		break;
787 
788 	case CLK_PWM1:
789 		id = 44;
790 		mask = CLK_PWM1_SEL_MASK;
791 		shift = CLK_PWM1_SEL_SHIFT;
792 		break;
793 
794 	default:
795 		return -ENOENT;
796 	}
797 
798 	con = readl(&cru->clksel_con[id]);
799 	sel = (con & mask) >> shift;
800 	if (sel == CLK_PWM0_SEL_CLK_MATRIX_100M_SRC)
801 		rate = 100 * MHz;
802 	if (sel == CLK_PWM0_SEL_CLK_MATRIX_50M_SRC)
803 		rate = 50 * MHz;
804 	else
805 		rate = OSC_HZ;
806 
807 	return rate;
808 }
809 
rk3528_pwm_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)810 static ulong rk3528_pwm_set_clk(struct rk3528_clk_priv *priv,
811 				ulong clk_id, ulong rate)
812 {
813 	struct rk3528_cru *cru = priv->cru;
814 	u32 id, sel, mask, shift;
815 
816 	if (rate == 100 * MHz)
817 		sel = CLK_PWM0_SEL_CLK_MATRIX_100M_SRC;
818 	else if (rate == 50 * MHz)
819 		sel = CLK_PWM0_SEL_CLK_MATRIX_50M_SRC;
820 	else
821 		sel = CLK_PWM0_SEL_XIN_OSC0_FUNC;
822 
823 	switch (clk_id) {
824 	case CLK_PWM0:
825 		id = 44;
826 		mask = CLK_PWM0_SEL_MASK;
827 		shift = CLK_PWM0_SEL_SHIFT;
828 		break;
829 
830 	case CLK_PWM1:
831 		id = 44;
832 		mask = CLK_PWM1_SEL_MASK;
833 		shift = CLK_PWM1_SEL_SHIFT;
834 		break;
835 
836 	default:
837 		return -ENOENT;
838 	}
839 
840 	rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
841 
842 	return rk3528_pwm_get_clk(priv, clk_id);
843 }
844 
rk3528_adc_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)845 static ulong rk3528_adc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
846 {
847 	struct rk3528_cru *cru = priv->cru;
848 	u32 div, con;
849 
850 	con = readl(&cru->clksel_con[74]);
851 	switch (clk_id) {
852 	case CLK_SARADC:
853 		div = (con & CLK_SARADC_DIV_MASK) >>
854 			CLK_SARADC_DIV_SHIFT;
855 		break;
856 
857 	case CLK_TSADC_TSEN:
858 		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
859 			CLK_TSADC_TSEN_DIV_SHIFT;
860 		break;
861 
862 	case CLK_TSADC:
863 		div = (con & CLK_TSADC_DIV_MASK) >>
864 			CLK_TSADC_DIV_SHIFT;
865 		break;
866 
867 	default:
868 		return -ENOENT;
869 	}
870 
871 	return DIV_TO_RATE(OSC_HZ, div);
872 }
873 
rk3528_adc_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)874 static ulong rk3528_adc_set_clk(struct rk3528_clk_priv *priv,
875 				ulong clk_id, ulong rate)
876 {
877 	struct rk3528_cru *cru = priv->cru;
878 	u32 div, mask, shift;
879 
880 	switch (clk_id) {
881 	case CLK_SARADC:
882 		mask = CLK_SARADC_DIV_MASK;
883 		shift =	CLK_SARADC_DIV_SHIFT;
884 		break;
885 
886 	case CLK_TSADC_TSEN:
887 		mask = CLK_TSADC_TSEN_DIV_MASK;
888 		shift =	CLK_TSADC_TSEN_DIV_SHIFT;
889 		break;
890 
891 	case CLK_TSADC:
892 		mask = CLK_TSADC_DIV_MASK;
893 		shift =	CLK_TSADC_DIV_SHIFT;
894 		break;
895 
896 	default:
897 		return -ENOENT;
898 	}
899 
900 	div = DIV_ROUND_UP(OSC_HZ, rate);
901 	rk_clrsetreg(&cru->clksel_con[74], mask, (div - 1) << shift);
902 
903 	return rk3528_adc_get_clk(priv, clk_id);
904 }
905 
rk3528_sdmmc_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)906 static ulong rk3528_sdmmc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
907 {
908 	struct rk3528_cru *cru = priv->cru;
909 	u32 div, sel, con;
910 	ulong prate;
911 
912 	con = readl(&cru->clksel_con[85]);
913 	div = (con & CCLK_SRC_SDMMC0_DIV_MASK) >>
914 		CCLK_SRC_SDMMC0_DIV_SHIFT;
915 	sel = (con & CCLK_SRC_SDMMC0_SEL_MASK) >>
916 		CCLK_SRC_SDMMC0_SEL_SHIFT;
917 
918 	if (sel == CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX)
919 		prate = priv->gpll_hz;
920 	else if (sel == CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX)
921 		prate = priv->cpll_hz;
922 	else
923 		prate = OSC_HZ;
924 
925 	return DIV_TO_RATE(prate, div);
926 }
927 
rk3528_sdmmc_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)928 static ulong rk3528_sdmmc_set_clk(struct rk3528_clk_priv *priv,
929 				  ulong clk_id, ulong rate)
930 {
931 	struct rk3528_cru *cru = priv->cru;
932 	u32 div, sel;
933 
934 	if (OSC_HZ % rate == 0) {
935 		div = DIV_ROUND_UP(OSC_HZ, rate);
936 		sel = CCLK_SRC_SDMMC0_SEL_XIN_OSC0_FUNC;
937 	} else if ((priv->cpll_hz % rate) == 0) {
938 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
939 		sel = CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX;
940 	} else {
941 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
942 		sel = CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX;
943 	}
944 
945 	assert(div - 1 <= 31);
946 	rk_clrsetreg(&cru->clksel_con[85],
947 		     CCLK_SRC_SDMMC0_SEL_MASK |
948 		     CCLK_SRC_SDMMC0_DIV_MASK,
949 		     sel << CCLK_SRC_SDMMC0_SEL_SHIFT |
950 		     (div - 1) << CCLK_SRC_SDMMC0_DIV_SHIFT);
951 
952 	return rk3528_sdmmc_get_clk(priv, clk_id);
953 }
954 
rk3528_sfc_get_clk(struct rk3528_clk_priv * priv)955 static ulong rk3528_sfc_get_clk(struct rk3528_clk_priv *priv)
956 {
957 	struct rk3528_cru *cru = priv->cru;
958 	u32 div, sel, con, parent;
959 
960 	con = readl(&cru->clksel_con[61]);
961 	div = (con & SCLK_SFC_DIV_MASK) >>
962 		SCLK_SFC_DIV_SHIFT;
963 	sel = (con & SCLK_SFC_SEL_MASK) >>
964 		SCLK_SFC_SEL_SHIFT;
965 	if (sel == SCLK_SFC_SEL_CLK_GPLL_MUX)
966 		parent = priv->gpll_hz;
967 	else if (sel == SCLK_SFC_SEL_CLK_CPLL_MUX)
968 		parent = priv->cpll_hz;
969 	else
970 		parent = OSC_HZ;
971 
972 	return DIV_TO_RATE(parent, div);
973 }
974 
rk3528_sfc_set_clk(struct rk3528_clk_priv * priv,ulong rate)975 static ulong rk3528_sfc_set_clk(struct rk3528_clk_priv *priv, ulong rate)
976 {
977 	struct rk3528_cru *cru = priv->cru;
978 	int div, sel;
979 
980 	if (OSC_HZ % rate == 0) {
981 		div = DIV_ROUND_UP(OSC_HZ, rate);
982 		sel = SCLK_SFC_SEL_XIN_OSC0_FUNC;
983 	} else if ((priv->cpll_hz % rate) == 0) {
984 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
985 		sel = SCLK_SFC_SEL_CLK_CPLL_MUX;
986 	} else {
987 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
988 		sel = SCLK_SFC_SEL_CLK_GPLL_MUX;
989 	}
990 
991 	assert(div - 1 <= 63);
992 	rk_clrsetreg(&cru->clksel_con[61],
993 		     SCLK_SFC_SEL_MASK |
994 		     SCLK_SFC_DIV_MASK,
995 		     sel << SCLK_SFC_SEL_SHIFT |
996 		     (div - 1) << SCLK_SFC_DIV_SHIFT);
997 
998 	return rk3528_sfc_get_clk(priv);
999 }
1000 
rk3528_emmc_get_clk(struct rk3528_clk_priv * priv)1001 static ulong rk3528_emmc_get_clk(struct rk3528_clk_priv *priv)
1002 {
1003 	struct rk3528_cru *cru = priv->cru;
1004 	u32 div, sel, con, parent;
1005 
1006 	con = readl(&cru->clksel_con[62]);
1007 	div = (con & CCLK_SRC_EMMC_DIV_MASK) >>
1008 		CCLK_SRC_EMMC_DIV_SHIFT;
1009 	sel = (con & CCLK_SRC_EMMC_SEL_MASK) >>
1010 		CCLK_SRC_EMMC_SEL_SHIFT;
1011 
1012 	if (sel == CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX)
1013 		parent = priv->gpll_hz;
1014 	else if (sel == CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX)
1015 		parent = priv->cpll_hz;
1016 	else
1017 		parent = OSC_HZ;
1018 
1019 	return DIV_TO_RATE(parent, div);
1020 }
1021 
rk3528_emmc_set_clk(struct rk3528_clk_priv * priv,ulong rate)1022 static ulong rk3528_emmc_set_clk(struct rk3528_clk_priv *priv, ulong rate)
1023 {
1024 	struct rk3528_cru *cru = priv->cru;
1025 	u32 div, sel;
1026 
1027 	if (OSC_HZ % rate == 0) {
1028 		div = DIV_ROUND_UP(OSC_HZ, rate);
1029 		sel = CCLK_SRC_EMMC_SEL_XIN_OSC0_FUNC;
1030 	} else if ((priv->cpll_hz % rate) == 0) {
1031 		div = DIV_ROUND_UP(priv->cpll_hz, rate);
1032 		sel = CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX;
1033 	} else {
1034 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1035 		sel = CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX;
1036 	}
1037 
1038 	assert(div - 1 <= 31);
1039 	rk_clrsetreg(&cru->clksel_con[62],
1040 		     CCLK_SRC_EMMC_SEL_MASK |
1041 		     CCLK_SRC_EMMC_DIV_MASK,
1042 		     sel << CCLK_SRC_EMMC_SEL_SHIFT |
1043 		     (div - 1) << CCLK_SRC_EMMC_DIV_SHIFT);
1044 
1045 	return rk3528_emmc_get_clk(priv);
1046 }
1047 
rk3528_dclk_vop_get_clk(struct rk3528_clk_priv * priv,ulong clk_id)1048 static ulong rk3528_dclk_vop_get_clk(struct rk3528_clk_priv *priv, ulong clk_id)
1049 {
1050 	struct rk3528_cru *cru = priv->cru;
1051 	u32 div_mask, div_shift;
1052 	u32 sel_mask, sel_shift;
1053 	u32 id, con, sel, div;
1054 	ulong prate;
1055 
1056 	switch (clk_id) {
1057 	case DCLK_VOP0:
1058 		id = 32;
1059 		sel_mask = DCLK_VOP_SRC0_SEL_MASK;
1060 		sel_shift = DCLK_VOP_SRC0_SEL_SHIFT;
1061 		/* FIXME if need src: clk_hdmiphy_pixel_io */
1062 		div_mask = DCLK_VOP_SRC0_DIV_MASK;
1063 		div_shift = DCLK_VOP_SRC0_DIV_SHIFT;
1064 		break;
1065 
1066 	case DCLK_VOP1:
1067 		id = 33;
1068 		sel_mask = DCLK_VOP_SRC1_SEL_MASK;
1069 		sel_shift = DCLK_VOP_SRC1_SEL_SHIFT;
1070 		div_mask = DCLK_VOP_SRC1_DIV_MASK;
1071 		div_shift = DCLK_VOP_SRC1_DIV_SHIFT;
1072 		break;
1073 
1074 	default:
1075 		return -ENOENT;
1076 	}
1077 
1078 	con = readl(&cru->clksel_con[id]);
1079 	div = (con & div_mask) >> div_shift;
1080 	sel = (con & sel_mask) >> sel_shift;
1081 	if (sel == DCLK_VOP_SRC_SEL_CLK_GPLL_MUX)
1082 		prate = priv->gpll_hz;
1083 	else
1084 		prate = priv->cpll_hz;
1085 
1086 	return DIV_TO_RATE(prate, div);
1087 }
1088 
rk3528_dclk_vop_set_clk(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)1089 static ulong rk3528_dclk_vop_set_clk(struct rk3528_clk_priv *priv,
1090 				     ulong clk_id, ulong rate)
1091 {
1092 	struct rk3528_cru *cru = priv->cru;
1093 	u32 div_mask, div_shift;
1094 	u32 sel_mask, sel_shift;
1095 	u32 id, sel, div;
1096 	ulong prate;
1097 
1098 	switch (clk_id) {
1099 	case DCLK_VOP0:
1100 		id = 32;
1101 		sel_mask = DCLK_VOP_SRC0_SEL_MASK;
1102 		sel_shift = DCLK_VOP_SRC0_SEL_SHIFT;
1103 		/* FIXME if need src: clk_hdmiphy_pixel_io */
1104 		div_mask = DCLK_VOP_SRC0_DIV_MASK;
1105 		div_shift = DCLK_VOP_SRC0_DIV_SHIFT;
1106 		break;
1107 
1108 	case DCLK_VOP1:
1109 		id = 33;
1110 		sel_mask = DCLK_VOP_SRC1_SEL_MASK;
1111 		sel_shift = DCLK_VOP_SRC1_SEL_SHIFT;
1112 		div_mask = DCLK_VOP_SRC1_DIV_MASK;
1113 		div_shift = DCLK_VOP_SRC1_DIV_SHIFT;
1114 		break;
1115 
1116 	default:
1117 		return -ENOENT;
1118 	}
1119 
1120 	if ((priv->gpll_hz % rate) == 0) {
1121 		prate = priv->gpll_hz;
1122 		sel = (DCLK_VOP_SRC_SEL_CLK_GPLL_MUX << sel_shift) & sel_mask;
1123 	} else {
1124 		prate = priv->cpll_hz;
1125 		sel = (DCLK_VOP_SRC_SEL_CLK_CPLL_MUX << sel_shift) & sel_mask;
1126 	}
1127 
1128 	div = ((DIV_ROUND_UP(prate, rate) - 1) << div_shift) & div_mask;
1129 	rk_clrsetreg(&cru->clksel_con[id], sel, div);
1130 
1131 	return rk3528_dclk_vop_get_clk(priv, clk_id);
1132 }
1133 
rk3528_uart_get_rate(struct rk3528_clk_priv * priv,ulong clk_id)1134 static ulong rk3528_uart_get_rate(struct rk3528_clk_priv *priv, ulong clk_id)
1135 {
1136 	struct rk3528_cru *cru = priv->cru;
1137 	u32 sel_shift, sel_mask, div_shift, div_mask;
1138 	u32 sel, id, con, frac_div, div;
1139 	ulong m, n, rate;
1140 
1141 	switch (clk_id) {
1142 	case SCLK_UART0:
1143 		id = 6;
1144 		sel_shift = SCLK_UART0_SRC_SEL_SHIFT;
1145 		sel_mask = SCLK_UART0_SRC_SEL_MASK;
1146 		div_shift = CLK_UART0_SRC_DIV_SHIFT;
1147 		div_mask = CLK_UART0_SRC_DIV_MASK;
1148 		break;
1149 
1150 	case SCLK_UART1:
1151 		id = 8;
1152 		sel_shift = SCLK_UART1_SRC_SEL_SHIFT;
1153 		sel_mask = SCLK_UART1_SRC_SEL_MASK;
1154 		div_shift = CLK_UART1_SRC_DIV_SHIFT;
1155 		div_mask = CLK_UART1_SRC_DIV_MASK;
1156 		break;
1157 
1158 	case SCLK_UART2:
1159 		id = 10;
1160 		sel_shift = SCLK_UART2_SRC_SEL_SHIFT;
1161 		sel_mask = SCLK_UART2_SRC_SEL_MASK;
1162 		div_shift = CLK_UART2_SRC_DIV_SHIFT;
1163 		div_mask = CLK_UART2_SRC_DIV_MASK;
1164 		break;
1165 
1166 	case SCLK_UART3:
1167 		id = 12;
1168 		sel_shift = SCLK_UART3_SRC_SEL_SHIFT;
1169 		sel_mask = SCLK_UART3_SRC_SEL_MASK;
1170 		div_shift = CLK_UART3_SRC_DIV_SHIFT;
1171 		div_mask = CLK_UART3_SRC_DIV_MASK;
1172 		break;
1173 
1174 	case SCLK_UART4:
1175 		id = 14;
1176 		sel_shift = SCLK_UART4_SRC_SEL_SHIFT;
1177 		sel_mask = SCLK_UART4_SRC_SEL_MASK;
1178 		div_shift = CLK_UART4_SRC_DIV_SHIFT;
1179 		div_mask = CLK_UART4_SRC_DIV_MASK;
1180 		break;
1181 
1182 	case SCLK_UART5:
1183 		id = 16;
1184 		sel_shift = SCLK_UART5_SRC_SEL_SHIFT;
1185 		sel_mask = SCLK_UART5_SRC_SEL_MASK;
1186 		div_shift = CLK_UART5_SRC_DIV_SHIFT;
1187 		div_mask = CLK_UART5_SRC_DIV_MASK;
1188 		break;
1189 
1190 	case SCLK_UART6:
1191 		id = 18;
1192 		sel_shift = SCLK_UART6_SRC_SEL_SHIFT;
1193 		sel_mask = SCLK_UART6_SRC_SEL_MASK;
1194 		div_shift = CLK_UART6_SRC_DIV_SHIFT;
1195 		div_mask = CLK_UART6_SRC_DIV_MASK;
1196 		break;
1197 
1198 	case SCLK_UART7:
1199 		id = 20;
1200 		sel_shift = SCLK_UART7_SRC_SEL_SHIFT;
1201 		sel_mask = SCLK_UART7_SRC_SEL_MASK;
1202 		div_shift = CLK_UART7_SRC_DIV_SHIFT;
1203 		div_mask = CLK_UART7_SRC_DIV_MASK;
1204 		break;
1205 
1206 	default:
1207 		return -ENOENT;
1208 	}
1209 
1210 	con = readl(&cru->clksel_con[id - 2]);
1211 	div = (con & div_mask) >> div_shift;
1212 
1213 	con = readl(&cru->clksel_con[id]);
1214 	sel = (con & sel_mask) >> sel_shift;
1215 
1216 	if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_SRC) {
1217 		rate = DIV_TO_RATE(priv->gpll_hz, div);
1218 	} else if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_FRAC) {
1219 		frac_div = readl(&cru->clksel_con[id - 1]);
1220 		n = (frac_div & 0xffff0000) >> 16;
1221 		m = frac_div & 0x0000ffff;
1222 		rate = DIV_TO_RATE(priv->gpll_hz, div) * n / m;
1223 	} else {
1224 		rate = OSC_HZ;
1225 	}
1226 
1227 	return rate;
1228 }
1229 
rk3528_uart_set_rate(struct rk3528_clk_priv * priv,ulong clk_id,ulong rate)1230 static ulong rk3528_uart_set_rate(struct rk3528_clk_priv *priv,
1231 				  ulong clk_id, ulong rate)
1232 {
1233 	struct rk3528_cru *cru = priv->cru;
1234 	u32 sel_shift, sel_mask, div_shift, div_mask;
1235 	u32 sel, id, div;
1236 	ulong m = 0, n = 0, val;
1237 
1238 	if (rate == OSC_HZ) {
1239 		sel = SCLK_UART0_SRC_SEL_XIN_OSC0_FUNC;
1240 		div = DIV_ROUND_UP(OSC_HZ, rate);
1241 	} else if (priv->gpll_hz % rate == 0) {
1242 		sel = SCLK_UART0_SRC_SEL_CLK_UART0_SRC;
1243 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1244 	} else {
1245 		sel = SCLK_UART0_SRC_SEL_CLK_UART0_FRAC;
1246 		div = 2;
1247 		rational_best_approximation(rate, priv->gpll_hz / div,
1248 					    GENMASK(16 - 1, 0),
1249 					    GENMASK(16 - 1, 0),
1250 					    &n, &m);
1251 	}
1252 
1253 	switch (clk_id) {
1254 	case SCLK_UART0:
1255 		id = 6;
1256 		sel_shift = SCLK_UART0_SRC_SEL_SHIFT;
1257 		sel_mask = SCLK_UART0_SRC_SEL_MASK;
1258 		div_shift = CLK_UART0_SRC_DIV_SHIFT;
1259 		div_mask = CLK_UART0_SRC_DIV_MASK;
1260 		break;
1261 
1262 	case SCLK_UART1:
1263 		id = 8;
1264 		sel_shift = SCLK_UART1_SRC_SEL_SHIFT;
1265 		sel_mask = SCLK_UART1_SRC_SEL_MASK;
1266 		div_shift = CLK_UART1_SRC_DIV_SHIFT;
1267 		div_mask = CLK_UART1_SRC_DIV_MASK;
1268 		break;
1269 
1270 	case SCLK_UART2:
1271 		id = 10;
1272 		sel_shift = SCLK_UART2_SRC_SEL_SHIFT;
1273 		sel_mask = SCLK_UART2_SRC_SEL_MASK;
1274 		div_shift = CLK_UART2_SRC_DIV_SHIFT;
1275 		div_mask = CLK_UART2_SRC_DIV_MASK;
1276 		break;
1277 
1278 	case SCLK_UART3:
1279 		id = 12;
1280 		sel_shift = SCLK_UART3_SRC_SEL_SHIFT;
1281 		sel_mask = SCLK_UART3_SRC_SEL_MASK;
1282 		div_shift = CLK_UART3_SRC_DIV_SHIFT;
1283 		div_mask = CLK_UART3_SRC_DIV_MASK;
1284 		break;
1285 
1286 	case SCLK_UART4:
1287 		id = 14;
1288 		sel_shift = SCLK_UART4_SRC_SEL_SHIFT;
1289 		sel_mask = SCLK_UART4_SRC_SEL_MASK;
1290 		div_shift = CLK_UART4_SRC_DIV_SHIFT;
1291 		div_mask = CLK_UART4_SRC_DIV_MASK;
1292 		break;
1293 
1294 	case SCLK_UART5:
1295 		id = 16;
1296 		sel_shift = SCLK_UART5_SRC_SEL_SHIFT;
1297 		sel_mask = SCLK_UART5_SRC_SEL_MASK;
1298 		div_shift = CLK_UART5_SRC_DIV_SHIFT;
1299 		div_mask = CLK_UART5_SRC_DIV_MASK;
1300 		break;
1301 
1302 	case SCLK_UART6:
1303 		id = 18;
1304 		sel_shift = SCLK_UART6_SRC_SEL_SHIFT;
1305 		sel_mask = SCLK_UART6_SRC_SEL_MASK;
1306 		div_shift = CLK_UART6_SRC_DIV_SHIFT;
1307 		div_mask = CLK_UART6_SRC_DIV_MASK;
1308 		break;
1309 
1310 	case SCLK_UART7:
1311 		id = 20;
1312 		sel_shift = SCLK_UART7_SRC_SEL_SHIFT;
1313 		sel_mask = SCLK_UART7_SRC_SEL_MASK;
1314 		div_shift = CLK_UART7_SRC_DIV_SHIFT;
1315 		div_mask = CLK_UART7_SRC_DIV_MASK;
1316 		break;
1317 
1318 	default:
1319 		return -ENOENT;
1320 	}
1321 
1322 	rk_clrsetreg(&cru->clksel_con[id - 2], div_mask, (div - 1) << div_shift);
1323 	rk_clrsetreg(&cru->clksel_con[id], sel_mask, sel << sel_shift);
1324 	if (m && n) {
1325 		val = n << 16 | m;
1326 		writel(val, &cru->clksel_con[id - 1]);
1327 	}
1328 
1329 	return rk3528_uart_get_rate(priv, clk_id);
1330 }
1331 
rk3528_clk_get_rate(struct clk * clk)1332 static ulong rk3528_clk_get_rate(struct clk *clk)
1333 {
1334 	struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1335 	ulong rate = 0;
1336 
1337 	if (!priv->gpll_hz || !priv->cpll_hz) {
1338 		printf("%s: gpll=%lu, cpll=%ld\n",
1339 		       __func__, priv->gpll_hz, priv->cpll_hz);
1340 		return -ENOENT;
1341 	}
1342 
1343 	switch (clk->id) {
1344 	case PLL_APLL:
1345 	case ARMCLK:
1346 		rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru,
1347 					     APLL);
1348 		break;
1349 	case PLL_CPLL:
1350 		rate = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], priv->cru,
1351 					     CPLL);
1352 		break;
1353 	case PLL_GPLL:
1354 		rate = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], priv->cru,
1355 					     GPLL);
1356 		break;
1357 
1358 	case PLL_PPLL:
1359 		rate = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], priv->cru,
1360 					     PPLL);
1361 		break;
1362 	case PLL_DPLL:
1363 		rate = rockchip_pll_get_rate(&rk3528_pll_clks[DPLL], priv->cru,
1364 					     DPLL);
1365 		break;
1366 
1367 	case TCLK_WDT_NS:
1368 		rate = OSC_HZ;
1369 		break;
1370 	case CLK_I2C0:
1371 	case CLK_I2C1:
1372 	case CLK_I2C2:
1373 	case CLK_I2C3:
1374 	case CLK_I2C4:
1375 	case CLK_I2C5:
1376 	case CLK_I2C6:
1377 	case CLK_I2C7:
1378 		rate = rk3528_i2c_get_clk(priv, clk->id);
1379 		break;
1380 	case CLK_SPI0:
1381 	case CLK_SPI1:
1382 		rate = rk3528_spi_get_clk(priv, clk->id);
1383 		break;
1384 	case CLK_PWM0:
1385 	case CLK_PWM1:
1386 		rate = rk3528_pwm_get_clk(priv, clk->id);
1387 		break;
1388 	case CLK_SARADC:
1389 	case CLK_TSADC:
1390 	case CLK_TSADC_TSEN:
1391 		rate = rk3528_adc_get_clk(priv, clk->id);
1392 		break;
1393 	case CCLK_SRC_EMMC:
1394 		rate = rk3528_emmc_get_clk(priv);
1395 		break;
1396 	case HCLK_SDMMC0:
1397 	case CCLK_SRC_SDMMC0:
1398 		rate = rk3528_sdmmc_get_clk(priv, clk->id);
1399 		break;
1400 	case SCLK_SFC:
1401 		rate = rk3528_sfc_get_clk(priv);
1402 		break;
1403 	case DCLK_VOP0:
1404 	case DCLK_VOP1:
1405 		rate = rk3528_dclk_vop_get_clk(priv, clk->id);
1406 		break;
1407 	case DCLK_CVBS:
1408 		rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1) / 4;
1409 		break;
1410 	case DCLK_4X_CVBS:
1411 		rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1);
1412 		break;
1413 	case SCLK_UART0:
1414 	case SCLK_UART1:
1415 	case SCLK_UART2:
1416 	case SCLK_UART3:
1417 	case SCLK_UART4:
1418 	case SCLK_UART5:
1419 	case SCLK_UART6:
1420 	case SCLK_UART7:
1421 		rate = rk3528_uart_get_rate(priv, clk->id);
1422 		break;
1423 	case CLK_MATRIX_50M_SRC:
1424 	case CLK_MATRIX_100M_SRC:
1425 	case CLK_MATRIX_150M_SRC:
1426 	case CLK_MATRIX_200M_SRC:
1427 	case CLK_MATRIX_250M_SRC:
1428 	case CLK_MATRIX_300M_SRC:
1429 	case CLK_MATRIX_339M_SRC:
1430 	case CLK_MATRIX_400M_SRC:
1431 	case CLK_MATRIX_500M_SRC:
1432 	case CLK_MATRIX_600M_SRC:
1433 	case ACLK_BUS_VOPGL_BIU:
1434 		rate = rk3528_cgpll_matrix_get_rate(priv, clk->id);
1435 		break;
1436 	case CLK_PPLL_50M_MATRIX:
1437 	case CLK_PPLL_100M_MATRIX:
1438 	case CLK_PPLL_125M_MATRIX:
1439 	case CLK_GMAC1_VPU_25M:
1440 	case CLK_GMAC1_RMII_VPU:
1441 	case CLK_GMAC1_SRC_VPU:
1442 		rate = rk3528_ppll_matrix_get_rate(priv, clk->id);
1443 		break;
1444 	default:
1445 		return -ENOENT;
1446 	}
1447 
1448 	return rate;
1449 };
1450 
rk3528_clk_set_rate(struct clk * clk,ulong rate)1451 static ulong rk3528_clk_set_rate(struct clk *clk, ulong rate)
1452 {
1453 	struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1454 	ulong ret = 0;
1455 
1456 	if (!priv->gpll_hz) {
1457 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1458 		return -ENOENT;
1459 	}
1460 
1461 	switch (clk->id) {
1462 	case PLL_APLL:
1463 	case ARMCLK:
1464 		if (priv->armclk_hz)
1465 			rk3528_armclk_set_clk(priv, rate);
1466 		priv->armclk_hz = rate;
1467 		break;
1468 	case PLL_CPLL:
1469 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru,
1470 					    CPLL, rate);
1471 		priv->cpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL],
1472 						      priv->cru, CPLL);
1473 		break;
1474 	case PLL_GPLL:
1475 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru,
1476 					    GPLL, rate);
1477 		priv->gpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL],
1478 						      priv->cru, GPLL);
1479 		break;
1480 	case PLL_PPLL:
1481 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru,
1482 					    PPLL, rate);
1483 		priv->ppll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL],
1484 						      priv->cru, PPLL);
1485 		break;
1486 	case TCLK_WDT_NS:
1487 		return (rate == OSC_HZ) ? 0 : -EINVAL;
1488 	case CLK_I2C0:
1489 	case CLK_I2C1:
1490 	case CLK_I2C2:
1491 	case CLK_I2C3:
1492 	case CLK_I2C4:
1493 	case CLK_I2C5:
1494 	case CLK_I2C6:
1495 	case CLK_I2C7:
1496 		ret = rk3528_i2c_set_clk(priv, clk->id, rate);
1497 		break;
1498 	case CLK_SPI0:
1499 	case CLK_SPI1:
1500 		ret = rk3528_spi_set_clk(priv, clk->id, rate);
1501 		break;
1502 	case CLK_PWM0:
1503 	case CLK_PWM1:
1504 		ret = rk3528_pwm_set_clk(priv, clk->id, rate);
1505 		break;
1506 	case CLK_SARADC:
1507 	case CLK_TSADC:
1508 	case CLK_TSADC_TSEN:
1509 		ret = rk3528_adc_set_clk(priv, clk->id, rate);
1510 		break;
1511 	case HCLK_SDMMC0:
1512 	case CCLK_SRC_SDMMC0:
1513 		ret = rk3528_sdmmc_set_clk(priv, clk->id, rate);
1514 		break;
1515 	case SCLK_SFC:
1516 		ret = rk3528_sfc_set_clk(priv, rate);
1517 		break;
1518 	case CCLK_SRC_EMMC:
1519 		ret = rk3528_emmc_set_clk(priv, rate);
1520 		break;
1521 	case DCLK_VOP0:
1522 	case DCLK_VOP1:
1523 		ret = rk3528_dclk_vop_set_clk(priv, clk->id, rate);
1524 		break;
1525 	case SCLK_UART0:
1526 	case SCLK_UART1:
1527 	case SCLK_UART2:
1528 	case SCLK_UART3:
1529 	case SCLK_UART4:
1530 	case SCLK_UART5:
1531 	case SCLK_UART6:
1532 	case SCLK_UART7:
1533 		ret = rk3528_uart_set_rate(priv, clk->id, rate);
1534 		break;
1535 	case CLK_MATRIX_50M_SRC:
1536 	case CLK_MATRIX_100M_SRC:
1537 	case CLK_MATRIX_150M_SRC:
1538 	case CLK_MATRIX_200M_SRC:
1539 	case CLK_MATRIX_250M_SRC:
1540 	case CLK_MATRIX_300M_SRC:
1541 	case CLK_MATRIX_339M_SRC:
1542 	case CLK_MATRIX_400M_SRC:
1543 	case CLK_MATRIX_500M_SRC:
1544 	case CLK_MATRIX_600M_SRC:
1545 	case ACLK_BUS_VOPGL_BIU:
1546 		ret = rk3528_cgpll_matrix_set_rate(priv, clk->id, rate);
1547 		break;
1548 	case CLK_PPLL_50M_MATRIX:
1549 	case CLK_PPLL_100M_MATRIX:
1550 	case CLK_PPLL_125M_MATRIX:
1551 	case CLK_GMAC1_VPU_25M:
1552 		ret = rk3528_ppll_matrix_set_rate(priv, clk->id, rate);
1553 		break;
1554 	case CLK_GMAC1_RMII_VPU:
1555 	case CLK_GMAC1_SRC_VPU:
1556 		/* dummy set */
1557 		ret = rk3528_ppll_matrix_get_rate(priv, clk->id);
1558 		break;
1559 	default:
1560 		return -ENOENT;
1561 	}
1562 
1563 	return ret;
1564 };
1565 
1566 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
rk3528_clk_set_parent(struct clk * clk,struct clk * parent)1567 static int rk3528_clk_set_parent(struct clk *clk, struct clk *parent)
1568 {
1569 	struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
1570 	const char *clock_dev_name = parent->dev->name;
1571 
1572 	switch (clk->id) {
1573 	case DCLK_VOP0:
1574 		if (!strcmp(clock_dev_name, "inno_hdmi_pll_clk"))
1575 			/* clk_hdmiphy_pixel_io */
1576 			rk_clrsetreg(&priv->cru->clksel_con[84], 0x1, 1);
1577 		else
1578 			rk_clrsetreg(&priv->cru->clksel_con[84], 0x1, 0);
1579 		break;
1580 
1581 	default:
1582 		return -ENOENT;
1583 	}
1584 
1585 	return 0;
1586 }
1587 #endif
1588 
1589 static struct clk_ops rk3528_clk_ops = {
1590 	.get_rate = rk3528_clk_get_rate,
1591 	.set_rate = rk3528_clk_set_rate,
1592 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1593 	.set_parent = rk3528_clk_set_parent,
1594 #endif
1595 };
1596 
rk3528_grfclk_get_rate(struct clk * clk)1597 static ulong rk3528_grfclk_get_rate(struct clk *clk)
1598 {
1599 	struct rk3528_clk_priv *priv;
1600 	struct udevice *cru_dev;
1601 	ulong rate = 0;
1602 	int ret;
1603 
1604 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1605 					  DM_GET_DRIVER(rockchip_rk3528_cru),
1606 					  &cru_dev);
1607 	if (ret) {
1608 		printf("%s: could not find cru device\n", __func__);
1609 		return ret;
1610 	}
1611 	priv = dev_get_priv(cru_dev);
1612 
1613 	switch (clk->id) {
1614 	case SCLK_SDMMC_SAMPLE:
1615 		rate = rk3528_sdmmc_get_clk(priv, CCLK_SRC_SDMMC0) / 2;
1616 		break;
1617 	default:
1618 		return -ENOENT;
1619 	}
1620 
1621 	return rate;
1622 };
1623 
1624 #define ROCKCHIP_MMC_DELAY_SEL		BIT(11)
1625 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1626 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	3
1627 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1628 #define PSECS_PER_SEC 1000000000000LL
1629 /*
1630  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1631  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1632  */
1633 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1634 
rk3528_mmc_get_phase(struct clk * clk)1635 int rk3528_mmc_get_phase(struct clk *clk)
1636 {
1637 	struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev);
1638 	u32 raw_value = 0, delay_num;
1639 	u16 degrees = 0;
1640 	ulong rate;
1641 
1642 	rate = rk3528_grfclk_get_rate(clk);
1643 	if (rate < 0)
1644 		return rate;
1645 
1646 	if (clk->id == SCLK_SDMMC_SAMPLE)
1647 		raw_value = readl(&priv->grf->sdmmc_con1);
1648 	else
1649 		return -ENONET;
1650 
1651 	raw_value >>= 1;
1652 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1653 
1654 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1655 		/* degrees/delaynum * 10000 */
1656 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1657 					36 * (rate / 1000000);
1658 
1659 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1660 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1661 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1662 	}
1663 
1664 	return degrees % 360;
1665 }
1666 
rk3528_mmc_set_phase(struct clk * clk,u32 degrees)1667 int rk3528_mmc_set_phase(struct clk *clk, u32 degrees)
1668 {
1669 	struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev);
1670 	u8 nineties, remainder, delay_num;
1671 	u32 raw_value, delay;
1672 	ulong rate;
1673 
1674 	rate = rk3528_grfclk_get_rate(clk);
1675 	if (rate < 0)
1676 		return rate;
1677 
1678 	nineties = degrees / 90;
1679 	remainder = (degrees % 90);
1680 
1681 	/*
1682 	 * Convert to delay; do a little extra work to make sure we
1683 	 * don't overflow 32-bit / 64-bit numbers.
1684 	 */
1685 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1686 	delay *= remainder;
1687 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1688 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1689 
1690 	delay_num = (u8)min_t(u32, delay, 255);
1691 
1692 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1693 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1694 	raw_value |= nineties;
1695 
1696 	raw_value <<= 1;
1697 	if (clk->id == SCLK_SDMMC_SAMPLE)
1698 		writel(raw_value | 0xffff0000, &priv->grf->sdmmc_con1);
1699 	else
1700 		return -ENONET;
1701 
1702 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1703 	      degrees, delay_num, raw_value, rk3528_mmc_get_phase(clk));
1704 
1705 	return 0;
1706 }
1707 
rk3528_grfclk_get_phase(struct clk * clk)1708 static int rk3528_grfclk_get_phase(struct clk *clk)
1709 {
1710 	int ret;
1711 
1712 	debug("%s %ld\n", __func__, clk->id);
1713 	switch (clk->id) {
1714 	case SCLK_SDMMC_SAMPLE:
1715 		ret = rk3528_mmc_get_phase(clk);
1716 		break;
1717 	default:
1718 		return -ENOENT;
1719 	}
1720 
1721 	return ret;
1722 }
1723 
rk3528_grfclk_set_phase(struct clk * clk,int degrees)1724 static int rk3528_grfclk_set_phase(struct clk *clk, int degrees)
1725 {
1726 	int ret;
1727 
1728 	debug("%s %ld\n", __func__, clk->id);
1729 	switch (clk->id) {
1730 	case SCLK_SDMMC_SAMPLE:
1731 		ret = rk3528_mmc_set_phase(clk, degrees);
1732 		break;
1733 	default:
1734 		return -ENOENT;
1735 	}
1736 
1737 	return ret;
1738 }
1739 
1740 static struct clk_ops rk3528_grfclk_ops = {
1741 	.get_rate = rk3528_grfclk_get_rate,
1742 	.get_phase = rk3528_grfclk_get_phase,
1743 	.set_phase = rk3528_grfclk_set_phase,
1744 };
1745 
1746 #ifndef CONFIG_SPL_BUILD
1747 /**
1748  * soc_clk_dump() - Print clock frequencies
1749  * Returns zero on success
1750  *
1751  * Implementation for the clk dump command.
1752  */
soc_clk_dump(void)1753 int soc_clk_dump(void)
1754 {
1755 	const struct rk3528_clk_info *clk_dump;
1756 	struct rk3528_clk_priv *priv;
1757 	struct udevice *cru_dev;
1758 	struct clk clk;
1759 	ulong clk_count = ARRAY_SIZE(clks_dump);
1760 	ulong rate;
1761 	int i, ret;
1762 
1763 	ret = uclass_get_device_by_driver(UCLASS_CLK,
1764 					  DM_GET_DRIVER(rockchip_rk3528_cru),
1765 					  &cru_dev);
1766 	if (ret) {
1767 		printf("%s failed to get cru device\n", __func__);
1768 		return ret;
1769 	}
1770 
1771 	priv = dev_get_priv(cru_dev);
1772 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
1773 	       priv->sync_kernel ? "sync kernel" : "uboot",
1774 	       priv->armclk_enter_hz / 1000,
1775 	       priv->armclk_init_hz / 1000,
1776 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
1777 	       priv->set_armclk_rate ? " KHz" : "N/A");
1778 	for (i = 0; i < clk_count; i++) {
1779 		clk_dump = &clks_dump[i];
1780 		if (clk_dump->name) {
1781 			clk.id = clk_dump->id;
1782 			ret = clk_request(cru_dev, &clk);
1783 			if (ret < 0)
1784 				return ret;
1785 
1786 			rate = clk_get_rate(&clk);
1787 			clk_free(&clk);
1788 			if (i == 0) {
1789 				if (rate < 0)
1790 					printf("  %s %s\n", clk_dump->name,
1791 					       "unknown");
1792 				else
1793 					printf("  %s %lu KHz\n", clk_dump->name,
1794 					       rate / 1000);
1795 			} else {
1796 				if (rate < 0)
1797 					printf("  %s %s\n", clk_dump->name,
1798 					       "unknown");
1799 				else
1800 					printf("  %s %lu KHz\n", clk_dump->name,
1801 					       rate / 1000);
1802 			}
1803 		}
1804 	}
1805 
1806 	return 0;
1807 }
1808 #endif
1809 
rk3528_grfclk_probe(struct udevice * dev)1810 static int rk3528_grfclk_probe(struct udevice *dev)
1811 {
1812 	struct rk3528_grf_clk_priv *priv = dev_get_priv(dev);
1813 
1814 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1815 	if (IS_ERR(priv->grf))
1816 		return PTR_ERR(priv->grf);
1817 
1818 	return 0;
1819 }
1820 
1821 static const struct udevice_id rk3528_grf_cru_ids[] = {
1822 	{ .compatible = "rockchip,rk3528-grf-cru" },
1823 	{ }
1824 };
1825 
1826 U_BOOT_DRIVER(rockchip_rk3528_grf_cru) = {
1827 	.name		= "rockchip_rk3528_grf_cru",
1828 	.id		= UCLASS_CLK,
1829 	.of_match	= rk3528_grf_cru_ids,
1830 	.priv_auto_alloc_size = sizeof(struct rk3528_grf_clk_priv),
1831 	.ops		= &rk3528_grfclk_ops,
1832 	.probe		= rk3528_grfclk_probe,
1833 };
1834 
rk3528_clk_init(struct rk3528_clk_priv * priv)1835 static int rk3528_clk_init(struct rk3528_clk_priv *priv)
1836 {
1837 	int ret;
1838 
1839 	priv->sync_kernel = false;
1840 
1841 #ifdef CONFIG_SPL_BUILD
1842 	/*
1843 	 * BOOTROM:
1844 	 *	CPU 1902/2(postdiv1)=546M
1845 	 *	CPLL 996/2(postdiv1)=498M
1846 	 *	GPLL 1188/2(postdiv1)=594M
1847 	 *	   |-- clk_matrix_200m_src_div=1 => rate: 300M
1848 	 *	   |-- clk_matrix_300m_src_div=2 => rate: 200M
1849 	 *
1850 	 * Avoid overclocking when change GPLL rate:
1851 	 *	Change clk_matrix_200m_src_div to 5.
1852 	 *	Change clk_matrix_300m_src_div to 3.
1853 	 */
1854 	writel(0x01200120, &priv->cru->clksel_con[1]);
1855 	writel(0x00030003, &priv->cru->clksel_con[2]);
1856 
1857 	if (!priv->armclk_enter_hz) {
1858 		priv->armclk_enter_hz =
1859 			rockchip_pll_get_rate(&rk3528_pll_clks[APLL],
1860 					      priv->cru, APLL);
1861 		priv->armclk_init_hz = priv->armclk_enter_hz;
1862 	}
1863 
1864 	if (priv->armclk_init_hz != APLL_HZ) {
1865 		ret = rk3528_armclk_set_clk(priv, APLL_HZ);
1866 		if (!ret)
1867 			priv->armclk_init_hz = APLL_HZ;
1868 	}
1869 #else
1870 	if (!priv->armclk_enter_hz) {
1871 		struct clk clk;
1872 
1873 		ret = rockchip_get_scmi_clk(&clk.dev);
1874 		if (ret) {
1875 			printf("Failed to get scmi clk dev\n");
1876 			return ret;
1877 		}
1878 
1879 		clk.id = SCMI_CLK_CPU;
1880 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
1881 		if (ret < 0) {
1882 			printf("Failed to set scmi cpu %dhz\n", CPU_PVTPLL_HZ);
1883 			return ret;
1884 		} else {
1885 			priv->armclk_enter_hz =
1886 				rockchip_pll_get_rate(&rk3528_pll_clks[APLL],
1887 						      priv->cru, APLL);
1888 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
1889 		}
1890 	}
1891 #endif
1892 	if (priv->cpll_hz != CPLL_HZ) {
1893 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru,
1894 					    CPLL, CPLL_HZ);
1895 		if (!ret)
1896 			priv->cpll_hz = CPLL_HZ;
1897 	}
1898 
1899 	if (priv->gpll_hz != GPLL_HZ) {
1900 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru,
1901 					    GPLL, GPLL_HZ);
1902 		if (!ret)
1903 			priv->gpll_hz = GPLL_HZ;
1904 	}
1905 
1906 	if (priv->ppll_hz != PPLL_HZ) {
1907 		ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru,
1908 					    PPLL, PPLL_HZ);
1909 		if (!ret)
1910 			priv->ppll_hz = PPLL_HZ;
1911 	}
1912 
1913 #ifdef CONFIG_SPL_BUILD
1914 	/* Init to override bootrom config */
1915 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_50M_SRC,   50000000);
1916 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_100M_SRC, 100000000);
1917 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_150M_SRC, 150000000);
1918 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_200M_SRC, 200000000);
1919 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_250M_SRC, 250000000);
1920 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_300M_SRC, 300000000);
1921 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_339M_SRC, 340000000);
1922 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_400M_SRC, 400000000);
1923 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_500M_SRC, 500000000);
1924 	rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_600M_SRC, 600000000);
1925 	rk3528_cgpll_matrix_set_rate(priv, ACLK_BUS_VOPGL_BIU,  500000000);
1926 
1927 	/* The default rate is 100Mhz, it's not friendly for remote IR module */
1928 	rk3528_pwm_set_clk(priv, CLK_PWM0, 24000000);
1929 	rk3528_pwm_set_clk(priv, CLK_PWM1, 24000000);
1930 #endif
1931 	return 0;
1932 }
1933 
rk3528_clk_probe(struct udevice * dev)1934 static int rk3528_clk_probe(struct udevice *dev)
1935 {
1936 	struct rk3528_clk_priv *priv = dev_get_priv(dev);
1937 	int ret;
1938 
1939 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1940 	if (IS_ERR(priv->grf))
1941 		return PTR_ERR(priv->grf);
1942 
1943 	ret = rk3528_clk_init(priv);
1944 	if (ret)
1945 		return ret;
1946 
1947 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1948 	ret = clk_set_defaults(dev);
1949 	if (ret)
1950 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1951 	else
1952 		priv->sync_kernel = true;
1953 
1954 	return 0;
1955 }
1956 
rk3528_clk_ofdata_to_platdata(struct udevice * dev)1957 static int rk3528_clk_ofdata_to_platdata(struct udevice *dev)
1958 {
1959 	struct rk3528_clk_priv *priv = dev_get_priv(dev);
1960 
1961 	priv->cru = dev_read_addr_ptr(dev);
1962 
1963 	return 0;
1964 }
1965 
rk3528_clk_bind(struct udevice * dev)1966 static int rk3528_clk_bind(struct udevice *dev)
1967 {
1968 	struct udevice *sys_child, *sf_child;
1969 	struct softreset_reg *sf_priv;
1970 	struct sysreset_reg *priv;
1971 	int ret;
1972 
1973 	/* The reset driver does not have a device node, so bind it here */
1974 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1975 				 &sys_child);
1976 	if (ret) {
1977 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1978 	} else {
1979 		priv = malloc(sizeof(struct sysreset_reg));
1980 		priv->glb_srst_fst_value = offsetof(struct rk3528_cru,
1981 						    glb_srst_fst);
1982 		priv->glb_srst_snd_value = offsetof(struct rk3528_cru,
1983 						    glb_srst_snd);
1984 		sys_child->priv = priv;
1985 	}
1986 
1987 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1988 					 dev_ofnode(dev), &sf_child);
1989 	if (ret) {
1990 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1991 	} else {
1992 		sf_priv = malloc(sizeof(struct softreset_reg));
1993 		sf_priv->sf_reset_offset = offsetof(struct rk3528_cru,
1994 						    softrst_con[0]);
1995 		sf_priv->sf_reset_num = 47;
1996 		sf_child->priv = sf_priv;
1997 	}
1998 
1999 	return 0;
2000 }
2001 
2002 static const struct udevice_id rk3528_clk_ids[] = {
2003 	{ .compatible = "rockchip,rk3528-cru" },
2004 	{ }
2005 };
2006 
2007 U_BOOT_DRIVER(rockchip_rk3528_cru) = {
2008 	.name		= "rockchip_rk3528_cru",
2009 	.id		= UCLASS_CLK,
2010 	.of_match	= rk3528_clk_ids,
2011 	.priv_auto_alloc_size = sizeof(struct rk3528_clk_priv),
2012 	.ofdata_to_platdata = rk3528_clk_ofdata_to_platdata,
2013 	.ops		= &rk3528_clk_ops,
2014 	.bind		= rk3528_clk_bind,
2015 	.probe		= rk3528_clk_probe,
2016 };
2017 
2018 /* spl scmi clk */
2019 #ifdef CONFIG_SPL_BUILD
2020 
rk3528_crypto_get_rate(struct rk3528_clk_priv * priv,struct clk * clk)2021 static ulong rk3528_crypto_get_rate(struct rk3528_clk_priv *priv, struct clk *clk)
2022 {
2023 	struct rk3528_cru *cru = priv->cru;
2024 	u32 id, sel, con, mask, shift;
2025 	ulong rate;
2026 
2027 	switch (clk->id) {
2028 	case SCMI_CORE_CRYPTO:
2029 		id = 43;
2030 		mask = CLK_CORE_CRYPTO_SEL_MASK;
2031 		shift = CLK_CORE_CRYPTO_SEL_SHIFT;
2032 		break;
2033 
2034 	case SCMI_PKA_CRYPTO:
2035 		id = 44;
2036 		mask = CLK_PKA_CRYPTO_SEL_MASK;
2037 		shift = CLK_PKA_CRYPTO_SEL_SHIFT;
2038 		break;
2039 
2040 	default:
2041 		return -ENOENT;
2042 	}
2043 
2044 	con = readl(&cru->clksel_con[id]);
2045 	sel = (con & mask) >> shift;
2046 	if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC)
2047 		rate = 300 * MHz;
2048 	else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC)
2049 		rate = 200 * MHz;
2050 	else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC)
2051 		rate = 100 * MHz;
2052 	else
2053 		rate = OSC_HZ;
2054 
2055 	return rate;
2056 }
2057 
rk3528_crypto_set_rate(struct rk3528_clk_priv * priv,struct clk * clk,ulong rate)2058 static ulong rk3528_crypto_set_rate(struct rk3528_clk_priv *priv,
2059 				    struct clk *clk, ulong rate)
2060 {
2061 	struct rk3528_cru *cru = priv->cru;
2062 	u32 id, sel, mask, shift;
2063 
2064 	if (rate == 300 * MHz)
2065 		sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC;
2066 	else if (rate == 200 * MHz)
2067 		sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC;
2068 	else if (rate == 100 * MHz)
2069 		sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC;
2070 	else
2071 		sel = CLK_CORE_CRYPTO_SEL_XIN_OSC0_FUNC;
2072 
2073 	switch (clk->id) {
2074 	case SCMI_CORE_CRYPTO:
2075 		id = 43;
2076 		mask = CLK_CORE_CRYPTO_SEL_MASK;
2077 		shift = CLK_CORE_CRYPTO_SEL_SHIFT;
2078 		break;
2079 
2080 	case SCMI_PKA_CRYPTO:
2081 		id = 44;
2082 		mask = CLK_PKA_CRYPTO_SEL_MASK;
2083 		shift = CLK_PKA_CRYPTO_SEL_SHIFT;
2084 		break;
2085 
2086 	default:
2087 		return -ENOENT;
2088 	}
2089 
2090 	rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift);
2091 
2092 	return rk3528_crypto_get_rate(priv, clk);
2093 }
2094 
rk3528_clk_scmi_get_rate(struct clk * clk)2095 static ulong rk3528_clk_scmi_get_rate(struct clk *clk)
2096 {
2097 	struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
2098 
2099 	switch (clk->id) {
2100 	case SCMI_CORE_CRYPTO:
2101 	case SCMI_PKA_CRYPTO:
2102 		return rk3528_crypto_get_rate(priv, clk);
2103 	default:
2104 		return -ENOENT;
2105 	}
2106 };
2107 
rk3528_clk_scmi_set_rate(struct clk * clk,ulong rate)2108 static ulong rk3528_clk_scmi_set_rate(struct clk *clk, ulong rate)
2109 {
2110 	struct rk3528_clk_priv *priv = dev_get_priv(clk->dev);
2111 
2112 	switch (clk->id) {
2113 	case SCMI_CORE_CRYPTO:
2114 	case SCMI_PKA_CRYPTO:
2115 		return rk3528_crypto_set_rate(priv, clk, rate);
2116 	default:
2117 		return -ENOENT;
2118 	}
2119 
2120 	return 0;
2121 };
2122 
rk3528_scmi_clk_ofdata_to_platdata(struct udevice * dev)2123 static int rk3528_scmi_clk_ofdata_to_platdata(struct udevice *dev)
2124 {
2125 	struct rk3528_clk_priv *priv = dev_get_priv(dev);
2126 
2127 	priv->cru = (struct rk3528_cru *)0xff4a0000;
2128 
2129 	return 0;
2130 }
2131 
2132 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2133 static const struct clk_ops scmi_clk_ops = {
2134 	.get_rate = rk3528_clk_scmi_get_rate,
2135 	.set_rate = rk3528_clk_scmi_set_rate,
2136 };
2137 
2138 U_BOOT_DRIVER(scmi_clock) = {
2139 	.name = "scmi_clk",
2140 	.id = UCLASS_CLK,
2141 	.ops = &scmi_clk_ops,
2142 	.priv_auto_alloc_size = sizeof(struct rk3528_clk_priv),
2143 	.ofdata_to_platdata = rk3528_scmi_clk_ofdata_to_platdata,
2144 };
2145 #endif
2146