xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3576.c (revision 5c6e0812b45b3700adf1840c517c4e837c0dbe18)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Elaine Zhang <zhangqing@rock-chips.com>
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_rk3576.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rockchip,rk3576-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
23 
24 #if 1
25 static struct rockchip_pll_rate_table rk3576_24m_pll_rates[] = {
26 	/* _mhz, _p, _m, _s, _k */
27 	RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
28 	RK3588_PLL_RATE(1200000000, 1, 100, 1, 0),
29 	RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
30 	RK3588_PLL_RATE(1150000000, 3, 575, 2, 0),
31 	RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
32 	RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
33 	RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
34 	RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
35 	RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
36 	RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
37 	RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
38 	RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
39 	RK3588_PLL_RATE(742500000, 4, 495, 2, 0),
40 	RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
41 	RK3588_PLL_RATE(610400000, 3, 305, 2, 13107),
42 	RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
43 	RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
44 	RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
45 	RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
46 	{ /* sentinel */ },
47 };
48 #else
49 static struct rockchip_pll_rate_table rk3576_26m_pll_rates[] = {
50 	/* _mhz, _p, _m, _s, _k */
51 	RK3588_PLL_RATE(1188000000, 2, 183, 1, 50412),
52 	RK3588_PLL_RATE(1100000000, 2, 338, 2, 30247),
53 	RK3588_PLL_RATE(1014000000, 1, 156, 2, 0),
54 	RK3588_PLL_RATE(1000000000, 2, 308, 2, 45371),
55 	RK3588_PLL_RATE(858000000, 1, 132, 2, 0),
56 	RK3588_PLL_RATE(806000000, 1, 124, 2, 0),
57 	RK3588_PLL_RATE(786432000, 2, 242, 2, 64165),
58 	RK3588_PLL_RATE(594000000, 2, 183, 2, 50412),
59 	RK3588_PLL_RATE(297000000, 2, 183, 3, 50412),
60 	RK3588_PLL_RATE(148500000, 2, 183, 4, 50412),
61 	{ /* sentinel */ },
62 };
63 #endif
64 
65 static struct rockchip_pll_clock rk3576_pll_clks[] = {
66 	[BPLL] = PLL(pll_rk3588, PLL_BPLL, RK3576_PLL_CON(0),
67 		      RK3576_BPLL_MODE_CON0, 0, 15, 0,
68 		      rk3576_24m_pll_rates),
69 	[LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3576_LPLL_CON(16),
70 		     RK3576_LPLL_MODE_CON0, 0, 15, 0, rk3576_24m_pll_rates),
71 	[VPLL] = PLL(pll_rk3588, PLL_VPLL, RK3576_PLL_CON(88),
72 		      RK3576_LPLL_MODE_CON0, 4, 15, 0, rk3576_24m_pll_rates),
73 	[AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3576_PLL_CON(96),
74 		      RK3576_MODE_CON0, 6, 15, 0, rk3576_24m_pll_rates),
75 	[CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3576_PLL_CON(104),
76 		     RK3576_MODE_CON0, 8, 15, 0, rk3576_24m_pll_rates),
77 	[GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3576_PLL_CON(112),
78 		     RK3576_MODE_CON0, 2, 15, 0, rk3576_24m_pll_rates),
79 	[PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3576_PMU_PLL_CON(128),
80 		     RK3576_MODE_CON0, 10, 15, 0, rk3576_24m_pll_rates),
81 };
82 
83 #ifndef CONFIG_SPL_BUILD
84 #define RK3576_CLK_DUMP(_id, _name, _iscru)	\
85 {						\
86 	.id = _id,				\
87 	.name = _name,				\
88 	.is_cru = _iscru,			\
89 }
90 
91 static const struct rk3576_clk_info clks_dump[] = {
92 	RK3576_CLK_DUMP(PLL_BPLL, "bpll", true),
93 	RK3576_CLK_DUMP(PLL_LPLL, "lpll", true),
94 	RK3576_CLK_DUMP(PLL_VPLL, "vpll", true),
95 	RK3576_CLK_DUMP(PLL_AUPLL, "aupll", true),
96 	RK3576_CLK_DUMP(PLL_CPLL, "cpll", true),
97 	RK3576_CLK_DUMP(PLL_GPLL, "gpll", true),
98 	RK3576_CLK_DUMP(PLL_PPLL, "ppll", true),
99 	RK3576_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true),
100 	RK3576_CLK_DUMP(PCLK_BUS_ROOT, "pclk_bus_root", true),
101 	RK3576_CLK_DUMP(HCLK_BUS_ROOT, "hclk_bus_root", true),
102 	RK3576_CLK_DUMP(ACLK_TOP, "aclk_top", true),
103 	RK3576_CLK_DUMP(ACLK_TOP_MID, "aclk_top_mid", true),
104 	RK3576_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top", true),
105 	RK3576_CLK_DUMP(HCLK_TOP, "hclk_top", true),
106 };
107 #endif
108 
109 #ifdef CONFIG_SPL_BUILD
110 #ifndef BITS_WITH_WMASK
111 #define BITS_WITH_WMASK(bits, msk, shift) \
112 	((bits) << (shift)) | ((msk) << ((shift) + 16))
113 #endif
114 #endif
115 
116 #ifndef CONFIG_SPL_BUILD
117 /*
118  *
119  * rational_best_approximation(31415, 10000,
120  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
121  *
122  * you may look at given_numerator as a fixed point number,
123  * with the fractional part size described in given_denominator.
124  *
125  * for theoretical background, see:
126  * http://en.wikipedia.org/wiki/Continued_fraction
127  */
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)128 static void rational_best_approximation(unsigned long given_numerator,
129 					unsigned long given_denominator,
130 					unsigned long max_numerator,
131 					unsigned long max_denominator,
132 					unsigned long *best_numerator,
133 					unsigned long *best_denominator)
134 {
135 	unsigned long n, d, n0, d0, n1, d1;
136 
137 	n = given_numerator;
138 	d = given_denominator;
139 	n0 = 0;
140 	d1 = 0;
141 	n1 = 1;
142 	d0 = 1;
143 	for (;;) {
144 		unsigned long t, a;
145 
146 		if (n1 > max_numerator || d1 > max_denominator) {
147 			n1 = n0;
148 			d1 = d0;
149 			break;
150 		}
151 		if (d == 0)
152 			break;
153 		t = d;
154 		a = n / d;
155 		d = n % d;
156 		n = t;
157 		t = n0 + a * n1;
158 		n0 = n1;
159 		n1 = t;
160 		t = d0 + a * d1;
161 		d0 = d1;
162 		d1 = t;
163 	}
164 	*best_numerator = n1;
165 	*best_denominator = d1;
166 }
167 #endif
168 
rk3576_bus_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)169 static ulong rk3576_bus_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
170 {
171 	struct rk3576_cru *cru = priv->cru;
172 	u32 con, sel, div, rate;
173 
174 	switch (clk_id) {
175 	case ACLK_BUS_ROOT:
176 		con = readl(&cru->clksel_con[55]);
177 		sel = (con & ACLK_BUS_ROOT_SEL_MASK) >>
178 		      ACLK_BUS_ROOT_SEL_SHIFT;
179 		div = (con & ACLK_BUS_ROOT_DIV_MASK) >>
180 		      ACLK_BUS_ROOT_DIV_SHIFT;
181 		if (sel == ACLK_BUS_ROOT_SEL_CPLL)
182 			rate = DIV_TO_RATE(priv->cpll_hz , div);
183 		else
184 			rate = DIV_TO_RATE(priv->gpll_hz, div);
185 		break;
186 	case HCLK_BUS_ROOT:
187 		con = readl(&cru->clksel_con[55]);
188 		sel = (con & HCLK_BUS_ROOT_SEL_MASK) >>
189 		      HCLK_BUS_ROOT_SEL_SHIFT;
190 		if (sel == HCLK_BUS_ROOT_SEL_200M)
191 			rate = 198 * MHz;
192 		else if (sel == HCLK_BUS_ROOT_SEL_100M)
193 			rate = 100 * MHz;
194 		else if (sel == HCLK_BUS_ROOT_SEL_50M)
195 			rate = 50 * MHz;
196 		else
197 			rate = OSC_HZ;
198 		break;
199 	case PCLK_BUS_ROOT:
200 		con = readl(&cru->clksel_con[55]);
201 		sel = (con & PCLK_BUS_ROOT_SEL_MASK) >>
202 		      PCLK_BUS_ROOT_SEL_SHIFT;
203 		if (sel == PCLK_BUS_ROOT_SEL_100M)
204 			rate = 100 * MHz;
205 		else if (sel == PCLK_BUS_ROOT_SEL_50M)
206 			rate = 50 * MHz;
207 		else
208 			rate = OSC_HZ;
209 		break;
210 	default:
211 		return -ENOENT;
212 	}
213 
214 	return rate;
215 }
216 
rk3576_bus_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)217 static ulong rk3576_bus_set_clk(struct rk3576_clk_priv *priv,
218 				   ulong clk_id, ulong rate)
219 {
220 	struct rk3576_cru *cru = priv->cru;
221 	int src_clk, src_clk_div;
222 
223 	switch (clk_id) {
224 	case ACLK_BUS_ROOT:
225 		if (!(priv->cpll_hz % rate)) {
226 			src_clk = ACLK_BUS_ROOT_SEL_CPLL;
227 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
228 		} else {
229 			src_clk = ACLK_BUS_ROOT_SEL_GPLL;
230 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
231 		}
232 		rk_clrsetreg(&cru->clksel_con[55],
233 			     ACLK_BUS_ROOT_SEL_MASK,
234 			     src_clk << ACLK_BUS_ROOT_SEL_SHIFT);
235 		assert(src_clk_div - 1 <= 31);
236 		rk_clrsetreg(&cru->clksel_con[55],
237 			     ACLK_BUS_ROOT_DIV_MASK |
238 			     ACLK_BUS_ROOT_SEL_MASK,
239 			     (src_clk <<
240 			      ACLK_BUS_ROOT_SEL_SHIFT) |
241 			     (src_clk_div - 1) << ACLK_BUS_ROOT_DIV_SHIFT);
242 		break;
243 	case HCLK_BUS_ROOT:
244 		if (rate >= 198 * MHz)
245 			src_clk = HCLK_BUS_ROOT_SEL_200M;
246 		else if (rate >= 99 * MHz)
247 			src_clk = HCLK_BUS_ROOT_SEL_100M;
248 		else if (rate >= 50 * MHz)
249 			src_clk = HCLK_BUS_ROOT_SEL_50M;
250 		else
251 			src_clk = HCLK_BUS_ROOT_SEL_OSC;
252 		rk_clrsetreg(&cru->clksel_con[55],
253 			     HCLK_BUS_ROOT_SEL_MASK,
254 			     src_clk << HCLK_BUS_ROOT_SEL_SHIFT);
255 		break;
256 	case PCLK_BUS_ROOT:
257 		if (rate >= 99 * MHz)
258 			src_clk = PCLK_BUS_ROOT_SEL_100M;
259 		else if (rate >= 50 * MHz)
260 			src_clk = PCLK_BUS_ROOT_SEL_50M;
261 		else
262 			src_clk = PCLK_BUS_ROOT_SEL_OSC;
263 		rk_clrsetreg(&cru->clksel_con[55],
264 			     PCLK_BUS_ROOT_SEL_MASK,
265 			     src_clk << PCLK_BUS_ROOT_SEL_SHIFT);
266 		break;
267 	default:
268 		printf("do not support this center freq\n");
269 		return -EINVAL;
270 	}
271 
272 	return rk3576_bus_get_clk(priv, clk_id);
273 }
274 
rk3576_top_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)275 static ulong rk3576_top_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
276 {
277 	struct rk3576_cru *cru = priv->cru;
278 	u32 con, sel, div, rate, prate;
279 
280 	switch (clk_id) {
281 	case ACLK_TOP:
282 		con = readl(&cru->clksel_con[9]);
283 		div = (con & ACLK_TOP_DIV_MASK) >>
284 		      ACLK_TOP_DIV_SHIFT;
285 		sel = (con & ACLK_TOP_SEL_MASK) >>
286 		      ACLK_TOP_SEL_SHIFT;
287 		if (sel == ACLK_TOP_SEL_CPLL)
288 			prate = priv->cpll_hz;
289 		else if (sel == ACLK_TOP_SEL_AUPLL)
290 			prate = priv->aupll_hz;
291 		else
292 			prate = priv->gpll_hz;
293 		return DIV_TO_RATE(prate, div);
294 	case ACLK_TOP_MID:
295 		con = readl(&cru->clksel_con[10]);
296 		div = (con & ACLK_TOP_MID_DIV_MASK) >>
297 		      ACLK_TOP_MID_DIV_SHIFT;
298 		sel = (con & ACLK_TOP_MID_SEL_MASK) >>
299 		      ACLK_TOP_MID_SEL_SHIFT;
300 		if (sel == ACLK_TOP_MID_SEL_CPLL)
301 			prate = priv->cpll_hz;
302 		else
303 			prate = priv->gpll_hz;
304 		return DIV_TO_RATE(prate, div);
305 	case PCLK_TOP_ROOT:
306 		con = readl(&cru->clksel_con[8]);
307 		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
308 		if (sel == PCLK_TOP_SEL_100M)
309 			rate = 100 * MHz;
310 		else if (sel == PCLK_TOP_SEL_50M)
311 			rate = 50 * MHz;
312 		else
313 			rate = OSC_HZ;
314 		break;
315 	case HCLK_TOP:
316 		con = readl(&cru->clksel_con[19]);
317 		sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
318 		if (sel == HCLK_TOP_SEL_200M)
319 			rate = 200 * MHz;
320 		else if (sel == HCLK_TOP_SEL_100M)
321 			rate = 100 * MHz;
322 		else if (sel == HCLK_TOP_SEL_50M)
323 			rate = 50 * MHz;
324 		else
325 			rate = OSC_HZ;
326 		break;
327 	default:
328 		return -ENOENT;
329 	}
330 
331 	return rate;
332 }
333 
rk3576_top_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)334 static ulong rk3576_top_set_clk(struct rk3576_clk_priv *priv,
335 				ulong clk_id, ulong rate)
336 {
337 	struct rk3576_cru *cru = priv->cru;
338 	int src_clk, src_clk_div;
339 
340 	switch (clk_id) {
341 	case ACLK_TOP:
342 		if (!(priv->cpll_hz % rate)) {
343 			src_clk = ACLK_TOP_SEL_CPLL;
344 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
345 		} else {
346 			src_clk = ACLK_TOP_SEL_GPLL;
347 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
348 		}
349 		assert(src_clk_div - 1 <= 31);
350 		rk_clrsetreg(&cru->clksel_con[9],
351 			     ACLK_TOP_DIV_MASK |
352 			     ACLK_TOP_SEL_MASK,
353 			     (src_clk <<
354 			      ACLK_TOP_SEL_SHIFT) |
355 			     (src_clk_div - 1) << ACLK_TOP_SEL_SHIFT);
356 		break;
357 	case ACLK_TOP_MID:
358 		if (!(priv->cpll_hz % rate)) {
359 			src_clk = ACLK_TOP_MID_SEL_CPLL;
360 			src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
361 		} else {
362 			src_clk = ACLK_TOP_MID_SEL_GPLL;
363 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
364 		}
365 		rk_clrsetreg(&cru->clksel_con[10],
366 			     ACLK_TOP_MID_DIV_MASK |
367 			     ACLK_TOP_MID_SEL_MASK,
368 			     (ACLK_TOP_MID_SEL_GPLL <<
369 			      ACLK_TOP_MID_SEL_SHIFT) |
370 			     (src_clk_div - 1) << ACLK_TOP_MID_DIV_SHIFT);
371 		break;
372 	case PCLK_TOP_ROOT:
373 		if (rate >= 99 * MHz)
374 			src_clk = PCLK_TOP_SEL_100M;
375 		else if (rate >= 50 * MHz)
376 			src_clk = PCLK_TOP_SEL_50M;
377 		else
378 			src_clk = PCLK_TOP_SEL_OSC;
379 		rk_clrsetreg(&cru->clksel_con[8],
380 			     PCLK_TOP_SEL_MASK,
381 			     src_clk << PCLK_TOP_SEL_SHIFT);
382 		break;
383 	case HCLK_TOP:
384 		if (rate >= 198 * MHz)
385 			src_clk = HCLK_TOP_SEL_200M;
386 		else if (rate >= 99 * MHz)
387 			src_clk = HCLK_TOP_SEL_100M;
388 		else if (rate >= 50 * MHz)
389 			src_clk = HCLK_TOP_SEL_50M;
390 		else
391 			src_clk = HCLK_TOP_SEL_OSC;
392 		rk_clrsetreg(&cru->clksel_con[19],
393 			     HCLK_TOP_SEL_MASK,
394 			     src_clk << HCLK_TOP_SEL_SHIFT);
395 		break;
396 	default:
397 		printf("do not support this top freq\n");
398 		return -EINVAL;
399 	}
400 
401 	return rk3576_top_get_clk(priv, clk_id);
402 }
403 
rk3576_i2c_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)404 static ulong rk3576_i2c_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
405 {
406 	struct rk3576_cru *cru = priv->cru;
407 	u32 sel, con;
408 	ulong rate;
409 
410 	switch (clk_id) {
411 	case CLK_I2C0:
412 		con = readl(&cru->pmuclksel_con[6]);
413 		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
414 		break;
415 	case CLK_I2C1:
416 		con = readl(&cru->clksel_con[57]);
417 		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
418 		break;
419 	case CLK_I2C2:
420 		con = readl(&cru->clksel_con[57]);
421 		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
422 		break;
423 	case CLK_I2C3:
424 		con = readl(&cru->clksel_con[57]);
425 		sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
426 		break;
427 	case CLK_I2C4:
428 		con = readl(&cru->clksel_con[57]);
429 		sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
430 		break;
431 	case CLK_I2C5:
432 		con = readl(&cru->clksel_con[57]);
433 		sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
434 		break;
435 	case CLK_I2C6:
436 		con = readl(&cru->clksel_con[57]);
437 		sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
438 		break;
439 	case CLK_I2C7:
440 		con = readl(&cru->clksel_con[57]);
441 		sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
442 		break;
443 	case CLK_I2C8:
444 		con = readl(&cru->clksel_con[57]);
445 		sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
446 		break;
447 	case CLK_I2C9:
448 		con = readl(&cru->clksel_con[58]);
449 		sel = (con & CLK_I2C9_SEL_MASK) >> CLK_I2C9_SEL_SHIFT;
450 		break;
451 
452 	default:
453 		return -ENOENT;
454 	}
455 	if (sel == CLK_I2C_SEL_200M)
456 		rate = 200 * MHz;
457 	else if (sel == CLK_I2C_SEL_100M)
458 		rate = 100 * MHz;
459 	else if (sel == CLK_I2C_SEL_50M)
460 		rate = 50 * MHz;
461 	else
462 		rate = OSC_HZ;
463 
464 	return rate;
465 }
466 
rk3576_i2c_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)467 static ulong rk3576_i2c_set_clk(struct rk3576_clk_priv *priv, ulong clk_id,
468 				ulong rate)
469 {
470 	struct rk3576_cru *cru = priv->cru;
471 	int src_clk;
472 
473 	if (rate >= 198 * MHz)
474 		src_clk = CLK_I2C_SEL_200M;
475 	else if (rate >= 99 * MHz)
476 		src_clk = CLK_I2C_SEL_100M;
477 	if (rate >= 50 * MHz)
478 		src_clk = CLK_I2C_SEL_50M;
479 	else
480 		src_clk = CLK_I2C_SEL_OSC;
481 
482 	switch (clk_id) {
483 	case CLK_I2C0:
484 		rk_clrsetreg(&cru->pmuclksel_con[6], CLK_I2C0_SEL_MASK,
485 			     src_clk << CLK_I2C0_SEL_SHIFT);
486 		break;
487 	case CLK_I2C1:
488 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C1_SEL_MASK,
489 			     src_clk << CLK_I2C1_SEL_SHIFT);
490 		break;
491 	case CLK_I2C2:
492 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C2_SEL_MASK,
493 			     src_clk << CLK_I2C2_SEL_SHIFT);
494 		break;
495 	case CLK_I2C3:
496 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C3_SEL_MASK,
497 			     src_clk << CLK_I2C3_SEL_SHIFT);
498 		break;
499 	case CLK_I2C4:
500 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C4_SEL_MASK,
501 			     src_clk << CLK_I2C4_SEL_SHIFT);
502 		break;
503 	case CLK_I2C5:
504 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C5_SEL_MASK,
505 			     src_clk << CLK_I2C5_SEL_SHIFT);
506 		break;
507 	case CLK_I2C6:
508 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C6_SEL_MASK,
509 			     src_clk << CLK_I2C6_SEL_SHIFT);
510 		break;
511 	case CLK_I2C7:
512 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C7_SEL_MASK,
513 			     src_clk << CLK_I2C7_SEL_SHIFT);
514 		break;
515 	case CLK_I2C8:
516 		rk_clrsetreg(&cru->clksel_con[57], CLK_I2C8_SEL_MASK,
517 			     src_clk << CLK_I2C8_SEL_SHIFT);
518 	case CLK_I2C9:
519 		rk_clrsetreg(&cru->clksel_con[58], CLK_I2C9_SEL_MASK,
520 			     src_clk << CLK_I2C9_SEL_SHIFT);
521 		break;
522 	default:
523 		return -ENOENT;
524 	}
525 
526 	return rk3576_i2c_get_clk(priv, clk_id);
527 }
528 
rk3576_spi_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)529 static ulong rk3576_spi_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
530 {
531 	struct rk3576_cru *cru = priv->cru;
532 	u32 sel, con;
533 
534 	switch (clk_id) {
535 	case CLK_SPI0:
536 		con = readl(&cru->clksel_con[70]);
537 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
538 		break;
539 	case CLK_SPI1:
540 		con = readl(&cru->clksel_con[71]);
541 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
542 		break;
543 	case CLK_SPI2:
544 		con = readl(&cru->clksel_con[71]);
545 		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
546 		break;
547 	case CLK_SPI3:
548 		con = readl(&cru->clksel_con[71]);
549 		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
550 		break;
551 	case CLK_SPI4:
552 		con = readl(&cru->clksel_con[71]);
553 		sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
554 		break;
555 	default:
556 		return -ENOENT;
557 	}
558 
559 	switch (sel) {
560 	case CLK_SPI_SEL_200M:
561 		return 200 * MHz;
562 	case CLK_SPI_SEL_100M:
563 		return 100 * MHz;
564 	case CLK_SPI_SEL_50M:
565 		return 50 * MHz;
566 	case CLK_SPI_SEL_OSC:
567 		return OSC_HZ;
568 	default:
569 		return -ENOENT;
570 	}
571 }
572 
rk3576_spi_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)573 static ulong rk3576_spi_set_clk(struct rk3576_clk_priv *priv,
574 				ulong clk_id, ulong rate)
575 {
576 	struct rk3576_cru *cru = priv->cru;
577 	int src_clk;
578 
579 	if (rate >= 198 * MHz)
580 		src_clk = CLK_SPI_SEL_200M;
581 	else if (rate >= 99 * MHz)
582 		src_clk = CLK_SPI_SEL_100M;
583 	else if (rate >= 50 * MHz)
584 		src_clk = CLK_SPI_SEL_50M;
585 	else
586 		src_clk = CLK_SPI_SEL_OSC;
587 
588 	switch (clk_id) {
589 	case CLK_SPI0:
590 		rk_clrsetreg(&cru->clksel_con[70],
591 			     CLK_SPI0_SEL_MASK,
592 			     src_clk << CLK_SPI0_SEL_SHIFT);
593 		break;
594 	case CLK_SPI1:
595 		rk_clrsetreg(&cru->clksel_con[71],
596 			     CLK_SPI1_SEL_MASK,
597 			     src_clk << CLK_SPI1_SEL_SHIFT);
598 		break;
599 	case CLK_SPI2:
600 		rk_clrsetreg(&cru->clksel_con[71],
601 			     CLK_SPI2_SEL_MASK,
602 			     src_clk << CLK_SPI2_SEL_SHIFT);
603 		break;
604 	case CLK_SPI3:
605 		rk_clrsetreg(&cru->clksel_con[71],
606 			     CLK_SPI3_SEL_MASK,
607 			     src_clk << CLK_SPI3_SEL_SHIFT);
608 		break;
609 	case CLK_SPI4:
610 		rk_clrsetreg(&cru->clksel_con[71],
611 			     CLK_SPI4_SEL_MASK,
612 			     src_clk << CLK_SPI4_SEL_SHIFT);
613 		break;
614 	default:
615 		return -ENOENT;
616 	}
617 
618 	return rk3576_spi_get_clk(priv, clk_id);
619 }
620 
rk3576_pwm_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)621 static ulong rk3576_pwm_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
622 {
623 	struct rk3576_cru *cru = priv->cru;
624 	u32 sel, con;
625 
626 	switch (clk_id) {
627 	case CLK_PWM1:
628 		con = readl(&cru->clksel_con[71]);
629 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
630 		break;
631 	case CLK_PWM2:
632 		con = readl(&cru->clksel_con[74]);
633 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
634 		break;
635 	case CLK_PMU1PWM:
636 		con = readl(&cru->pmuclksel_con[5]);
637 		sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
638 		break;
639 	default:
640 		return -ENOENT;
641 	}
642 
643 	switch (sel) {
644 	case CLK_PWM_SEL_100M:
645 		return 100 * MHz;
646 	case CLK_PWM_SEL_50M:
647 		return 50 * MHz;
648 	case CLK_PWM_SEL_OSC:
649 		return OSC_HZ;
650 	default:
651 		return -ENOENT;
652 	}
653 }
654 
rk3576_pwm_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)655 static ulong rk3576_pwm_set_clk(struct rk3576_clk_priv *priv,
656 				ulong clk_id, ulong rate)
657 {
658 	struct rk3576_cru *cru = priv->cru;
659 	int src_clk;
660 
661 	if (rate >= 99 * MHz)
662 		src_clk = CLK_PWM_SEL_100M;
663 	else if (rate >= 50 * MHz)
664 		src_clk = CLK_PWM_SEL_50M;
665 	else
666 		src_clk = CLK_PWM_SEL_OSC;
667 
668 	switch (clk_id) {
669 	case CLK_PWM1:
670 		rk_clrsetreg(&cru->clksel_con[71],
671 			     CLK_PWM1_SEL_MASK,
672 			     src_clk << CLK_PWM1_SEL_SHIFT);
673 		break;
674 	case CLK_PWM2:
675 		rk_clrsetreg(&cru->clksel_con[74],
676 			     CLK_PWM2_SEL_MASK,
677 			     src_clk << CLK_PWM2_SEL_SHIFT);
678 		break;
679 	case CLK_PMU1PWM:
680 		rk_clrsetreg(&cru->pmuclksel_con[5],
681 			     CLK_PMU1PWM_SEL_MASK,
682 			     src_clk << CLK_PMU1PWM_SEL_SHIFT);
683 		break;
684 	default:
685 		return -ENOENT;
686 	}
687 
688 	return rk3576_pwm_get_clk(priv, clk_id);
689 }
690 
rk3576_adc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)691 static ulong rk3576_adc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
692 {
693 	struct rk3576_cru *cru = priv->cru;
694 	u32 div, sel, con, prate;
695 
696 	switch (clk_id) {
697 	case CLK_SARADC:
698 		con = readl(&cru->clksel_con[58]);
699 		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
700 		sel = (con & CLK_SARADC_SEL_MASK) >>
701 		      CLK_SARADC_SEL_SHIFT;
702 		if (sel == CLK_SARADC_SEL_OSC)
703 			prate = OSC_HZ;
704 		else
705 			prate = priv->gpll_hz;
706 		return DIV_TO_RATE(prate, div);
707 	case CLK_TSADC:
708 		con = readl(&cru->clksel_con[59]);
709 		div = (con & CLK_TSADC_DIV_MASK) >>
710 		      CLK_TSADC_DIV_SHIFT;
711 		prate = OSC_HZ;
712 		return DIV_TO_RATE(prate, div);
713 	default:
714 		return -ENOENT;
715 	}
716 }
717 
rk3576_adc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)718 static ulong rk3576_adc_set_clk(struct rk3576_clk_priv *priv,
719 				ulong clk_id, ulong rate)
720 {
721 	struct rk3576_cru *cru = priv->cru;
722 	int src_clk_div;
723 
724 	switch (clk_id) {
725 	case CLK_SARADC:
726 		if (!(OSC_HZ % rate)) {
727 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
728 			assert(src_clk_div - 1 <= 255);
729 			rk_clrsetreg(&cru->clksel_con[58],
730 				     CLK_SARADC_SEL_MASK |
731 				     CLK_SARADC_DIV_MASK,
732 				     (CLK_SARADC_SEL_OSC <<
733 				      CLK_SARADC_SEL_SHIFT) |
734 				     (src_clk_div - 1) <<
735 				     CLK_SARADC_DIV_SHIFT);
736 		} else {
737 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
738 			assert(src_clk_div - 1 <= 255);
739 			rk_clrsetreg(&cru->clksel_con[59],
740 				     CLK_SARADC_SEL_MASK |
741 				     CLK_SARADC_DIV_MASK,
742 				     (CLK_SARADC_SEL_GPLL <<
743 				      CLK_SARADC_SEL_SHIFT) |
744 				     (src_clk_div - 1) <<
745 				     CLK_SARADC_DIV_SHIFT);
746 		}
747 		break;
748 	case CLK_TSADC:
749 		src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
750 		assert(src_clk_div - 1 <= 255);
751 		rk_clrsetreg(&cru->clksel_con[58],
752 			     CLK_TSADC_DIV_MASK,
753 			     (src_clk_div - 1) <<
754 			     CLK_TSADC_DIV_SHIFT);
755 		break;
756 	default:
757 		return -ENOENT;
758 	}
759 	return rk3576_adc_get_clk(priv, clk_id);
760 }
761 
rk3576_mmc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)762 static ulong rk3576_mmc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
763 {
764 	struct rk3576_cru *cru = priv->cru;
765 	u32 sel, con, prate, div = 0;
766 
767 	switch (clk_id) {
768 	case CCLK_SRC_SDIO:
769 	case HCLK_SDIO:
770 		con = readl(&cru->clksel_con[104]);
771 		div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
772 		sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
773 		      CCLK_SDIO_SRC_SEL_SHIFT;
774 		if (sel == CCLK_SDIO_SRC_SEL_GPLL)
775 			prate = priv->gpll_hz;
776 		else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
777 			prate = priv->cpll_hz;
778 		else
779 			prate = OSC_HZ;
780 		return DIV_TO_RATE(prate, div);
781 	case CCLK_SRC_SDMMC0:
782 	case HCLK_SDMMC0:
783 		con = readl(&cru->clksel_con[105]);
784 		div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT;
785 		sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >>
786 		      CCLK_SDMMC0_SRC_SEL_SHIFT;
787 		if (sel == CCLK_SDMMC0_SRC_SEL_GPLL)
788 			prate = priv->gpll_hz;
789 		else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL)
790 			prate = priv->cpll_hz;
791 		else
792 			prate = OSC_HZ;
793 		return DIV_TO_RATE(prate, div);
794 	case CCLK_SRC_EMMC:
795 	case HCLK_EMMC:
796 		con = readl(&cru->clksel_con[89]);
797 		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
798 		sel = (con & CCLK_EMMC_SEL_MASK) >>
799 		      CCLK_EMMC_SEL_SHIFT;
800 		if (sel == CCLK_EMMC_SEL_GPLL)
801 			prate = priv->gpll_hz;
802 		else if (sel == CCLK_EMMC_SEL_CPLL)
803 			prate = priv->cpll_hz;
804 		else
805 			prate = OSC_HZ;
806 		return DIV_TO_RATE(prate, div);
807 	case BCLK_EMMC:
808 		con = readl(&cru->clksel_con[90]);
809 		sel = (con & BCLK_EMMC_SEL_MASK) >>
810 		      BCLK_EMMC_SEL_SHIFT;
811 		if (sel == BCLK_EMMC_SEL_200M)
812 			prate = 200 * MHz;
813 		else if (sel == BCLK_EMMC_SEL_100M)
814 			prate = 100 * MHz;
815 		else if (sel == BCLK_EMMC_SEL_50M)
816 			prate = 50 * MHz;
817 		else
818 			prate = OSC_HZ;
819 		return DIV_TO_RATE(prate, div);
820 	case SCLK_FSPI_X2:
821 		con = readl(&cru->clksel_con[89]);
822 		div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
823 		sel = (con & SCLK_FSPI_SEL_MASK) >>
824 		      SCLK_FSPI_SEL_SHIFT;
825 		if (sel == SCLK_FSPI_SEL_GPLL)
826 			prate = priv->gpll_hz;
827 		else if (sel == SCLK_FSPI_SEL_CPLL)
828 			prate = priv->cpll_hz;
829 		else
830 			prate = OSC_HZ;
831 		return DIV_TO_RATE(prate, div);
832 	case SCLK_FSPI1_X2:
833 		con = readl(&cru->clksel_con[106]);
834 		div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT;
835 		sel = (con & SCLK_FSPI_SEL_MASK) >>
836 		      SCLK_FSPI_SEL_SHIFT;
837 		if (sel == SCLK_FSPI_SEL_GPLL)
838 			prate = priv->gpll_hz;
839 		else if (sel == SCLK_FSPI_SEL_CPLL)
840 			prate = priv->cpll_hz;
841 		else
842 			prate = OSC_HZ;
843 		return DIV_TO_RATE(prate, div);
844 	case DCLK_DECOM:
845 		con = readl(&cru->clksel_con[72]);
846 		div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
847 		sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
848 		if (sel == DCLK_DECOM_SEL_SPLL)
849 			prate = priv->spll_hz;
850 		else
851 			prate = priv->gpll_hz;
852 		return DIV_TO_RATE(prate, div);
853 
854 	default:
855 		return -ENOENT;
856 	}
857 }
858 
rk3576_mmc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)859 static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv,
860 				ulong clk_id, ulong rate)
861 {
862 	struct rk3576_cru *cru = priv->cru;
863 	int src_clk, div = 0;
864 
865 	switch (clk_id) {
866 	case CCLK_SRC_SDIO:
867 	case CCLK_SRC_SDMMC0:
868 	case CCLK_SRC_EMMC:
869 	case SCLK_FSPI_X2:
870 	case SCLK_FSPI1_X2:
871 	case HCLK_SDMMC0:
872 	case HCLK_EMMC:
873 	case HCLK_SDIO:
874 		if (!(OSC_HZ % rate)) {
875 			src_clk = SCLK_FSPI_SEL_OSC;
876 			div = DIV_ROUND_UP(OSC_HZ, rate);
877 		} else if (!(priv->cpll_hz % rate)) {
878 			src_clk = SCLK_FSPI_SEL_CPLL;
879 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
880 		} else {
881 			src_clk = SCLK_FSPI_SEL_GPLL;
882 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
883 		}
884 		break;
885 	case BCLK_EMMC:
886 		if (rate >= 198 * MHz)
887 			src_clk = BCLK_EMMC_SEL_200M;
888 		else if (rate >= 99 * MHz)
889 			src_clk = BCLK_EMMC_SEL_100M;
890 		else if (rate >= 50 * MHz)
891 			src_clk = BCLK_EMMC_SEL_50M;
892 		else
893 			src_clk = BCLK_EMMC_SEL_OSC;
894 		break;
895 	case DCLK_DECOM:
896 		if (!(priv->spll_hz % rate)) {
897 			src_clk = DCLK_DECOM_SEL_SPLL;
898 			div = DIV_ROUND_UP(priv->spll_hz, rate);
899 		} else {
900 			src_clk = DCLK_DECOM_SEL_GPLL;
901 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
902 		}
903 		break;
904 	default:
905 		return -ENOENT;
906 	}
907 
908 	switch (clk_id) {
909 	case CCLK_SRC_SDIO:
910 	case HCLK_SDIO:
911 		rk_clrsetreg(&cru->clksel_con[104],
912 			     CCLK_SDIO_SRC_SEL_MASK |
913 			     CCLK_SDIO_SRC_DIV_MASK,
914 			     (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
915 			     (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
916 		break;
917 	case CCLK_SRC_SDMMC0:
918 	case HCLK_SDMMC0:
919 		rk_clrsetreg(&cru->clksel_con[105],
920 			     CCLK_SDMMC0_SRC_SEL_MASK |
921 			     CCLK_SDMMC0_SRC_DIV_MASK,
922 			     (src_clk << CCLK_SDMMC0_SRC_SEL_SHIFT) |
923 			     (div - 1) << CCLK_SDMMC0_SRC_DIV_SHIFT);
924 		break;
925 	case CCLK_SRC_EMMC:
926 	case HCLK_EMMC:
927 		rk_clrsetreg(&cru->clksel_con[89],
928 			     CCLK_EMMC_DIV_MASK |
929 			     CCLK_EMMC_SEL_MASK,
930 			     (src_clk << CCLK_EMMC_SEL_SHIFT) |
931 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
932 		break;
933 	case SCLK_FSPI_X2:
934 		rk_clrsetreg(&cru->clksel_con[89],
935 			     SCLK_FSPI_DIV_MASK |
936 			     SCLK_FSPI_SEL_MASK,
937 			     (src_clk << SCLK_FSPI_SEL_SHIFT) |
938 			     (div - 1) << SCLK_FSPI_DIV_SHIFT);
939 		break;
940 	case SCLK_FSPI1_X2:
941 		rk_clrsetreg(&cru->clksel_con[106],
942 			     SCLK_FSPI_DIV_MASK |
943 			     SCLK_FSPI_SEL_MASK,
944 			     (src_clk << SCLK_FSPI_SEL_SHIFT) |
945 			     (div - 1) << SCLK_FSPI_DIV_SHIFT);
946 		break;
947 	case BCLK_EMMC:
948 		rk_clrsetreg(&cru->clksel_con[90],
949 			     BCLK_EMMC_SEL_MASK,
950 			     src_clk << BCLK_EMMC_SEL_SHIFT);
951 		break;
952 	case DCLK_DECOM:
953 		rk_clrsetreg(&cru->clksel_con[72],
954 			     DCLK_DECOM_DIV_MASK |
955 			     DCLK_DECOM_SEL_MASK,
956 			     (src_clk << DCLK_DECOM_SEL_SHIFT) |
957 			     (div - 1) << DCLK_DECOM_DIV_SHIFT);
958 		break;
959 
960 	default:
961 		return -ENOENT;
962 	}
963 
964 	return rk3576_mmc_get_clk(priv, clk_id);
965 }
966 
967 #ifndef CONFIG_SPL_BUILD
968 
rk3576_aclk_vop_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)969 static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
970 {
971 	struct rk3576_cru *cru = priv->cru;
972 	u32 div, sel, con, parent = 0;
973 
974 	switch (clk_id) {
975 	case ACLK_VOP_ROOT:
976 	case ACLK_VOP:
977 		con = readl(&cru->clksel_con[144]);
978 		div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
979 		sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
980 		if (sel == ACLK_VOP_ROOT_SEL_GPLL)
981 			parent = priv->gpll_hz;
982 		else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
983 			parent = priv->cpll_hz;
984 		else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
985 			parent = priv->aupll_hz;
986 		else if (sel == ACLK_VOP_ROOT_SEL_SPLL)
987 			parent = priv->spll_hz;
988 		else if (sel == ACLK_VOP_ROOT_SEL_LPLL)
989 			parent = priv->lpll_hz / 2;
990 		return DIV_TO_RATE(parent, div);
991 	case ACLK_VO0_ROOT:
992 		con = readl(&cru->clksel_con[149]);
993 		div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
994 		sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
995 		if (sel == ACLK_VO0_ROOT_SEL_GPLL)
996 			parent = priv->gpll_hz;
997 		else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
998 			parent = priv->cpll_hz;
999 		else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
1000 			parent = priv->lpll_hz / 2;
1001 		else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
1002 			parent = priv->bpll_hz / 4;
1003 		return DIV_TO_RATE(parent, div);
1004 	case ACLK_VO1_ROOT:
1005 		con = readl(&cru->clksel_con[158]);
1006 		div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT;
1007 		sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT;
1008 		if (sel == ACLK_VO0_ROOT_SEL_GPLL)
1009 			parent = priv->gpll_hz;
1010 		else if (sel == ACLK_VO0_ROOT_SEL_CPLL)
1011 			parent = priv->cpll_hz;
1012 		else if (sel == ACLK_VO0_ROOT_SEL_LPLL)
1013 			parent = priv->lpll_hz / 2;
1014 		else if (sel == ACLK_VO0_ROOT_SEL_BPLL)
1015 			parent = priv->bpll_hz / 4;
1016 		return DIV_TO_RATE(parent, div);
1017 	case HCLK_VOP_ROOT:
1018 		con = readl(&cru->clksel_con[144]);
1019 		sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
1020 		if (sel == HCLK_VOP_ROOT_SEL_200M)
1021 			return 200 * MHz;
1022 		else if (sel == HCLK_VOP_ROOT_SEL_100M)
1023 			return 100 * MHz;
1024 		else if (sel == HCLK_VOP_ROOT_SEL_50M)
1025 			return 50 * MHz;
1026 		else
1027 			return OSC_HZ;
1028 	case PCLK_VOP_ROOT:
1029 		con = readl(&cru->clksel_con[144]);
1030 		sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT;
1031 		if (sel == PCLK_VOP_ROOT_SEL_100M)
1032 			return 100 * MHz;
1033 		else if (sel == PCLK_VOP_ROOT_SEL_50M)
1034 			return 50 * MHz;
1035 		else
1036 			return OSC_HZ;
1037 
1038 	default:
1039 		return -ENOENT;
1040 	}
1041 }
1042 
rk3576_aclk_vop_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1043 static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv,
1044 				     ulong clk_id, ulong rate)
1045 {
1046 	struct rk3576_cru *cru = priv->cru;
1047 	int src_clk, div;
1048 
1049 	switch (clk_id) {
1050 	case ACLK_VOP_ROOT:
1051 	case ACLK_VOP:
1052 		if (rate == 700 * MHz) {
1053 			src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1054 			div = 1;
1055 		} else if (!(priv->cpll_hz % rate)) {
1056 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1057 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1058 		} else {
1059 			src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1060 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1061 		}
1062 		rk_clrsetreg(&cru->clksel_con[144],
1063 			     ACLK_VOP_ROOT_DIV_MASK |
1064 			     ACLK_VOP_ROOT_SEL_MASK,
1065 			     (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1066 			     (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1067 		break;
1068 	case ACLK_VO0_ROOT:
1069 		if (!(priv->cpll_hz % rate)) {
1070 			src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1071 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1072 		} else {
1073 			src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1074 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1075 		}
1076 		rk_clrsetreg(&cru->clksel_con[149],
1077 			     ACLK_VO0_ROOT_DIV_MASK |
1078 			     ACLK_VO0_ROOT_SEL_MASK,
1079 			     (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1080 			     (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1081 		break;
1082 	case ACLK_VO1_ROOT:
1083 		if (!(priv->cpll_hz % rate)) {
1084 			src_clk = ACLK_VO0_ROOT_SEL_CPLL;
1085 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1086 		} else {
1087 			src_clk = ACLK_VO0_ROOT_SEL_GPLL;
1088 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1089 		}
1090 		rk_clrsetreg(&cru->clksel_con[158],
1091 			     ACLK_VO0_ROOT_DIV_MASK |
1092 			     ACLK_VO0_ROOT_SEL_MASK,
1093 			     (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) |
1094 			     (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT);
1095 		break;
1096 	case HCLK_VOP_ROOT:
1097 		if (rate == 200 * MHz)
1098 			src_clk = HCLK_VOP_ROOT_SEL_200M;
1099 		else if (rate == 100 * MHz)
1100 			src_clk = HCLK_VOP_ROOT_SEL_100M;
1101 		else if (rate == 50 * MHz)
1102 			src_clk = HCLK_VOP_ROOT_SEL_50M;
1103 		else
1104 			src_clk = HCLK_VOP_ROOT_SEL_OSC;
1105 		rk_clrsetreg(&cru->clksel_con[144],
1106 			     HCLK_VOP_ROOT_SEL_MASK,
1107 			     src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1108 		break;
1109 	case PCLK_VOP_ROOT:
1110 		if (rate == 100 * MHz)
1111 			src_clk = PCLK_VOP_ROOT_SEL_100M;
1112 		else if (rate == 50 * MHz)
1113 			src_clk = PCLK_VOP_ROOT_SEL_50M;
1114 		else
1115 			src_clk = PCLK_VOP_ROOT_SEL_OSC;
1116 		rk_clrsetreg(&cru->clksel_con[144],
1117 			     PCLK_VOP_ROOT_SEL_MASK,
1118 			     src_clk << PCLK_VOP_ROOT_SEL_SHIFT);
1119 		break;
1120 
1121 	default:
1122 		return -ENOENT;
1123 	}
1124 
1125 	return rk3576_aclk_vop_get_clk(priv, clk_id);
1126 }
1127 
rk3576_dclk_vop_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1128 static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1129 {
1130 	struct rk3576_cru *cru = priv->cru;
1131 	u32 div, sel, con, parent;
1132 
1133 	switch (clk_id) {
1134 	case DCLK_VP0:
1135 	case DCLK_VP0_SRC:
1136 		con = readl(&cru->clksel_con[145]);
1137 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1138 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1139 		break;
1140 	case DCLK_VP1:
1141 	case DCLK_VP1_SRC:
1142 		con = readl(&cru->clksel_con[146]);
1143 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1144 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1145 		break;
1146 	case DCLK_VP2:
1147 	case DCLK_VP2_SRC:
1148 		con = readl(&cru->clksel_con[147]);
1149 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1150 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1151 		break;
1152 	default:
1153 		return -ENOENT;
1154 	}
1155 
1156 	if (sel == DCLK_VOP_SRC_SEL_VPLL)
1157 		parent = priv->vpll_hz;
1158 	else if (sel == DCLK_VOP_SRC_SEL_BPLL)
1159 		parent = priv->bpll_hz / 4;
1160 	else if (sel == DCLK_VOP_SRC_SEL_LPLL)
1161 		parent = priv->lpll_hz / 2;
1162 	else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1163 		parent = priv->gpll_hz;
1164 	else
1165 		parent = priv->cpll_hz;
1166 
1167 	return DIV_TO_RATE(parent, div);
1168 }
1169 
1170 #define RK3576_VOP_PLL_LIMIT_FREQ 594000000
1171 
rk3576_dclk_vop_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1172 static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv,
1173 				     ulong clk_id, ulong rate)
1174 {
1175 	struct rk3576_cru *cru = priv->cru;
1176 	ulong pll_rate, now, best_rate = 0;
1177 	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1178 	u32 mask, div_shift, sel_shift;
1179 
1180 	switch (clk_id) {
1181 	case DCLK_VP0:
1182 	case DCLK_VP0_SRC:
1183 		conid = 145;
1184 		con = readl(&cru->clksel_con[conid]);
1185 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1186 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1187 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1188 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1189 		break;
1190 	case DCLK_VP1:
1191 	case DCLK_VP1_SRC:
1192 		conid = 146;
1193 		con = readl(&cru->clksel_con[conid]);
1194 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1195 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1196 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1197 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1198 		break;
1199 	case DCLK_VP2:
1200 	case DCLK_VP2_SRC:
1201 		conid = 147;
1202 		con = readl(&cru->clksel_con[conid]);
1203 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1204 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1205 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1206 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1207 		break;
1208 	default:
1209 		return -ENOENT;
1210 	}
1211 
1212 	if (sel == DCLK_VOP_SRC_SEL_VPLL) {
1213 		pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1214 						 priv->cru, VPLL);
1215 		if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
1216 			div = DIV_ROUND_UP(pll_rate, rate);
1217 			rk_clrsetreg(&cru->clksel_con[conid],
1218 				     mask,
1219 				     DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1220 				     ((div - 1) << div_shift));
1221 		} else {
1222 			div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate);
1223 			if (div % 2)
1224 				div = div + 1;
1225 			rk_clrsetreg(&cru->clksel_con[conid],
1226 				     mask,
1227 				     DCLK_VOP_SRC_SEL_VPLL << sel_shift |
1228 				     ((div - 1) << div_shift));
1229 			rockchip_pll_set_rate(&rk3576_pll_clks[VPLL],
1230 					      priv->cru, VPLL, div * rate);
1231 			priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1232 							      priv->cru, VPLL);
1233 		}
1234 	} else {
1235 		for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) {
1236 			switch (i) {
1237 			case DCLK_VOP_SRC_SEL_GPLL:
1238 				pll_rate = priv->gpll_hz;
1239 				break;
1240 			case DCLK_VOP_SRC_SEL_CPLL:
1241 				pll_rate = priv->cpll_hz;
1242 				break;
1243 			case DCLK_VOP_SRC_SEL_BPLL:
1244 				pll_rate = 0;
1245 				break;
1246 			case DCLK_VOP_SRC_SEL_LPLL:
1247 				pll_rate = 0;
1248 				break;
1249 			case DCLK_VOP_SRC_SEL_VPLL:
1250 				pll_rate = 0;
1251 				break;
1252 			default:
1253 				printf("do not support this vop pll sel\n");
1254 				return -EINVAL;
1255 			}
1256 
1257 			div = DIV_ROUND_UP(pll_rate, rate);
1258 			if (div > 255)
1259 				continue;
1260 			now = pll_rate / div;
1261 			if (abs(rate - now) < abs(rate - best_rate)) {
1262 				best_rate = now;
1263 				best_div = div;
1264 				best_sel = i;
1265 			}
1266 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1267 			      pll_rate, best_rate, best_div, best_sel);
1268 		}
1269 
1270 		if (best_rate) {
1271 			rk_clrsetreg(&cru->clksel_con[conid],
1272 				     mask,
1273 				     best_sel << sel_shift |
1274 				     (best_div - 1) << div_shift);
1275 		} else {
1276 			printf("do not support this vop freq %lu\n", rate);
1277 			return -EINVAL;
1278 		}
1279 	}
1280 	return rk3576_dclk_vop_get_clk(priv, clk_id);
1281 }
1282 
rk3576_clk_csihost_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1283 static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1284 {
1285 	struct rk3576_cru *cru = priv->cru;
1286 	u32 div, sel, con, parent;
1287 
1288 	switch (clk_id) {
1289 		case CLK_DSIHOST0:
1290 		con = readl(&cru->clksel_con[151]);
1291 		div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT;
1292 		sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT;
1293 		break;
1294 	default:
1295 		return -ENOENT;
1296 	}
1297 
1298 	if (sel == CLK_DSIHOST0_SEL_VPLL)
1299 		parent = priv->vpll_hz;
1300 	else if (sel == CLK_DSIHOST0_SEL_BPLL)
1301 		parent = priv->bpll_hz / 4;
1302 	else if (sel == CLK_DSIHOST0_SEL_LPLL)
1303 		parent = priv->lpll_hz / 2;
1304 	else if (sel == CLK_DSIHOST0_SEL_GPLL)
1305 		parent = priv->gpll_hz;
1306 	else if (sel == CLK_DSIHOST0_SEL_SPLL)
1307 		parent = priv->spll_hz;
1308 	else
1309 		parent = priv->cpll_hz;
1310 
1311 	return DIV_TO_RATE(parent, div);
1312 }
1313 
rk3576_clk_csihost_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1314 static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv,
1315 				     ulong clk_id, ulong rate)
1316 {
1317 	struct rk3576_cru *cru = priv->cru;
1318 	ulong pll_rate, now, best_rate = 0;
1319 	u32 i, con, div, best_div = 0, best_sel = 0;
1320 	u32 mask, div_shift, sel_shift;
1321 
1322 	switch (clk_id) {
1323 	case CLK_DSIHOST0:
1324 		con = 151;
1325 		mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK;
1326 		div_shift = CLK_DSIHOST0_DIV_SHIFT;
1327 		sel_shift = CLK_DSIHOST0_SEL_SHIFT;
1328 		break;
1329 	default:
1330 		return -ENOENT;
1331 	}
1332 	for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) {
1333 		switch (i) {
1334 		case CLK_DSIHOST0_SEL_GPLL:
1335 			pll_rate = priv->gpll_hz;
1336 			break;
1337 		case CLK_DSIHOST0_SEL_CPLL:
1338 			pll_rate = priv->cpll_hz;
1339 			break;
1340 		case CLK_DSIHOST0_SEL_BPLL:
1341 			pll_rate = 0;
1342 			break;
1343 		case CLK_DSIHOST0_SEL_LPLL:
1344 			pll_rate = 0;
1345 			break;
1346 		case CLK_DSIHOST0_SEL_VPLL:
1347 			pll_rate = 0;
1348 			break;
1349 		case CLK_DSIHOST0_SEL_SPLL:
1350 			pll_rate = priv->spll_hz;
1351 			break;
1352 		default:
1353 			printf("do not support this vop pll sel\n");
1354 			return -EINVAL;
1355 		}
1356 
1357 		div = DIV_ROUND_UP(pll_rate, rate);
1358 		if (div > 255)
1359 			continue;
1360 		now = pll_rate / div;
1361 		if (abs(rate - now) < abs(rate - best_rate)) {
1362 			best_rate = now;
1363 			best_div = div;
1364 			best_sel = i;
1365 		}
1366 		debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1367 		      pll_rate, best_rate, best_div, best_sel);
1368 	}
1369 	if (best_rate) {
1370 		rk_clrsetreg(&cru->clksel_con[con],
1371 			     mask,
1372 			     best_sel << sel_shift |
1373 			     (best_div - 1) << div_shift);
1374 	} else {
1375 		printf("do not support this vop freq %lu\n", rate);
1376 		return -EINVAL;
1377 	}
1378 	return rk3576_clk_csihost_get_clk(priv, clk_id);
1379 }
1380 
rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1381 static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1382 {
1383 	struct rk3576_cru *cru = priv->cru;
1384 	u32 div, sel, con, parent;
1385 	unsigned long m = 0, n = 0;
1386 
1387 	switch (clk_id) {
1388 	case DCLK_EBC:
1389 		con = readl(&cru->clksel_con[123]);
1390 		div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT;
1391 		sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
1392 		if (sel == DCLK_EBC_SEL_CPLL)
1393 			parent = priv->cpll_hz;
1394 		else if (sel == DCLK_EBC_SEL_VPLL)
1395 			parent = priv->vpll_hz;
1396 		else if (sel == DCLK_EBC_SEL_AUPLL)
1397 			parent = priv->aupll_hz;
1398 		else if (sel == DCLK_EBC_SEL_LPLL)
1399 			parent = priv->lpll_hz / 2;
1400 		else if (sel == DCLK_EBC_SEL_GPLL)
1401 			parent = priv->gpll_hz;
1402 		else if (sel == DCLK_EBC_SEL_FRAC_SRC)
1403 			parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC);
1404 		else
1405 			parent = OSC_HZ;
1406 		return DIV_TO_RATE(parent, div);
1407 	case DCLK_EBC_FRAC_SRC:
1408 		con = readl(&cru->clksel_con[123]);
1409 		div = readl(&cru->clksel_con[122]);
1410 		sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT;
1411 		if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL)
1412 			parent = priv->gpll_hz;
1413 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL)
1414 			parent = priv->cpll_hz;
1415 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL)
1416 			parent = priv->vpll_hz;
1417 		else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL)
1418 			parent = priv->aupll_hz;
1419 		else
1420 			parent = OSC_HZ;
1421 
1422 		n = div & CLK_UART_FRAC_NUMERATOR_MASK;
1423 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1424 		m = div & CLK_UART_FRAC_DENOMINATOR_MASK;
1425 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1426 		return parent * n / m;
1427 	default:
1428 		return -ENOENT;
1429 	}
1430 }
1431 
rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1432 static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv,
1433 				     ulong clk_id, ulong rate)
1434 {
1435 	struct rk3576_cru *cru = priv->cru;
1436 	ulong pll_rate, now, best_rate = 0;
1437 	u32 i, con, sel, div, best_div = 0, best_sel = 0;
1438 	unsigned long m = 0, n = 0, val;
1439 
1440 	switch (clk_id) {
1441 	case DCLK_EBC:
1442 		con = readl(&cru->clksel_con[123]);
1443 		sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
1444 		if (sel == DCLK_EBC_SEL_VPLL) {
1445 			pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1446 							 priv->cru, VPLL);
1447 			if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ &&
1448 			    pll_rate % rate == 0) {
1449 				div = DIV_ROUND_UP(pll_rate, rate);
1450 				rk_clrsetreg(&cru->clksel_con[123],
1451 					     DCLK_EBC_DIV_MASK,
1452 					     (div - 1) << DCLK_EBC_DIV_SHIFT);
1453 			} else {
1454 				div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ,
1455 						   rate);
1456 				if (div % 2)
1457 					div = div + 1;
1458 				rk_clrsetreg(&cru->clksel_con[123],
1459 					     DCLK_EBC_DIV_MASK,
1460 					     (div - 1) << DCLK_EBC_DIV_SHIFT);
1461 				rockchip_pll_set_rate(&rk3576_pll_clks[VPLL],
1462 						      priv->cru,
1463 						      VPLL, div * rate);
1464 				priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
1465 								      priv->cru,
1466 								      VPLL);
1467 			}
1468 		} else if (sel == DCLK_EBC_SEL_FRAC_SRC) {
1469 			rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate);
1470 			div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate;
1471 			rk_clrsetreg(&cru->clksel_con[123],
1472 				     DCLK_EBC_DIV_MASK,
1473 				     (div - 1) << DCLK_EBC_DIV_SHIFT);
1474 		} else {
1475 			for (i = 0; i <= DCLK_EBC_SEL_LPLL; i++) {
1476 				switch (i) {
1477 				case DCLK_EBC_SEL_GPLL:
1478 					pll_rate = priv->gpll_hz;
1479 					break;
1480 				case DCLK_EBC_SEL_CPLL:
1481 					pll_rate = priv->cpll_hz;
1482 					break;
1483 				case DCLK_EBC_SEL_VPLL:
1484 					pll_rate = 0;
1485 					break;
1486 				case DCLK_EBC_SEL_AUPLL:
1487 					pll_rate = priv->aupll_hz;
1488 					break;
1489 				case DCLK_EBC_SEL_LPLL:
1490 					pll_rate = 0;
1491 					break;
1492 				default:
1493 					printf("not support ebc pll sel\n");
1494 					return -EINVAL;
1495 				}
1496 
1497 				div = DIV_ROUND_UP(pll_rate, rate);
1498 				if (div > 255)
1499 					continue;
1500 				now = pll_rate / div;
1501 				if (abs(rate - now) < abs(rate - best_rate)) {
1502 					best_rate = now;
1503 					best_div = div;
1504 					best_sel = i;
1505 				}
1506 			}
1507 
1508 			if (best_rate) {
1509 				rk_clrsetreg(&cru->clksel_con[123],
1510 					     DCLK_EBC_DIV_MASK |
1511 					     DCLK_EBC_SEL_MASK,
1512 					     best_sel <<
1513 					     DCLK_EBC_SEL_SHIFT |
1514 					     (best_div - 1) <<
1515 					     DCLK_EBC_DIV_SHIFT);
1516 			} else {
1517 				printf("do not support this vop freq %lu\n",
1518 				       rate);
1519 				return -EINVAL;
1520 			}
1521 		}
1522 		break;
1523 	case DCLK_EBC_FRAC_SRC:
1524 		sel = DCLK_EBC_FRAC_SRC_SEL_GPLL;
1525 		div = 1;
1526 		rational_best_approximation(rate, priv->gpll_hz,
1527 					    GENMASK(16 - 1, 0),
1528 					    GENMASK(16 - 1, 0),
1529 					    &m, &n);
1530 
1531 		if (m < 4 && m != 0) {
1532 			if (n % 2 == 0)
1533 				val = 1;
1534 			else
1535 				val = DIV_ROUND_UP(4, m);
1536 
1537 			n *= val;
1538 			m *= val;
1539 			if (n > 0xffff) {
1540 				n = 0xffff;
1541 			}
1542 		}
1543 
1544 		rk_clrsetreg(&cru->clksel_con[123],
1545 		     DCLK_EBC_FRAC_SRC_SEL_MASK,
1546 		     (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT));
1547 		if (m && n) {
1548 			val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1549 			writel(val, &cru->clksel_con[122]);
1550 		}
1551 		break;
1552 	default:
1553 		return -ENOENT;
1554 	}
1555 	return rk3576_dclk_ebc_get_clk(priv, clk_id);
1556 }
1557 
rk3576_gmac_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1558 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
1559 {
1560 	struct rk3576_cru *cru = priv->cru;
1561 	u32 con, div, src, p_rate;
1562 
1563 	switch (clk_id) {
1564 	case CLK_GMAC0_PTP_REF_SRC:
1565 	case CLK_GMAC0_PTP_REF:
1566 		con = readl(&cru->clksel_con[105]);
1567 		div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1568 		src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT;
1569 		if (src == CLK_GMAC0_PTP_SEL_GPLL)
1570 			p_rate = priv->gpll_hz;
1571 		else if (src == CLK_GMAC0_PTP_SEL_CPLL)
1572 			p_rate = priv->cpll_hz;
1573 		else
1574 			p_rate = GMAC0_PTP_REFCLK_IN;
1575 		return DIV_TO_RATE(p_rate, div);
1576 	case CLK_GMAC1_PTP_REF_SRC:
1577 	case CLK_GMAC1_PTP_REF:
1578 		con = readl(&cru->clksel_con[104]);
1579 		div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1580 		src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT;
1581 		if (src == CLK_GMAC1_PTP_SEL_GPLL)
1582 			p_rate = priv->gpll_hz;
1583 		else if (src == CLK_GMAC1_PTP_SEL_CPLL)
1584 			p_rate = priv->cpll_hz;
1585 		else
1586 			p_rate = GMAC1_PTP_REFCLK_IN;
1587 		return DIV_TO_RATE(p_rate, div);
1588 	case CLK_GMAC0_125M_SRC:
1589 		con = readl(&cru->clksel_con[30]);
1590 		div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT;
1591 		return DIV_TO_RATE(priv->cpll_hz, div);
1592 	case CLK_GMAC1_125M_SRC:
1593 		con = readl(&cru->clksel_con[31]);
1594 		div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT;
1595 		return DIV_TO_RATE(priv->cpll_hz, div);
1596 	default:
1597 		return -ENOENT;
1598 	}
1599 }
1600 
rk3576_gmac_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1601 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv,
1602 				 ulong clk_id, ulong rate)
1603 {
1604 	struct rk3576_cru *cru = priv->cru;
1605 	int div, src;
1606 
1607 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
1608 
1609 	switch (clk_id) {
1610 	case CLK_GMAC0_PTP_REF_SRC:
1611 	case CLK_GMAC0_PTP_REF:
1612 		if (rate == GMAC0_PTP_REFCLK_IN) {
1613 			src = CLK_GMAC0_PTP_SEL_REFIN;
1614 			div = 1;
1615 		} else if (!(priv->gpll_hz % rate)) {
1616 			src = CLK_GMAC0_PTP_SEL_GPLL;
1617 			div = priv->gpll_hz / rate;
1618 		} else {
1619 			src = CLK_GMAC0_PTP_SEL_CPLL;
1620 			div = priv->cpll_hz / rate;
1621 		}
1622 		rk_clrsetreg(&cru->clksel_con[105],
1623 			     CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1624 			     src << CLK_GMAC0_PTP_SEL_SHIFT |
1625 			     (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1626 		break;
1627 	case CLK_GMAC1_PTP_REF_SRC:
1628 	case CLK_GMAC1_PTP_REF:
1629 		if (rate == GMAC1_PTP_REFCLK_IN) {
1630 			src = CLK_GMAC1_PTP_SEL_REFIN;
1631 			div = 1;
1632 		} else if (!(priv->gpll_hz % rate)) {
1633 			src = CLK_GMAC1_PTP_SEL_GPLL;
1634 			div = priv->gpll_hz / rate;
1635 		} else {
1636 			src = CLK_GMAC1_PTP_SEL_CPLL;
1637 			div = priv->cpll_hz / rate;
1638 		}
1639 		rk_clrsetreg(&cru->clksel_con[104],
1640 			     CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1641 			     src << CLK_GMAC1_PTP_SEL_SHIFT |
1642 			     (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1643 		break;
1644 
1645 	case CLK_GMAC0_125M_SRC:
1646 		rk_clrsetreg(&cru->clksel_con[30],
1647 			     CLK_GMAC0_125M_DIV_MASK,
1648 			     (div - 1) << CLK_GMAC0_125M_DIV_SHIFT);
1649 		break;
1650 	case CLK_GMAC1_125M_SRC:
1651 		rk_clrsetreg(&cru->clksel_con[31],
1652 			     CLK_GMAC1_125M_DIV_MASK,
1653 			     (div - 1) << CLK_GMAC1_125M_DIV_SHIFT);
1654 		break;
1655 	default:
1656 		return -ENOENT;
1657 	}
1658 
1659 	return rk3576_gmac_get_clk(priv, clk_id);
1660 }
1661 
rk3576_uart_frac_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)1662 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1663 {
1664 	struct rk3576_cru *cru = priv->cru;
1665 	u32 reg, con, fracdiv, p_src, p_rate;
1666 	unsigned long m, n;
1667 
1668 	switch (clk_id) {
1669 	case CLK_UART_FRAC_0:
1670 		reg = 21;
1671 		break;
1672 	case CLK_UART_FRAC_1:
1673 		reg = 23;
1674 		break;
1675 	case CLK_UART_FRAC_2:
1676 		reg = 25;
1677 		break;
1678 	default:
1679 		return -ENOENT;
1680 	}
1681 	con = readl(&cru->clksel_con[reg + 1]);
1682 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1683 	if (p_src == CLK_UART_SRC_SEL_GPLL)
1684 		p_rate = priv->gpll_hz;
1685 	else if (p_src == CLK_UART_SRC_SEL_CPLL)
1686 		p_rate = priv->cpll_hz;
1687 	else if (p_src == CLK_UART_SRC_SEL_AUPLL)
1688 		p_rate = priv->aupll_hz;
1689 	else
1690 		p_rate = OSC_HZ;
1691 
1692 	fracdiv = readl(&cru->clksel_con[reg]);
1693 	n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1694 	n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1695 	m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1696 	m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1697 	return p_rate * n / m;
1698 }
1699 
rk3576_uart_frac_set_rate(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1700 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv,
1701 				  ulong clk_id, ulong rate)
1702 {
1703 	struct rk3576_cru *cru = priv->cru;
1704 	u32 reg, clk_src, p_rate;
1705 	unsigned long m = 0, n = 0, val;
1706 
1707 	if (priv->cpll_hz % rate == 0) {
1708 		clk_src = CLK_UART_SRC_SEL_CPLL;
1709 		p_rate = priv->cpll_hz;
1710 	} else if (rate == OSC_HZ) {
1711 		clk_src = CLK_UART_SRC_SEL_OSC;
1712 		p_rate = OSC_HZ;
1713 	} else {
1714 		clk_src = CLK_UART_SRC_SEL_GPLL;
1715 		p_rate = priv->cpll_hz;
1716 	}
1717 	rational_best_approximation(rate, p_rate,
1718 					    GENMASK(16 - 1, 0),
1719 					    GENMASK(16 - 1, 0),
1720 					    &m, &n);
1721 
1722 	if (m < 4 && m != 0) {
1723 		if (n % 2 == 0)
1724 			val = 1;
1725 		else
1726 			val = DIV_ROUND_UP(4, m);
1727 
1728 		n *= val;
1729 		m *= val;
1730 		if (n > 0xffff) {
1731 			n = 0xffff;
1732 		}
1733 	}
1734 
1735 
1736 	switch (clk_id) {
1737 	case CLK_UART_FRAC_0:
1738 		reg = 21;
1739 		break;
1740 	case CLK_UART_FRAC_1:
1741 		reg = 23;
1742 		break;
1743 	case CLK_UART_FRAC_2:
1744 		reg = 25;
1745 		break;
1746 	default:
1747 		return -ENOENT;
1748 	}
1749 	rk_clrsetreg(&cru->clksel_con[reg +1],
1750 		     CLK_UART_SRC_SEL_MASK,
1751 		     (clk_src << CLK_UART_SRC_SEL_SHIFT));
1752 	if (m && n) {
1753 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1754 		writel(val, &cru->clksel_con[reg]);
1755 	}
1756 
1757 	return rk3576_uart_frac_get_rate(priv, clk_id);
1758 }
1759 
1760 
rk3576_uart_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)1761 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
1762 {
1763 	struct rk3576_cru *cru = priv->cru;
1764 	u32 con, div, src, p_rate;
1765 
1766 	switch (clk_id) {
1767 	case SCLK_UART0:
1768 		con = readl(&cru->clksel_con[60]);
1769 		break;
1770 	case SCLK_UART1:
1771 		con = readl(&cru->pmuclksel_con[8]);
1772 		src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
1773 		if (src == CLK_UART1_SEL_OSC)
1774 			return OSC_HZ;
1775 		con = readl(&cru->clksel_con[27]);
1776 		break;
1777 	case SCLK_UART2:
1778 		con = readl(&cru->clksel_con[61]);
1779 		break;
1780 	case SCLK_UART3:
1781 		con = readl(&cru->clksel_con[62]);
1782 		break;
1783 	case SCLK_UART4:
1784 		con = readl(&cru->clksel_con[63]);
1785 		break;
1786 	case SCLK_UART5:
1787 		con = readl(&cru->clksel_con[64]);
1788 		break;
1789 	case SCLK_UART6:
1790 		con = readl(&cru->clksel_con[65]);
1791 		break;
1792 	case SCLK_UART7:
1793 		con = readl(&cru->clksel_con[66]);
1794 		break;
1795 	case SCLK_UART8:
1796 		con = readl(&cru->clksel_con[67]);
1797 		break;
1798 	case SCLK_UART9:
1799 		con = readl(&cru->clksel_con[68]);
1800 		break;
1801 	case SCLK_UART10:
1802 		con = readl(&cru->clksel_con[69]);
1803 		break;
1804 	case SCLK_UART11:
1805 		con = readl(&cru->clksel_con[70]);
1806 		break;
1807 	default:
1808 		return -ENOENT;
1809 	}
1810 	if (clk_id == SCLK_UART1) {
1811 		src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT;
1812 		div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
1813 	} else {
1814 		src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1815 		div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT;
1816 	}
1817 	if (src == CLK_UART_SEL_GPLL)
1818 		p_rate = priv->gpll_hz;
1819 	else  if (src == CLK_UART_SEL_CPLL)
1820 		p_rate = priv->cpll_hz;
1821 	else  if (src == CLK_UART_SEL_AUPLL)
1822 		p_rate = priv->aupll_hz;
1823 	else  if (src == CLK_UART_SEL_FRAC0)
1824 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0);
1825 	else  if (src == CLK_UART_SEL_FRAC1)
1826 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1);
1827 	else  if (src == CLK_UART_SEL_FRAC2)
1828 		p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2);
1829 	else
1830 		p_rate = OSC_HZ;
1831 
1832 	return DIV_TO_RATE(p_rate, div);
1833 }
1834 
rk3576_uart_set_rate(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1835 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv,
1836 				  ulong clk_id, ulong rate)
1837 {
1838 	struct rk3576_cru *cru = priv->cru;
1839 	u32 reg, clk_src = 0, div = 0;
1840 
1841 	if (!(priv->gpll_hz % rate)) {
1842 		clk_src = CLK_UART_SEL_GPLL;
1843 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1844 	} else if (!(priv->cpll_hz % rate)) {
1845 		clk_src = CLK_UART_SEL_CPLL;
1846 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1847 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) {
1848 		clk_src = CLK_UART_SEL_FRAC0;
1849 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate);
1850 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) {
1851 		clk_src = CLK_UART_SEL_FRAC1;
1852 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate);
1853 	} else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) {
1854 		clk_src = CLK_UART_SEL_FRAC2;
1855 		div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate);
1856 	} else if (!(OSC_HZ % rate)) {
1857 		clk_src = CLK_UART_SEL_OSC;
1858 		div = DIV_ROUND_UP(OSC_HZ, rate);
1859 	}
1860 
1861 	switch (clk_id) {
1862 	case SCLK_UART0:
1863 		reg = 60;
1864 		break;
1865 	case SCLK_UART1:
1866 		if (rate == OSC_HZ) {
1867 			rk_clrsetreg(&cru->pmuclksel_con[8],
1868 		     CLK_UART1_SEL_MASK,
1869 		     (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT));
1870 			return 0;
1871 		} else {
1872 		rk_clrsetreg(&cru->clksel_con[27],
1873 		     CLK_UART1_SRC_SEL_MASK |
1874 		     CLK_UART1_SRC_DIV_MASK,
1875 		     (clk_src << CLK_UART1_SRC_SEL_SHIFT) |
1876 		     ((div - 1) << CLK_UART1_SRC_DIV_SHIFT));
1877 		rk_clrsetreg(&cru->pmuclksel_con[8],
1878 		     CLK_UART1_SEL_MASK,
1879 		     (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT));
1880 		return 0;
1881 		}
1882 		break;
1883 	case SCLK_UART2:
1884 		reg = 61;
1885 		break;
1886 	case SCLK_UART3:
1887 		reg = 62;
1888 		break;
1889 	case SCLK_UART4:
1890 		reg = 63;
1891 		break;
1892 	case SCLK_UART5:
1893 		reg = 64;
1894 		break;
1895 	case SCLK_UART6:
1896 		reg = 65;
1897 		break;
1898 	case SCLK_UART7:
1899 		reg = 66;
1900 		break;
1901 	case SCLK_UART8:
1902 		reg = 67;
1903 		break;
1904 	case SCLK_UART9:
1905 		reg = 68;
1906 		break;
1907 	case SCLK_UART10:
1908 		reg = 69;
1909 		break;
1910 	case SCLK_UART11:
1911 		reg = 70;
1912 		break;
1913 	default:
1914 		return -ENOENT;
1915 	}
1916 	rk_clrsetreg(&cru->clksel_con[reg],
1917 		     CLK_UART_SEL_MASK |
1918 		     CLK_UART_DIV_MASK,
1919 		     (clk_src << CLK_UART_SEL_SHIFT) |
1920 		     ((div - 1) << CLK_UART_DIV_SHIFT));
1921 
1922 	return rk3576_uart_get_rate(priv, clk_id);
1923 }
1924 
rk3576_ref_clkout_get_clk(struct rk3576_clk_priv * priv,ulong clk_id)1925 static ulong rk3576_ref_clkout_get_clk(struct rk3576_clk_priv *priv,
1926 				       ulong clk_id)
1927 {
1928 	struct rk3576_cru *cru = priv->cru;
1929 	u32 reg, con, div, src, p_rate;
1930 
1931 	switch (clk_id) {
1932 	case REF_CLK0_OUT_PLL:
1933 		reg = 33;
1934 		break;
1935 	case REF_CLK1_OUT_PLL:
1936 		reg = 34;
1937 		break;
1938 	case REF_CLK2_OUT_PLL:
1939 		reg = 35;
1940 		break;
1941 	default:
1942 		return -ENOENT;
1943 	}
1944 	con = readl(&cru->clksel_con[reg]);
1945 	div = (con & REF_CLK0_OUT_PLL_DIV_MASK) >> REF_CLK0_OUT_PLL_DIV_SHIFT;
1946 	src = (con & REF_CLK0_OUT_PLL_SEL_MASK) >> REF_CLK0_OUT_PLL_SEL_SHIFT;
1947 	if (src == REF_CLK0_OUT_PLL_SEL_GPLL)
1948 		p_rate = priv->gpll_hz;
1949 	else if (src == REF_CLK0_OUT_PLL_SEL_CPLL)
1950 		p_rate = priv->cpll_hz;
1951 	else if (src == REF_CLK0_OUT_PLL_SEL_SPLL)
1952 		p_rate = priv->spll_hz;
1953 	else if (src == REF_CLK0_OUT_PLL_SEL_AUPLL)
1954 		p_rate = priv->aupll_hz;
1955 	else if (src == REF_CLK0_OUT_PLL_SEL_LPLL)
1956 		p_rate = priv->lpll_hz / 2;
1957 	else
1958 		p_rate = OSC_HZ;
1959 	return DIV_TO_RATE(p_rate, div);
1960 }
1961 
rk3576_ref_clkout_set_clk(struct rk3576_clk_priv * priv,ulong clk_id,ulong rate)1962 static ulong rk3576_ref_clkout_set_clk(struct rk3576_clk_priv *priv,
1963 				       ulong clk_id, ulong rate)
1964 {
1965 	struct rk3576_cru *cru = priv->cru;
1966 	ulong p_rate, now, best_rate = 0;
1967 	u32 i, con, div, best_div = 0, best_sel = 0;
1968 
1969 	switch (clk_id) {
1970 	case REF_CLK0_OUT_PLL:
1971 		con = 33;
1972 		break;
1973 	case REF_CLK1_OUT_PLL:
1974 		con = 34;
1975 		break;
1976 	case REF_CLK2_OUT_PLL:
1977 		con = 35;
1978 		break;
1979 	default:
1980 		return -ENOENT;
1981 	}
1982 
1983 	for (i = 0; i <= REF_CLK0_OUT_PLL_SEL_OSC; i++) {
1984 		switch (i) {
1985 		case REF_CLK0_OUT_PLL_SEL_GPLL:
1986 			p_rate = priv->gpll_hz;
1987 			break;
1988 		case REF_CLK0_OUT_PLL_SEL_CPLL:
1989 			p_rate = priv->cpll_hz;
1990 			break;
1991 		case REF_CLK0_OUT_PLL_SEL_SPLL:
1992 			p_rate = priv->spll_hz;
1993 			break;
1994 		case REF_CLK0_OUT_PLL_SEL_AUPLL:
1995 			p_rate = priv->aupll_hz;
1996 			break;
1997 		case REF_CLK0_OUT_PLL_SEL_LPLL:
1998 			p_rate = 0;
1999 			break;
2000 		case REF_CLK0_OUT_PLL_SEL_OSC:
2001 			p_rate = OSC_HZ;
2002 			break;
2003 		default:
2004 			printf("do not support this vop pll sel\n");
2005 			return -EINVAL;
2006 		}
2007 
2008 		div = DIV_ROUND_UP(p_rate, rate);
2009 		if (div > 255)
2010 			continue;
2011 		now = p_rate / div;
2012 		if (abs(rate - now) < abs(rate - best_rate)) {
2013 			best_rate = now;
2014 			best_div = div;
2015 			best_sel = i;
2016 		}
2017 		debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
2018 		      p_rate, best_rate, best_div, best_sel);
2019 	}
2020 	if (best_rate) {
2021 		rk_clrsetreg(&cru->clksel_con[con],
2022 			     REF_CLK0_OUT_PLL_DIV_MASK |
2023 			     REF_CLK0_OUT_PLL_SEL_MASK,
2024 			     best_sel << REF_CLK0_OUT_PLL_SEL_SHIFT |
2025 			     (best_div - 1) << REF_CLK0_OUT_PLL_DIV_SHIFT);
2026 	} else {
2027 		printf("do not support this vop freq %lu\n", rate);
2028 		return -EINVAL;
2029 	}
2030 
2031 	return rk3576_ref_clkout_get_clk(priv, clk_id);
2032 }
2033 
2034 #endif
2035 
rk3576_ufs_ref_get_rate(struct rk3576_clk_priv * priv,ulong clk_id)2036 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id)
2037 {
2038 	struct rk3576_cru *cru = priv->cru;
2039 	u32 src, div;
2040 
2041 	src = readl(&cru->pmuclksel_con[3]) & 0x3;
2042 	div= readl(&cru->pmuclksel_con[1]) & 0xff;
2043 	if (src == 0)
2044 		return OSC_HZ;
2045 	else if (src == 2)
2046 		return priv->ppll_hz / (div + 1);
2047 	else
2048 		return 26000000;
2049 
2050 }
2051 
rk3576_clk_get_rate(struct clk * clk)2052 static ulong rk3576_clk_get_rate(struct clk *clk)
2053 {
2054 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2055 	ulong rate = 0;
2056 
2057 	if (!priv->gpll_hz) {
2058 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2059 		return -ENOENT;
2060 	}
2061 
2062 	if (!priv->ppll_hz) {
2063 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2064 						      priv->cru, PPLL);
2065 	}
2066 
2067 	switch (clk->id) {
2068 	case PLL_LPLL:
2069 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru,
2070 					     LPLL);
2071 		priv->lpll_hz = rate;
2072 		break;
2073 	case PLL_BPLL:
2074 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru,
2075 					     BPLL);
2076 		priv->bpll_hz = rate;
2077 		break;
2078 	case PLL_GPLL:
2079 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru,
2080 					     GPLL);
2081 		break;
2082 	case PLL_CPLL:
2083 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru,
2084 					     CPLL);
2085 		break;
2086 	case PLL_VPLL:
2087 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru,
2088 					     VPLL);
2089 		break;
2090 	case PLL_AUPLL:
2091 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru,
2092 					     AUPLL);
2093 		break;
2094 	case PLL_PPLL:
2095 		rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru,
2096 					     PPLL) * 2;
2097 		break;
2098 	case ACLK_BUS_ROOT:
2099 	case HCLK_BUS_ROOT:
2100 	case PCLK_BUS_ROOT:
2101 		rate = rk3576_bus_get_clk(priv, clk->id);
2102 		break;
2103 	case ACLK_TOP:
2104 	case HCLK_TOP:
2105 	case PCLK_TOP_ROOT:
2106 	case ACLK_TOP_MID:
2107 		rate = rk3576_top_get_clk(priv, clk->id);
2108 		break;
2109 	case CLK_I2C0:
2110 	case CLK_I2C1:
2111 	case CLK_I2C2:
2112 	case CLK_I2C3:
2113 	case CLK_I2C4:
2114 	case CLK_I2C5:
2115 	case CLK_I2C6:
2116 	case CLK_I2C7:
2117 	case CLK_I2C8:
2118 	case CLK_I2C9:
2119 		rate = rk3576_i2c_get_clk(priv, clk->id);
2120 		break;
2121 	case CLK_SPI0:
2122 	case CLK_SPI1:
2123 	case CLK_SPI2:
2124 	case CLK_SPI3:
2125 	case CLK_SPI4:
2126 		rate = rk3576_spi_get_clk(priv, clk->id);
2127 		break;
2128 	case CLK_PWM1:
2129 	case CLK_PWM2:
2130 	case CLK_PMU1PWM:
2131 		rate = rk3576_pwm_get_clk(priv, clk->id);
2132 		break;
2133 	case CLK_SARADC:
2134 	case CLK_TSADC:
2135 		rate = rk3576_adc_get_clk(priv, clk->id);
2136 		break;
2137 	case CCLK_SRC_SDIO:
2138 	case CCLK_SRC_SDMMC0:
2139 	case CCLK_SRC_EMMC:
2140 	case BCLK_EMMC:
2141 	case SCLK_FSPI_X2:
2142 	case SCLK_FSPI1_X2:
2143 	case DCLK_DECOM:
2144 	case HCLK_SDMMC0:
2145 	case HCLK_EMMC:
2146 	case HCLK_SDIO:
2147 		rate = rk3576_mmc_get_clk(priv, clk->id);
2148 		break;
2149 	case TCLK_WDT0:
2150 		rate = OSC_HZ;
2151 		break;
2152 #ifndef CONFIG_SPL_BUILD
2153 	case ACLK_VOP_ROOT:
2154 	case ACLK_VOP:
2155 	case ACLK_VO0_ROOT:
2156 	case ACLK_VO1_ROOT:
2157 	case HCLK_VOP_ROOT:
2158 	case PCLK_VOP_ROOT:
2159 		rate = rk3576_aclk_vop_get_clk(priv, clk->id);
2160 		break;
2161 	case DCLK_VP0:
2162 	case DCLK_VP0_SRC:
2163 	case DCLK_VP1:
2164 	case DCLK_VP1_SRC:
2165 	case DCLK_VP2:
2166 	case DCLK_VP2_SRC:
2167 		rate = rk3576_dclk_vop_get_clk(priv, clk->id);
2168 		break;
2169 	case CLK_GMAC0_PTP_REF_SRC:
2170 	case CLK_GMAC1_PTP_REF_SRC:
2171 	case CLK_GMAC0_PTP_REF:
2172 	case CLK_GMAC1_PTP_REF:
2173 	case CLK_GMAC0_125M_SRC:
2174 	case CLK_GMAC1_125M_SRC:
2175 		rate = rk3576_gmac_get_clk(priv, clk->id);
2176 		break;
2177 	case CLK_UART_FRAC_0:
2178 	case CLK_UART_FRAC_1:
2179 	case CLK_UART_FRAC_2:
2180 		rate = rk3576_uart_frac_get_rate(priv, clk->id);
2181 		break;
2182 	case SCLK_UART0:
2183 	case SCLK_UART1:
2184 	case SCLK_UART2:
2185 	case SCLK_UART3:
2186 	case SCLK_UART4:
2187 	case SCLK_UART5:
2188 	case SCLK_UART6:
2189 	case SCLK_UART7:
2190 	case SCLK_UART8:
2191 	case SCLK_UART9:
2192 	case SCLK_UART10:
2193 	case SCLK_UART11:
2194 		rate = rk3576_uart_get_rate(priv, clk->id);
2195 		break;
2196 	case CLK_DSIHOST0:
2197 		rate = rk3576_clk_csihost_get_clk(priv, clk->id);
2198 		break;
2199 	case DCLK_EBC:
2200 	case DCLK_EBC_FRAC_SRC:
2201 		rate = rk3576_dclk_ebc_get_clk(priv, clk->id);
2202 		break;
2203 	case REF_CLK0_OUT_PLL:
2204 	case REF_CLK1_OUT_PLL:
2205 	case REF_CLK2_OUT_PLL:
2206 		rate = rk3576_ref_clkout_get_clk(priv, clk->id);
2207 		break;
2208 #endif
2209 	case CLK_REF_UFS_CLKOUT:
2210 	case CLK_REF_OSC_MPHY:
2211 		rate = rk3576_ufs_ref_get_rate(priv, clk->id);
2212 		break;
2213 
2214 	default:
2215 		return -ENOENT;
2216 	}
2217 
2218 	return rate;
2219 };
2220 
rk3576_clk_set_rate(struct clk * clk,ulong rate)2221 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
2222 {
2223 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2224 	ulong ret = 0;
2225 
2226 	if (!priv->ppll_hz) {
2227 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2228 						      priv->cru, PPLL);
2229 	}
2230 	if (!priv->aupll_hz) {
2231 		priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2232 						      priv->cru, AUPLL);
2233 	}
2234 
2235 	switch (clk->id) {
2236 	case PLL_CPLL:
2237 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2238 					    CPLL, rate);
2239 		priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL],
2240 						      priv->cru, CPLL);
2241 		break;
2242 	case PLL_GPLL:
2243 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2244 					    GPLL, rate);
2245 		priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL],
2246 						      priv->cru, GPLL);
2247 		break;
2248 	case PLL_VPLL:
2249 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru,
2250 					    VPLL, rate);
2251 		priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL],
2252 						       priv->cru, VPLL);
2253 		break;
2254 	case PLL_AUPLL:
2255 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru,
2256 					    AUPLL, rate);
2257 		priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL],
2258 						       priv->cru, AUPLL);
2259 		break;
2260 	case PLL_PPLL:
2261 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru,
2262 					    PPLL, rate);
2263 		priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL],
2264 						      priv->cru, PPLL) * 2;
2265 		break;
2266 	case ACLK_BUS_ROOT:
2267 	case HCLK_BUS_ROOT:
2268 	case PCLK_BUS_ROOT:
2269 		ret = rk3576_bus_set_clk(priv, clk->id, rate);
2270 		break;
2271 	case ACLK_TOP:
2272 	case HCLK_TOP:
2273 	case PCLK_TOP_ROOT:
2274 	case ACLK_TOP_MID:
2275 		ret = rk3576_top_set_clk(priv, clk->id, rate);
2276 		break;
2277 	case CLK_I2C0:
2278 	case CLK_I2C1:
2279 	case CLK_I2C2:
2280 	case CLK_I2C3:
2281 	case CLK_I2C4:
2282 	case CLK_I2C5:
2283 	case CLK_I2C6:
2284 	case CLK_I2C7:
2285 	case CLK_I2C8:
2286 	case CLK_I2C9:
2287 		ret = rk3576_i2c_set_clk(priv, clk->id, rate);
2288 		break;
2289 	case CLK_SPI0:
2290 	case CLK_SPI1:
2291 	case CLK_SPI2:
2292 	case CLK_SPI3:
2293 	case CLK_SPI4:
2294 		ret = rk3576_spi_set_clk(priv, clk->id, rate);
2295 		break;
2296 	case CLK_PWM1:
2297 	case CLK_PWM2:
2298 	case CLK_PMU1PWM:
2299 		ret = rk3576_pwm_set_clk(priv, clk->id, rate);
2300 		break;
2301 	case CLK_SARADC:
2302 	case CLK_TSADC:
2303 		ret = rk3576_adc_set_clk(priv, clk->id, rate);
2304 		break;
2305 	case CCLK_SRC_SDIO:
2306 	case CCLK_SRC_SDMMC0:
2307 	case CCLK_SRC_EMMC:
2308 	case BCLK_EMMC:
2309 	case SCLK_FSPI_X2:
2310 	case SCLK_FSPI1_X2:
2311 	case DCLK_DECOM:
2312 	case HCLK_SDMMC0:
2313 	case HCLK_EMMC:
2314 	case HCLK_SDIO:
2315 		ret = rk3576_mmc_set_clk(priv, clk->id, rate);
2316 		break;
2317 	case TCLK_WDT0:
2318 		ret = OSC_HZ;
2319 		break;
2320 #ifndef CONFIG_SPL_BUILD
2321 	case ACLK_VOP_ROOT:
2322 	case ACLK_VOP:
2323 	case ACLK_VO0_ROOT:
2324 	case ACLK_VO1_ROOT:
2325 	case HCLK_VOP_ROOT:
2326 	case PCLK_VOP_ROOT:
2327 		ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate);
2328 		break;
2329 	case DCLK_VP0:
2330 	case DCLK_VP0_SRC:
2331 	case DCLK_VP1:
2332 	case DCLK_VP1_SRC:
2333 	case DCLK_VP2:
2334 	case DCLK_VP2_SRC:
2335 		ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate);
2336 		break;
2337 	case CLK_GMAC0_PTP_REF_SRC:
2338 	case CLK_GMAC1_PTP_REF_SRC:
2339 	case CLK_GMAC0_PTP_REF:
2340 	case CLK_GMAC1_PTP_REF:
2341 	case CLK_GMAC0_125M_SRC:
2342 	case CLK_GMAC1_125M_SRC:
2343 		ret = rk3576_gmac_set_clk(priv, clk->id, rate);
2344 		break;
2345 	case CLK_UART_FRAC_0:
2346 	case CLK_UART_FRAC_1:
2347 	case CLK_UART_FRAC_2:
2348 		ret = rk3576_uart_frac_set_rate(priv, clk->id, rate);
2349 		break;
2350 	case SCLK_UART0:
2351 	case SCLK_UART1:
2352 	case SCLK_UART2:
2353 	case SCLK_UART3:
2354 	case SCLK_UART4:
2355 	case SCLK_UART5:
2356 	case SCLK_UART6:
2357 	case SCLK_UART7:
2358 	case SCLK_UART8:
2359 	case SCLK_UART9:
2360 	case SCLK_UART10:
2361 	case SCLK_UART11:
2362 		ret = rk3576_uart_set_rate(priv, clk->id, rate);
2363 		break;
2364 	case CLK_DSIHOST0:
2365 		ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate);
2366 		break;
2367 	case DCLK_EBC:
2368 	case DCLK_EBC_FRAC_SRC:
2369 		ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate);
2370 		break;
2371 	case REF_CLK0_OUT_PLL:
2372 	case REF_CLK1_OUT_PLL:
2373 	case REF_CLK2_OUT_PLL:
2374 		ret = rk3576_ref_clkout_set_clk(priv, clk->id, rate);
2375 		break;
2376 #endif
2377 	default:
2378 		return -ENOENT;
2379 	}
2380 
2381 	return ret;
2382 };
2383 
2384 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
rk3576_dclk_vop_set_parent(struct clk * clk,struct clk * parent)2385 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk,
2386 						     struct clk *parent)
2387 {
2388 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2389 	struct rk3576_cru *cru = priv->cru;
2390 	u32 sel;
2391 	const char *clock_dev_name = parent->dev->name;
2392 
2393 	if (parent->id == PLL_VPLL)
2394 		sel = 2;
2395 	else if (parent->id == PLL_GPLL)
2396 		sel = 0;
2397 	else if (parent->id == PLL_CPLL)
2398 		sel = 1;
2399 	else if (parent->id == PLL_BPLL)
2400 		sel = 3;
2401 	else
2402 		sel = 4;
2403 
2404 	switch (clk->id) {
2405 	case DCLK_VP0_SRC:
2406 		rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK,
2407 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2408 		break;
2409 	case DCLK_VP1_SRC:
2410 		rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK,
2411 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2412 		break;
2413 	case DCLK_VP2_SRC:
2414 		rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK,
2415 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
2416 		break;
2417 	case DCLK_VP0:
2418 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2419 			sel = 1;
2420 		else
2421 			sel = 0;
2422 		rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK,
2423 			     sel << DCLK0_VOP_SEL_SHIFT);
2424 		break;
2425 	case DCLK_VP1:
2426 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2427 			sel = 1;
2428 		else
2429 			sel = 0;
2430 		rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK,
2431 			     sel << DCLK1_VOP_SEL_SHIFT);
2432 		break;
2433 	case DCLK_VP2:
2434 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2435 			sel = 1;
2436 		else
2437 			sel = 0;
2438 		rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK,
2439 			     sel << DCLK2_VOP_SEL_SHIFT);
2440 		break;
2441 	case DCLK_EBC:
2442 		if (parent->id == PLL_GPLL)
2443 			sel = 0;
2444 		else if (parent->id == PLL_CPLL)
2445 			sel = 1;
2446 		else if (parent->id == PLL_VPLL)
2447 			sel = 2;
2448 		else if (parent->id == PLL_AUPLL)
2449 			sel = 3;
2450 		else if (parent->id == PLL_LPLL)
2451 			sel = 4;
2452 		else if (parent->id == DCLK_EBC_FRAC_SRC)
2453 			sel = 5;
2454 		else
2455 			sel = 6;
2456 		rk_clrsetreg(&cru->clksel_con[123], DCLK_EBC_SEL_MASK,
2457 			     sel << DCLK_EBC_SEL_SHIFT);
2458 		break;
2459 	default:
2460 		return -EINVAL;
2461 	}
2462 	return 0;
2463 }
2464 
rk3576_ufs_ref_set_parent(struct clk * clk,struct clk * parent)2465 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk,
2466 						     struct clk *parent)
2467 {
2468 	struct rk3576_clk_priv *priv = dev_get_priv(clk->dev);
2469 	struct rk3576_cru *cru = priv->cru;
2470 	u32 sel;
2471 	const char *clock_dev_name = parent->dev->name;
2472 
2473 	if (parent->id == CLK_REF_MPHY_26M)
2474 		sel = 2;
2475 	else if (!strcmp(clock_dev_name, "xin24m"))
2476 		sel = 0;
2477 	else
2478 		sel = 1;
2479 
2480 	rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0);
2481 	return 0;
2482 }
2483 
rk3576_clk_set_parent(struct clk * clk,struct clk * parent)2484 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent)
2485 {
2486 	switch (clk->id) {
2487 	case DCLK_VP0_SRC:
2488 	case DCLK_VP1_SRC:
2489 	case DCLK_VP2_SRC:
2490 	case DCLK_VP0:
2491 	case DCLK_VP1:
2492 	case DCLK_VP2:
2493 	case DCLK_EBC:
2494 		return rk3576_dclk_vop_set_parent(clk, parent);
2495 	case CLK_REF_OSC_MPHY:
2496 		return rk3576_ufs_ref_set_parent(clk, parent);
2497 
2498 	default:
2499 		return -ENOENT;
2500 	}
2501 
2502 	return 0;
2503 }
2504 #endif
2505 
2506 static struct clk_ops rk3576_clk_ops = {
2507 	.get_rate = rk3576_clk_get_rate,
2508 	.set_rate = rk3576_clk_set_rate,
2509 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2510 	.set_parent = rk3576_clk_set_parent,
2511 #endif
2512 };
2513 
rk3576_clk_init(struct rk3576_clk_priv * priv)2514 static void rk3576_clk_init(struct rk3576_clk_priv *priv)
2515 {
2516 	int ret;
2517 
2518 	priv->spll_hz = 702000000;
2519 
2520 	if (priv->cpll_hz != CPLL_HZ) {
2521 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru,
2522 					    CPLL, CPLL_HZ);
2523 		if (!ret)
2524 			priv->cpll_hz = CPLL_HZ;
2525 	}
2526 	if (priv->gpll_hz != GPLL_HZ) {
2527 		ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru,
2528 					    GPLL, GPLL_HZ);
2529 		if (!ret)
2530 			priv->gpll_hz = GPLL_HZ;
2531 	}
2532 	rk_clrsetreg(&priv->cru->clksel_con[123],
2533 		     DCLK_EBC_FRAC_SRC_SEL_MASK,
2534 		     (DCLK_EBC_FRAC_SRC_SEL_GPLL <<
2535 		      DCLK_EBC_FRAC_SRC_SEL_SHIFT));
2536 }
2537 
rk3576_clk_probe(struct udevice * dev)2538 static int rk3576_clk_probe(struct udevice *dev)
2539 {
2540 	struct rk3576_clk_priv *priv = dev_get_priv(dev);
2541 	int ret;
2542 #if CONFIG_IS_ENABLED(CLK_SCMI)
2543 	struct clk clk;
2544 #endif
2545 
2546 	priv->sync_kernel = false;
2547 
2548 #ifdef CONFIG_SPL_BUILD
2549 	/* relase presetn_bigcore_biu/cru/grf */
2550 	writel(0x1c001c00, 0x26010010);
2551 	/* set spll to normal mode */
2552 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2553 	       RK3576_SCRU_BASE + RK3576_PLL_CON(137));
2554 	writel(BITS_WITH_WMASK(1, 0x3U, 0),
2555 	       RK3576_SCRU_BASE + RK3576_MODE_CON0);
2556 	/* fix ppll\aupll\cpll */
2557 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2558 	       RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129));
2559 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2560 	       RK3576_CRU_BASE + RK3576_PLL_CON(97));
2561 	writel(BITS_WITH_WMASK(2, 0x7U, 6),
2562 	       RK3576_CRU_BASE + RK3576_PLL_CON(105));
2563 	writel(BITS_WITH_WMASK(1, 0x3U, 6),
2564 	       RK3576_CRU_BASE + RK3576_MODE_CON0);
2565 	writel(BITS_WITH_WMASK(1, 0x3U, 8),
2566 	       RK3576_CRU_BASE + RK3576_MODE_CON0);
2567 	if (!(readl(RK3576_CRU_BASE + RK3576_LITCORE_CLKSEL_CON(0)) & CLK_LITCORE_SEL_MASK)) {
2568 		/* init cci */
2569 		writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2570 		if (!priv->armclk_enter_hz) {
2571 			ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru,
2572 						    LPLL, LPLL_HZ);
2573 			priv->armclk_enter_hz =
2574 				rockchip_pll_get_rate(&rk3576_pll_clks[LPLL],
2575 						      priv->cru, LPLL);
2576 			priv->armclk_init_hz = priv->armclk_enter_hz;
2577 			rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK,
2578 				     0 << CLK_LITCORE_DIV_SHIFT);
2579 		}
2580 		/* init cci */
2581 		writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4));
2582 
2583 	}
2584 	if (!(readl(RK3576_CRU_BASE + RK3576_BIGCORE_CLKSEL_CON(0)) & CLK_BIGCORE_SEL_MASK)) {
2585 		rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru,
2586 		      BPLL, LPLL_HZ);
2587 		/* Change bigcore rm from 4 to 3 */
2588 		writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c);
2589 		writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44);
2590 		writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38);
2591 		udelay(1);
2592 		writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38);
2593 	}
2594 #endif
2595 
2596 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2597 	if (IS_ERR(priv->grf))
2598 		return PTR_ERR(priv->grf);
2599 
2600 	rk3576_clk_init(priv);
2601 
2602 #if CONFIG_IS_ENABLED(CLK_SCMI)
2603 #ifndef CONFIG_SPL_BUILD
2604 	ret = rockchip_get_scmi_clk(&clk.dev);
2605 	if (ret) {
2606 		printf("Failed to get scmi clk dev, ret=%d\n", ret);
2607 		return ret;
2608 	}
2609 	if (!priv->armclk_enter_hz) {
2610 		clk.id = ARMCLK_L;
2611 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2612 		if (ret < 0) {
2613 			printf("Failed to set cpubl, ret=%d\n", ret);
2614 		} else {
2615 			priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2616 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
2617 		}
2618 	}
2619 	clk.id = ARMCLK_B;
2620 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2621 	if (ret < 0)
2622 		printf("Failed to set cpub, ret=%d\n", ret);
2623 #endif
2624 #endif
2625 
2626 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2627 	ret = clk_set_defaults(dev);
2628 	if (ret)
2629 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2630 	else
2631 		priv->sync_kernel = true;
2632 
2633 	return 0;
2634 }
2635 
rk3576_clk_ofdata_to_platdata(struct udevice * dev)2636 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev)
2637 {
2638 	struct rk3576_clk_priv *priv = dev_get_priv(dev);
2639 
2640 	priv->cru = dev_read_addr_ptr(dev);
2641 
2642 	return 0;
2643 }
2644 
rk3576_clk_bind(struct udevice * dev)2645 static int rk3576_clk_bind(struct udevice *dev)
2646 {
2647 	int ret;
2648 	struct udevice *sys_child, *sf_child;
2649 	struct sysreset_reg *priv;
2650 	struct softreset_reg *sf_priv;
2651 
2652 	/* The reset driver does not have a device node, so bind it here */
2653 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2654 				 &sys_child);
2655 	if (ret) {
2656 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2657 	} else {
2658 		priv = malloc(sizeof(struct sysreset_reg));
2659 		priv->glb_srst_fst_value = offsetof(struct rk3576_cru,
2660 						    glb_srst_fst);
2661 		priv->glb_srst_snd_value = offsetof(struct rk3576_cru,
2662 						    glb_srsr_snd);
2663 		sys_child->priv = priv;
2664 	}
2665 
2666 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2667 					 dev_ofnode(dev), &sf_child);
2668 	if (ret) {
2669 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2670 	} else {
2671 		sf_priv = malloc(sizeof(struct softreset_reg));
2672 		sf_priv->sf_reset_offset = offsetof(struct rk3576_cru,
2673 						    softrst_con[0]);
2674 		sf_priv->sf_reset_num = 524454;
2675 		sf_child->priv = sf_priv;
2676 	}
2677 
2678 	return 0;
2679 }
2680 
2681 static const struct udevice_id rk3576_clk_ids[] = {
2682 	{ .compatible = "rockchip,rk3576-cru" },
2683 	{ }
2684 };
2685 
2686 U_BOOT_DRIVER(rockchip_rk3576_cru) = {
2687 	.name		= "rockchip_rk3576_cru",
2688 	.id		= UCLASS_CLK,
2689 	.of_match	= rk3576_clk_ids,
2690 	.priv_auto_alloc_size = sizeof(struct rk3576_clk_priv),
2691 	.ofdata_to_platdata = rk3576_clk_ofdata_to_platdata,
2692 	.ops		= &rk3576_clk_ops,
2693 	.bind		= rk3576_clk_bind,
2694 	.probe		= rk3576_clk_probe,
2695 };
2696 
2697 #ifndef CONFIG_SPL_BUILD
2698 /**
2699  * soc_clk_dump() - Print clock frequencies
2700  * Returns zero on success
2701  *
2702  * Implementation for the clk dump command.
2703  */
soc_clk_dump(void)2704 int soc_clk_dump(void)
2705 {
2706 	struct udevice *cru_dev;
2707 	struct rk3576_clk_priv *priv;
2708 	const struct rk3576_clk_info *clk_dump;
2709 	struct clk clk;
2710 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2711 	unsigned long rate;
2712 	int i, ret;
2713 
2714 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2715 					  DM_GET_DRIVER(rockchip_rk3576_cru),
2716 					  &cru_dev);
2717 	if (ret) {
2718 		printf("%s failed to get cru device\n", __func__);
2719 		return ret;
2720 	}
2721 
2722 	priv = dev_get_priv(cru_dev);
2723 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2724 	       priv->sync_kernel ? "sync kernel" : "uboot",
2725 	       priv->armclk_enter_hz / 1000,
2726 	       priv->armclk_init_hz / 1000,
2727 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2728 	       priv->set_armclk_rate ? " KHz" : "N/A");
2729 	for (i = 0; i < clk_count; i++) {
2730 		clk_dump = &clks_dump[i];
2731 		if (clk_dump->name) {
2732 			memset(&clk, 0, sizeof(struct clk));
2733 			clk.id = clk_dump->id;
2734 			if (clk_dump->is_cru)
2735 				ret = clk_request(cru_dev, &clk);
2736 			if (ret < 0)
2737 				return ret;
2738 
2739 			rate = clk_get_rate(&clk);
2740 			clk_free(&clk);
2741 			if (rate < 0)
2742 				printf("  %s %s\n", clk_dump->name,
2743 				       "unknown");
2744 			else
2745 				printf("  %s %lu KHz\n", clk_dump->name,
2746 				       rate / 1000);
2747 		}
2748 	}
2749 
2750 	return 0;
2751 }
2752 #endif
2753