1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2021 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-rockchip/cru_rk3568.h>
14#include <asm/arch-rockchip/clock.h>
15#include <asm/arch-rockchip/hardware.h>
16#include <dm/device-internal.h>
17#include <dm/lists.h>
18#include <dt-bindings/clock/rk3568-cru.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21
22#if CONFIG_IS_ENABLED(OF_PLATDATA)
23struct rk3568_clk_plat {
24	struct dtd_rockchip_rk3568_cru dtd;
25};
26
27struct rk3568_pmuclk_plat {
28	struct dtd_rockchip_rk3568_pmucru dtd;
29};
30#endif
31
32#define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
33{								\
34	.rate	= _rate##U,					\
35	.aclk_div = _aclk_div,					\
36	.pclk_div = _pclk_div,					\
37}
38
39#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
40
41static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = {
42	RK3568_CPUCLK_RATE(1416000000, 1, 5),
43	RK3568_CPUCLK_RATE(1296000000, 1, 5),
44	RK3568_CPUCLK_RATE(1200000000, 1, 3),
45	RK3568_CPUCLK_RATE(1104000000, 1, 3),
46	RK3568_CPUCLK_RATE(1008000000, 1, 3),
47	RK3568_CPUCLK_RATE(912000000, 1, 3),
48	RK3568_CPUCLK_RATE(816000000, 1, 3),
49	RK3568_CPUCLK_RATE(600000000, 1, 1),
50	RK3568_CPUCLK_RATE(408000000, 1, 1),
51	{ /* sentinel */ },
52};
53
54static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
55	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
56	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
57	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
58	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
59	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
60	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
61	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
62	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
63	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
64	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
65	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
66	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
67	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
68	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
69	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
70	RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
71	RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
72	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
73	{ /* sentinel */ },
74};
75
76static struct rockchip_pll_clock rk3568_pll_clks[] = {
77	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0),
78		     RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates),
79	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8),
80		     RK3568_MODE_CON, 2, 10, 0, NULL),
81	[CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24),
82		     RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates),
83	[GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16),
84		     RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates),
85	[NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32),
86		     RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates),
87	[VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40),
88		     RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates),
89	[PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0),
90		     RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates),
91	[HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16),
92		     RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates),
93};
94
95#ifndef CONFIG_SPL_BUILD
96static ulong
97rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
98			ulong pll_id, ulong rate)
99{
100	struct udevice *pmucru_dev;
101	struct rk3568_pmuclk_priv *pmu_priv;
102	int ret;
103
104	ret = uclass_get_device_by_driver(UCLASS_CLK,
105					  DM_DRIVER_GET(rockchip_rk3568_pmucru),
106					  &pmucru_dev);
107	if (ret) {
108		printf("%s: could not find pmucru device\n", __func__);
109		return ret;
110	}
111	pmu_priv = dev_get_priv(pmucru_dev);
112
113	rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
114			      pmu_priv->pmucru, pll_id, rate);
115
116	return 0;
117}
118#endif
119
120static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
121				     ulong pll_id)
122{
123	struct udevice *pmucru_dev;
124	struct rk3568_pmuclk_priv *pmu_priv;
125	int ret;
126
127	ret = uclass_get_device_by_driver(UCLASS_CLK,
128					  DM_DRIVER_GET(rockchip_rk3568_pmucru),
129					  &pmucru_dev);
130	if (ret) {
131		printf("%s: could not find pmucru device\n", __func__);
132		return ret;
133	}
134	pmu_priv = dev_get_priv(pmucru_dev);
135
136	return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
137				      pmu_priv->pmucru, pll_id);
138}
139
140/*
141 *
142 * rational_best_approximation(31415, 10000,
143 *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
144 *
145 * you may look at given_numerator as a fixed point number,
146 * with the fractional part size described in given_denominator.
147 *
148 * for theoretical background, see:
149 * http://en.wikipedia.org/wiki/Continued_fraction
150 */
151static void rational_best_approximation(unsigned long given_numerator,
152					unsigned long given_denominator,
153					unsigned long max_numerator,
154					unsigned long max_denominator,
155					unsigned long *best_numerator,
156					unsigned long *best_denominator)
157{
158	unsigned long n, d, n0, d0, n1, d1;
159
160	n = given_numerator;
161	d = given_denominator;
162	n0 = 0;
163	d1 = 0;
164	n1 = 1;
165	d0 = 1;
166	for (;;) {
167		unsigned long t, a;
168
169		if (n1 > max_numerator || d1 > max_denominator) {
170			n1 = n0;
171			d1 = d0;
172			break;
173		}
174		if (d == 0)
175			break;
176		t = d;
177		a = n / d;
178		d = n % d;
179		n = t;
180		t = n0 + a * n1;
181		n0 = n1;
182		n1 = t;
183		t = d0 + a * d1;
184		d0 = d1;
185		d1 = t;
186	}
187	*best_numerator = n1;
188	*best_denominator = d1;
189}
190
191static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
192{
193	struct rk3568_pmucru *pmucru = priv->pmucru;
194	unsigned long m, n;
195	u32 fracdiv;
196
197	fracdiv = readl(&pmucru->pmu_clksel_con[1]);
198	m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
199	m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
200	n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
201	n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
202
203	return OSC_HZ * m / n;
204}
205
206static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
207				      ulong rate)
208{
209	struct rk3568_pmucru *pmucru = priv->pmucru;
210	unsigned long m, n, val;
211
212	rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
213		     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
214
215	rational_best_approximation(rate, OSC_HZ,
216				    GENMASK(16 - 1, 0),
217				    GENMASK(16 - 1, 0),
218				    &m, &n);
219	val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
220	writel(val, &pmucru->pmu_clksel_con[1]);
221
222	return rk3568_rtc32k_get_pmuclk(priv);
223}
224
225static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
226				   ulong clk_id)
227{
228	struct rk3568_pmucru *pmucru = priv->pmucru;
229	u32 div, con;
230
231	switch (clk_id) {
232	case CLK_I2C0:
233		con = readl(&pmucru->pmu_clksel_con[3]);
234		div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
235		break;
236	default:
237		return -ENOENT;
238	}
239
240	return DIV_TO_RATE(priv->ppll_hz, div);
241}
242
243static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
244				   ulong clk_id, ulong rate)
245{
246	struct rk3568_pmucru *pmucru = priv->pmucru;
247	int src_clk_div;
248
249	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
250	assert(src_clk_div - 1 <= 127);
251
252	switch (clk_id) {
253	case CLK_I2C0:
254		rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
255			     (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
256		break;
257	default:
258		return -ENOENT;
259	}
260
261	return rk3568_i2c_get_pmuclk(priv, clk_id);
262}
263
264static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
265				   ulong clk_id)
266{
267	struct rk3568_pmucru *pmucru = priv->pmucru;
268	u32 div, sel, con, parent;
269
270	switch (clk_id) {
271	case CLK_PWM0:
272		con = readl(&pmucru->pmu_clksel_con[6]);
273		sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
274		div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
275		if (sel == CLK_PWM0_SEL_XIN24M)
276			parent = OSC_HZ;
277		else
278			parent = priv->ppll_hz;
279		break;
280	default:
281		return -ENOENT;
282	}
283
284	return DIV_TO_RATE(parent, div);
285}
286
287static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
288				   ulong clk_id, ulong rate)
289{
290	struct rk3568_pmucru *pmucru = priv->pmucru;
291	int src_clk_div;
292
293	switch (clk_id) {
294	case CLK_PWM0:
295		if (rate == OSC_HZ) {
296			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
297				     CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
298				     (CLK_PWM0_SEL_XIN24M <<
299				      CLK_PWM0_SEL_SHIFT) |
300				     0 << CLK_PWM0_SEL_SHIFT);
301		} else {
302			src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
303			assert(src_clk_div - 1 <= 127);
304			rk_clrsetreg(&pmucru->pmu_clksel_con[6],
305				     CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
306				     (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) |
307				     (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
308		}
309		break;
310	default:
311		return -ENOENT;
312	}
313
314	return rk3568_pwm_get_pmuclk(priv, clk_id);
315}
316
317static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
318{
319	struct rk3568_pmucru *pmucru = priv->pmucru;
320	u32 div, con, sel, parent;
321
322	con = readl(&pmucru->pmu_clksel_con[2]);
323	sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
324	div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
325	if (sel)
326		parent = GPLL_HZ;
327	else
328		parent = priv->ppll_hz;
329
330	return DIV_TO_RATE(parent, div);
331}
332
333static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
334				   ulong rate)
335{
336	struct rk3568_pmucru *pmucru = priv->pmucru;
337	int src_clk_div;
338
339	src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
340	assert(src_clk_div - 1 <= 31);
341
342	rk_clrsetreg(&pmucru->pmu_clksel_con[2],
343		     PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
344		     (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) |
345		     ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
346
347	return rk3568_pmu_get_pmuclk(priv);
348}
349
350static ulong rk3568_pmuclk_get_rate(struct clk *clk)
351{
352	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
353	ulong rate = 0;
354
355	if (!priv->ppll_hz) {
356		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
357		return -ENOENT;
358	}
359
360	debug("%s %ld\n", __func__, clk->id);
361	switch (clk->id) {
362	case PLL_PPLL:
363		rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
364					     priv->pmucru, PPLL);
365		break;
366	case PLL_HPLL:
367		rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
368					     priv->pmucru, HPLL);
369		break;
370	case CLK_RTC_32K:
371	case CLK_RTC32K_FRAC:
372		rate = rk3568_rtc32k_get_pmuclk(priv);
373		break;
374	case CLK_I2C0:
375		rate = rk3568_i2c_get_pmuclk(priv, clk->id);
376		break;
377	case CLK_PWM0:
378		rate = rk3568_pwm_get_pmuclk(priv, clk->id);
379		break;
380	case PCLK_PMU:
381		rate = rk3568_pmu_get_pmuclk(priv);
382		break;
383	default:
384		return -ENOENT;
385	}
386
387	return rate;
388}
389
390static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
391{
392	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
393	ulong ret = 0;
394
395	if (!priv->ppll_hz) {
396		printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
397		return -ENOENT;
398	}
399
400	debug("%s %ld %ld\n", __func__, clk->id, rate);
401	switch (clk->id) {
402	case PLL_PPLL:
403		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
404					    priv->pmucru, PPLL, rate);
405		priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
406						      priv->pmucru, PPLL);
407		break;
408	case PLL_HPLL:
409		ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL],
410					    priv->pmucru, HPLL, rate);
411		priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
412						      priv->pmucru, HPLL);
413		break;
414	case CLK_RTC_32K:
415	case CLK_RTC32K_FRAC:
416		ret = rk3568_rtc32k_set_pmuclk(priv, rate);
417		break;
418	case CLK_I2C0:
419		ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
420		break;
421	case CLK_PWM0:
422		ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
423		break;
424	case PCLK_PMU:
425		ret = rk3568_pmu_set_pmuclk(priv, rate);
426		break;
427	case CLK_PCIEPHY0_REF:
428	case CLK_PCIEPHY1_REF:
429	case CLK_PCIEPHY2_REF:
430		return 0;
431	default:
432		return -ENOENT;
433	}
434
435	return ret;
436}
437
438static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
439{
440	struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
441	struct rk3568_pmucru *pmucru = priv->pmucru;
442
443	if (parent->id == CLK_RTC32K_FRAC)
444		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
445			     RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
446	else
447		rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
448			     RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
449
450	return 0;
451}
452
453static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
454{
455	switch (clk->id) {
456	case CLK_RTC_32K:
457		return rk3568_rtc32k_set_parent(clk, parent);
458	default:
459		return -ENOENT;
460	}
461}
462
463static struct clk_ops rk3568_pmuclk_ops = {
464	.get_rate = rk3568_pmuclk_get_rate,
465	.set_rate = rk3568_pmuclk_set_rate,
466	.set_parent = rk3568_pmuclk_set_parent,
467};
468
469static int rk3568_pmuclk_probe(struct udevice *dev)
470{
471	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
472	int ret = 0;
473
474	if (priv->ppll_hz != PPLL_HZ) {
475		ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
476					    priv->pmucru,
477					    PPLL, PPLL_HZ);
478		if (!ret)
479			priv->ppll_hz = PPLL_HZ;
480	}
481
482	/* Ungate PCIe30phy refclk_m and refclk_n */
483	rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
484	return 0;
485}
486
487static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
488{
489	struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
490
491	priv->pmucru = dev_read_addr_ptr(dev);
492
493	return 0;
494}
495
496static int rk3568_pmuclk_bind(struct udevice *dev)
497{
498#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
499	int ret = 0;
500
501	ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]);
502	ret = rockchip_reset_bind(dev, ret, 1);
503	if (ret)
504		debug("Warning: pmucru software reset driver bind failed\n");
505#endif
506
507	return 0;
508}
509
510static const struct udevice_id rk3568_pmuclk_ids[] = {
511	{ .compatible = "rockchip,rk3568-pmucru" },
512	{ }
513};
514
515U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
516	.name		= "rockchip_rk3568_pmucru",
517	.id		= UCLASS_CLK,
518	.of_match	= rk3568_pmuclk_ids,
519	.priv_auto = sizeof(struct rk3568_pmuclk_priv),
520	.of_to_plat = rk3568_pmuclk_ofdata_to_platdata,
521	.ops		= &rk3568_pmuclk_ops,
522	.bind		= rk3568_pmuclk_bind,
523	.probe		= rk3568_pmuclk_probe,
524#if CONFIG_IS_ENABLED(OF_PLATDATA)
525	.plat_auto	= sizeof(struct rk3568_pmuclk_plat),
526#endif
527
528};
529
530static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
531{
532	struct rk3568_cru *cru = priv->cru;
533	const struct rockchip_cpu_rate_table *rate;
534	ulong old_rate;
535
536	rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
537	if (!rate) {
538		printf("%s unsupported rate\n", __func__);
539		return -EINVAL;
540	}
541
542	rk_clrsetreg(&cru->clksel_con[0],
543		     CLK_CORE_PRE_SEL_MASK,
544		     (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
545	rk_clrsetreg(&cru->clksel_con[2],
546		     SCLK_CORE_PRE_SEL_MASK |
547		     SCLK_CORE_SRC_SEL_MASK |
548		     SCLK_CORE_SRC_DIV_MASK,
549		     (SCLK_CORE_PRE_SEL_SRC <<
550		      SCLK_CORE_PRE_SEL_SHIFT) |
551		     (SCLK_CORE_SRC_SEL_APLL <<
552		      SCLK_CORE_SRC_SEL_SHIFT) |
553		     (1 << SCLK_CORE_SRC_DIV_SHIFT));
554
555	/*
556	 * set up dependent divisors for DBG and ACLK clocks.
557	 */
558	old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
559					 priv->cru, APLL);
560	if (old_rate > hz) {
561		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
562					  priv->cru, APLL, hz))
563			return -EINVAL;
564		rk_clrsetreg(&cru->clksel_con[3],
565			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
566			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
567			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
568		rk_clrsetreg(&cru->clksel_con[4],
569			     PERIPHCLK_CORE_PRE_DIV_MASK |
570			     PCLK_CORE_PRE_DIV_MASK,
571			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
572			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
573		rk_clrsetreg(&cru->clksel_con[5],
574			     ACLK_CORE_NDFT_DIV_MASK,
575			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
576	} else if (old_rate < hz) {
577		rk_clrsetreg(&cru->clksel_con[3],
578			     GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
579			     rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
580			     rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
581		rk_clrsetreg(&cru->clksel_con[4],
582			     PERIPHCLK_CORE_PRE_DIV_MASK |
583			     PCLK_CORE_PRE_DIV_MASK,
584			     rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
585			     rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
586		rk_clrsetreg(&cru->clksel_con[5],
587			     ACLK_CORE_NDFT_DIV_MASK,
588			     rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
589		if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
590					  priv->cru, APLL, hz))
591			return -EINVAL;
592	}
593
594	return 0;
595}
596
597static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
598				      ulong clk_id)
599{
600	struct rk3568_cru *cru = priv->cru;
601	int div, mask, shift, con;
602
603	switch (clk_id) {
604	case CPLL_500M:
605		con = 78;
606		mask = CPLL_500M_DIV_MASK;
607		shift = CPLL_500M_DIV_SHIFT;
608		break;
609	case CPLL_333M:
610		con = 79;
611		mask = CPLL_333M_DIV_MASK;
612		shift = CPLL_333M_DIV_SHIFT;
613		break;
614	case CPLL_250M:
615		con = 79;
616		mask = CPLL_250M_DIV_MASK;
617		shift = CPLL_250M_DIV_SHIFT;
618		break;
619	case CPLL_125M:
620		con = 80;
621		mask = CPLL_125M_DIV_MASK;
622		shift = CPLL_125M_DIV_SHIFT;
623		break;
624	case CPLL_100M:
625		con = 82;
626		mask = CPLL_100M_DIV_MASK;
627		shift = CPLL_100M_DIV_SHIFT;
628		break;
629	case CPLL_62P5M:
630		con = 80;
631		mask = CPLL_62P5M_DIV_MASK;
632		shift = CPLL_62P5M_DIV_SHIFT;
633		break;
634	case CPLL_50M:
635		con = 81;
636		mask = CPLL_50M_DIV_MASK;
637		shift = CPLL_50M_DIV_SHIFT;
638		break;
639	case CPLL_25M:
640		con = 81;
641		mask = CPLL_25M_DIV_MASK;
642		shift = CPLL_25M_DIV_SHIFT;
643		break;
644	default:
645		return -ENOENT;
646	}
647
648	div = (readl(&cru->clksel_con[con]) & mask) >> shift;
649	return DIV_TO_RATE(priv->cpll_hz, div);
650}
651
652static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
653				      ulong clk_id, ulong rate)
654{
655	struct rk3568_cru *cru = priv->cru;
656	int div, mask, shift, con;
657
658	switch (clk_id) {
659	case CPLL_500M:
660		con = 78;
661		mask = CPLL_500M_DIV_MASK;
662		shift = CPLL_500M_DIV_SHIFT;
663		break;
664	case CPLL_333M:
665		con = 79;
666		mask = CPLL_333M_DIV_MASK;
667		shift = CPLL_333M_DIV_SHIFT;
668		break;
669	case CPLL_250M:
670		con = 79;
671		mask = CPLL_250M_DIV_MASK;
672		shift = CPLL_250M_DIV_SHIFT;
673		break;
674	case CPLL_125M:
675		con = 80;
676		mask = CPLL_125M_DIV_MASK;
677		shift = CPLL_125M_DIV_SHIFT;
678		break;
679	case CPLL_100M:
680		con = 82;
681		mask = CPLL_100M_DIV_MASK;
682		shift = CPLL_100M_DIV_SHIFT;
683		break;
684	case CPLL_62P5M:
685		con = 80;
686		mask = CPLL_62P5M_DIV_MASK;
687		shift = CPLL_62P5M_DIV_SHIFT;
688		break;
689	case CPLL_50M:
690		con = 81;
691		mask = CPLL_50M_DIV_MASK;
692		shift = CPLL_50M_DIV_SHIFT;
693		break;
694	case CPLL_25M:
695		con = 81;
696		mask = CPLL_25M_DIV_MASK;
697		shift = CPLL_25M_DIV_SHIFT;
698		break;
699	default:
700		return -ENOENT;
701	}
702
703	div = DIV_ROUND_UP(priv->cpll_hz, rate);
704	if (clk_id == CPLL_25M)
705		assert(div - 1 <= 63);
706	else
707		assert(div - 1 <= 31);
708	rk_clrsetreg(&cru->clksel_con[con],
709		     mask, (div - 1) << shift);
710	return rk3568_cpll_div_get_rate(priv, clk_id);
711}
712
713static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
714{
715	struct rk3568_cru *cru = priv->cru;
716	u32 con, sel, rate;
717
718	switch (clk_id) {
719	case ACLK_BUS:
720		con = readl(&cru->clksel_con[50]);
721		sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
722		if (sel == ACLK_BUS_SEL_200M)
723			rate = 200 * MHz;
724		else if (sel == ACLK_BUS_SEL_150M)
725			rate = 150 * MHz;
726		else if (sel == ACLK_BUS_SEL_100M)
727			rate = 100 * MHz;
728		else
729			rate = OSC_HZ;
730		break;
731	case PCLK_BUS:
732	case PCLK_WDT_NS:
733		con = readl(&cru->clksel_con[50]);
734		sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
735		if (sel == PCLK_BUS_SEL_100M)
736			rate = 100 * MHz;
737		else if (sel == PCLK_BUS_SEL_75M)
738			rate = 75 * MHz;
739		else if (sel == PCLK_BUS_SEL_50M)
740			rate = 50 * MHz;
741		else
742			rate = OSC_HZ;
743		break;
744	default:
745		return -ENOENT;
746	}
747
748	return rate;
749}
750
751static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
752				ulong clk_id, ulong rate)
753{
754	struct rk3568_cru *cru = priv->cru;
755	int src_clk;
756
757	switch (clk_id) {
758	case ACLK_BUS:
759		if (rate == 200 * MHz)
760			src_clk = ACLK_BUS_SEL_200M;
761		else if (rate == 150 * MHz)
762			src_clk = ACLK_BUS_SEL_150M;
763		else if (rate == 100 * MHz)
764			src_clk = ACLK_BUS_SEL_100M;
765		else
766			src_clk = ACLK_BUS_SEL_24M;
767		rk_clrsetreg(&cru->clksel_con[50],
768			     ACLK_BUS_SEL_MASK,
769			     src_clk << ACLK_BUS_SEL_SHIFT);
770		break;
771	case PCLK_BUS:
772	case PCLK_WDT_NS:
773		if (rate == 100 * MHz)
774			src_clk = PCLK_BUS_SEL_100M;
775		else if (rate == 75 * MHz)
776			src_clk = PCLK_BUS_SEL_75M;
777		else if (rate == 50 * MHz)
778			src_clk = PCLK_BUS_SEL_50M;
779		else
780			src_clk = PCLK_BUS_SEL_24M;
781		rk_clrsetreg(&cru->clksel_con[50],
782			     PCLK_BUS_SEL_MASK,
783			     src_clk << PCLK_BUS_SEL_SHIFT);
784		break;
785
786	default:
787		printf("do not support this bus freq\n");
788		return -EINVAL;
789	}
790
791	return rk3568_bus_get_clk(priv, clk_id);
792}
793
794static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
795{
796	struct rk3568_cru *cru = priv->cru;
797	u32 con, sel, rate;
798
799	switch (clk_id) {
800	case ACLK_PERIMID:
801		con = readl(&cru->clksel_con[10]);
802		sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
803		if (sel == ACLK_PERIMID_SEL_300M)
804			rate = 300 * MHz;
805		else if (sel == ACLK_PERIMID_SEL_200M)
806			rate = 200 * MHz;
807		else if (sel == ACLK_PERIMID_SEL_100M)
808			rate = 100 * MHz;
809		else
810			rate = OSC_HZ;
811		break;
812	case HCLK_PERIMID:
813		con = readl(&cru->clksel_con[10]);
814		sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
815		if (sel == HCLK_PERIMID_SEL_150M)
816			rate = 150 * MHz;
817		else if (sel == HCLK_PERIMID_SEL_100M)
818			rate = 100 * MHz;
819		else if (sel == HCLK_PERIMID_SEL_75M)
820			rate = 75 * MHz;
821		else
822			rate = OSC_HZ;
823		break;
824	default:
825		return -ENOENT;
826	}
827
828	return rate;
829}
830
831static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
832				    ulong clk_id, ulong rate)
833{
834	struct rk3568_cru *cru = priv->cru;
835	int src_clk;
836
837	switch (clk_id) {
838	case ACLK_PERIMID:
839		if (rate == 300 * MHz)
840			src_clk = ACLK_PERIMID_SEL_300M;
841		else if (rate == 200 * MHz)
842			src_clk = ACLK_PERIMID_SEL_200M;
843		else if (rate == 100 * MHz)
844			src_clk = ACLK_PERIMID_SEL_100M;
845		else
846			src_clk = ACLK_PERIMID_SEL_24M;
847		rk_clrsetreg(&cru->clksel_con[10],
848			     ACLK_PERIMID_SEL_MASK,
849			     src_clk << ACLK_PERIMID_SEL_SHIFT);
850		break;
851	case HCLK_PERIMID:
852		if (rate == 150 * MHz)
853			src_clk = HCLK_PERIMID_SEL_150M;
854		else if (rate == 100 * MHz)
855			src_clk = HCLK_PERIMID_SEL_100M;
856		else if (rate == 75 * MHz)
857			src_clk = HCLK_PERIMID_SEL_75M;
858		else
859			src_clk = HCLK_PERIMID_SEL_24M;
860		rk_clrsetreg(&cru->clksel_con[10],
861			     HCLK_PERIMID_SEL_MASK,
862			     src_clk << HCLK_PERIMID_SEL_SHIFT);
863		break;
864
865	default:
866		printf("do not support this permid freq\n");
867		return -EINVAL;
868	}
869
870	return rk3568_perimid_get_clk(priv, clk_id);
871}
872
873static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
874{
875	struct rk3568_cru *cru = priv->cru;
876	u32 con, sel, rate;
877
878	switch (clk_id) {
879	case ACLK_TOP_HIGH:
880		con = readl(&cru->clksel_con[73]);
881		sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
882		if (sel == ACLK_TOP_HIGH_SEL_500M)
883			rate = 500 * MHz;
884		else if (sel == ACLK_TOP_HIGH_SEL_400M)
885			rate = 400 * MHz;
886		else if (sel == ACLK_TOP_HIGH_SEL_300M)
887			rate = 300 * MHz;
888		else
889			rate = OSC_HZ;
890		break;
891	case ACLK_TOP_LOW:
892		con = readl(&cru->clksel_con[73]);
893		sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
894		if (sel == ACLK_TOP_LOW_SEL_400M)
895			rate = 400 * MHz;
896		else if (sel == ACLK_TOP_LOW_SEL_300M)
897			rate = 300 * MHz;
898		else if (sel == ACLK_TOP_LOW_SEL_200M)
899			rate = 200 * MHz;
900		else
901			rate = OSC_HZ;
902		break;
903	case HCLK_TOP:
904		con = readl(&cru->clksel_con[73]);
905		sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
906		if (sel == HCLK_TOP_SEL_150M)
907			rate = 150 * MHz;
908		else if (sel == HCLK_TOP_SEL_100M)
909			rate = 100 * MHz;
910		else if (sel == HCLK_TOP_SEL_75M)
911			rate = 75 * MHz;
912		else
913			rate = OSC_HZ;
914		break;
915	case PCLK_TOP:
916		con = readl(&cru->clksel_con[73]);
917		sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
918		if (sel == PCLK_TOP_SEL_100M)
919			rate = 100 * MHz;
920		else if (sel == PCLK_TOP_SEL_75M)
921			rate = 75 * MHz;
922		else if (sel == PCLK_TOP_SEL_50M)
923			rate = 50 * MHz;
924		else
925			rate = OSC_HZ;
926		break;
927	default:
928		return -ENOENT;
929	}
930
931	return rate;
932}
933
934static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
935				ulong clk_id, ulong rate)
936{
937	struct rk3568_cru *cru = priv->cru;
938	int src_clk;
939
940	switch (clk_id) {
941	case ACLK_TOP_HIGH:
942		if (rate == 500 * MHz)
943			src_clk = ACLK_TOP_HIGH_SEL_500M;
944		else if (rate == 400 * MHz)
945			src_clk = ACLK_TOP_HIGH_SEL_400M;
946		else if (rate == 300 * MHz)
947			src_clk = ACLK_TOP_HIGH_SEL_300M;
948		else
949			src_clk = ACLK_TOP_HIGH_SEL_24M;
950		rk_clrsetreg(&cru->clksel_con[73],
951			     ACLK_TOP_HIGH_SEL_MASK,
952			     src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
953		break;
954	case ACLK_TOP_LOW:
955		if (rate == 400 * MHz)
956			src_clk = ACLK_TOP_LOW_SEL_400M;
957		else if (rate == 300 * MHz)
958			src_clk = ACLK_TOP_LOW_SEL_300M;
959		else if (rate == 200 * MHz)
960			src_clk = ACLK_TOP_LOW_SEL_200M;
961		else
962			src_clk = ACLK_TOP_LOW_SEL_24M;
963		rk_clrsetreg(&cru->clksel_con[73],
964			     ACLK_TOP_LOW_SEL_MASK,
965			     src_clk << ACLK_TOP_LOW_SEL_SHIFT);
966		break;
967	case HCLK_TOP:
968		if (rate == 150 * MHz)
969			src_clk = HCLK_TOP_SEL_150M;
970		else if (rate == 100 * MHz)
971			src_clk = HCLK_TOP_SEL_100M;
972		else if (rate == 75 * MHz)
973			src_clk = HCLK_TOP_SEL_75M;
974		else
975			src_clk = HCLK_TOP_SEL_24M;
976		rk_clrsetreg(&cru->clksel_con[73],
977			     HCLK_TOP_SEL_MASK,
978			     src_clk << HCLK_TOP_SEL_SHIFT);
979		break;
980	case PCLK_TOP:
981		if (rate == 100 * MHz)
982			src_clk = PCLK_TOP_SEL_100M;
983		else if (rate == 75 * MHz)
984			src_clk = PCLK_TOP_SEL_75M;
985		else if (rate == 50 * MHz)
986			src_clk = PCLK_TOP_SEL_50M;
987		else
988			src_clk = PCLK_TOP_SEL_24M;
989		rk_clrsetreg(&cru->clksel_con[73],
990			     PCLK_TOP_SEL_MASK,
991			     src_clk << PCLK_TOP_SEL_SHIFT);
992		break;
993
994	default:
995		printf("do not support this permid freq\n");
996		return -EINVAL;
997	}
998
999	return rk3568_top_get_clk(priv, clk_id);
1000}
1001
1002static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1003{
1004	struct rk3568_cru *cru = priv->cru;
1005	u32 sel, con;
1006	ulong rate;
1007
1008	switch (clk_id) {
1009	case CLK_I2C1:
1010	case CLK_I2C2:
1011	case CLK_I2C3:
1012	case CLK_I2C4:
1013	case CLK_I2C5:
1014		con = readl(&cru->clksel_con[71]);
1015		sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
1016		if (sel == CLK_I2C_SEL_200M)
1017			rate = 200 * MHz;
1018		else if (sel == CLK_I2C_SEL_100M)
1019			rate = 100 * MHz;
1020		else if (sel == CLK_I2C_SEL_CPLL_100M)
1021			rate = 100 * MHz;
1022		else
1023			rate = OSC_HZ;
1024		break;
1025	default:
1026		return -ENOENT;
1027	}
1028
1029	return rate;
1030}
1031
1032static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1033				ulong rate)
1034{
1035	struct rk3568_cru *cru = priv->cru;
1036	int src_clk;
1037
1038	if (rate == 200 * MHz)
1039		src_clk = CLK_I2C_SEL_200M;
1040	else if (rate == 100 * MHz)
1041		src_clk = CLK_I2C_SEL_100M;
1042	else
1043		src_clk = CLK_I2C_SEL_24M;
1044
1045	switch (clk_id) {
1046	case CLK_I2C1:
1047	case CLK_I2C2:
1048	case CLK_I2C3:
1049	case CLK_I2C4:
1050	case CLK_I2C5:
1051		rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1052			     src_clk << CLK_I2C_SEL_SHIFT);
1053		break;
1054	default:
1055		return -ENOENT;
1056	}
1057
1058	return rk3568_i2c_get_clk(priv, clk_id);
1059}
1060
1061static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1062{
1063	struct rk3568_cru *cru = priv->cru;
1064	u32 sel, con;
1065
1066	con = readl(&cru->clksel_con[72]);
1067
1068	switch (clk_id) {
1069	case CLK_SPI0:
1070		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1071		break;
1072	case CLK_SPI1:
1073		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1074		break;
1075	case CLK_SPI2:
1076		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1077		break;
1078	case CLK_SPI3:
1079		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1080		break;
1081	default:
1082		return -ENOENT;
1083	}
1084
1085	switch (sel) {
1086	case CLK_SPI_SEL_200M:
1087		return 200 * MHz;
1088	case CLK_SPI_SEL_24M:
1089		return OSC_HZ;
1090	case CLK_SPI_SEL_CPLL_100M:
1091		return 100 * MHz;
1092	default:
1093		return -ENOENT;
1094	}
1095}
1096
1097static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1098				ulong clk_id, ulong rate)
1099{
1100	struct rk3568_cru *cru = priv->cru;
1101	int src_clk;
1102
1103	if (rate == 200 * MHz)
1104		src_clk = CLK_SPI_SEL_200M;
1105	else if (rate == 100 * MHz)
1106		src_clk = CLK_SPI_SEL_CPLL_100M;
1107	else
1108		src_clk = CLK_SPI_SEL_24M;
1109
1110	switch (clk_id) {
1111	case CLK_SPI0:
1112		rk_clrsetreg(&cru->clksel_con[72],
1113			     CLK_SPI0_SEL_MASK,
1114			     src_clk << CLK_SPI0_SEL_SHIFT);
1115		break;
1116	case CLK_SPI1:
1117		rk_clrsetreg(&cru->clksel_con[72],
1118			     CLK_SPI1_SEL_MASK,
1119			     src_clk << CLK_SPI1_SEL_SHIFT);
1120		break;
1121	case CLK_SPI2:
1122		rk_clrsetreg(&cru->clksel_con[72],
1123			     CLK_SPI2_SEL_MASK,
1124			     src_clk << CLK_SPI2_SEL_SHIFT);
1125		break;
1126	case CLK_SPI3:
1127		rk_clrsetreg(&cru->clksel_con[72],
1128			     CLK_SPI3_SEL_MASK,
1129			     src_clk << CLK_SPI3_SEL_SHIFT);
1130		break;
1131	default:
1132		return -ENOENT;
1133	}
1134
1135	return rk3568_spi_get_clk(priv, clk_id);
1136}
1137
1138static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1139{
1140	struct rk3568_cru *cru = priv->cru;
1141	u32 sel, con;
1142
1143	con = readl(&cru->clksel_con[72]);
1144
1145	switch (clk_id) {
1146	case CLK_PWM1:
1147		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
1148		break;
1149	case CLK_PWM2:
1150		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1151		break;
1152	case CLK_PWM3:
1153		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1154		break;
1155	default:
1156		return -ENOENT;
1157	}
1158
1159	switch (sel) {
1160	case CLK_PWM_SEL_100M:
1161		return 100 * MHz;
1162	case CLK_PWM_SEL_24M:
1163		return OSC_HZ;
1164	case CLK_PWM_SEL_CPLL_100M:
1165		return 100 * MHz;
1166	default:
1167		return -ENOENT;
1168	}
1169}
1170
1171static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1172				ulong clk_id, ulong rate)
1173{
1174	struct rk3568_cru *cru = priv->cru;
1175	int src_clk;
1176
1177	if (rate == 100 * MHz)
1178		src_clk = CLK_PWM_SEL_100M;
1179	else
1180		src_clk = CLK_PWM_SEL_24M;
1181
1182	switch (clk_id) {
1183	case CLK_PWM1:
1184		rk_clrsetreg(&cru->clksel_con[72],
1185			     CLK_PWM1_SEL_MASK,
1186			     src_clk << CLK_PWM1_SEL_SHIFT);
1187		break;
1188	case CLK_PWM2:
1189		rk_clrsetreg(&cru->clksel_con[72],
1190			     CLK_PWM2_SEL_MASK,
1191			     src_clk << CLK_PWM2_SEL_SHIFT);
1192		break;
1193	case CLK_PWM3:
1194		rk_clrsetreg(&cru->clksel_con[72],
1195			     CLK_PWM3_SEL_MASK,
1196			     src_clk << CLK_PWM3_SEL_SHIFT);
1197		break;
1198	default:
1199		return -ENOENT;
1200	}
1201
1202	return rk3568_pwm_get_clk(priv, clk_id);
1203}
1204
1205static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1206{
1207	struct rk3568_cru *cru = priv->cru;
1208	u32 div, sel, con, prate;
1209
1210	switch (clk_id) {
1211	case CLK_SARADC:
1212		return OSC_HZ;
1213	case CLK_TSADC_TSEN:
1214		con = readl(&cru->clksel_con[51]);
1215		div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
1216		      CLK_TSADC_TSEN_DIV_SHIFT;
1217		sel = (con & CLK_TSADC_TSEN_SEL_MASK) >>
1218		      CLK_TSADC_TSEN_SEL_SHIFT;
1219		if (sel == CLK_TSADC_TSEN_SEL_24M)
1220			prate = OSC_HZ;
1221		else
1222			prate = 100 * MHz;
1223		return DIV_TO_RATE(prate, div);
1224	case CLK_TSADC:
1225		con = readl(&cru->clksel_con[51]);
1226		div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
1227		prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1228		return DIV_TO_RATE(prate, div);
1229	default:
1230		return -ENOENT;
1231	}
1232}
1233
1234static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1235				ulong clk_id, ulong rate)
1236{
1237	struct rk3568_cru *cru = priv->cru;
1238	int src_clk_div;
1239	ulong prate = 0;
1240
1241	switch (clk_id) {
1242	case CLK_SARADC:
1243		return OSC_HZ;
1244	case CLK_TSADC_TSEN:
1245		if (!(OSC_HZ % rate)) {
1246			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
1247			assert(src_clk_div - 1 <= 7);
1248			rk_clrsetreg(&cru->clksel_con[51],
1249				     CLK_TSADC_TSEN_SEL_MASK |
1250				     CLK_TSADC_TSEN_DIV_MASK,
1251				     (CLK_TSADC_TSEN_SEL_24M <<
1252				      CLK_TSADC_TSEN_SEL_SHIFT) |
1253				     (src_clk_div - 1) <<
1254				     CLK_TSADC_TSEN_DIV_SHIFT);
1255		} else {
1256			src_clk_div = DIV_ROUND_UP(100 * MHz, rate);
1257			assert(src_clk_div - 1 <= 7);
1258			rk_clrsetreg(&cru->clksel_con[51],
1259				     CLK_TSADC_TSEN_SEL_MASK |
1260				     CLK_TSADC_TSEN_DIV_MASK,
1261				     (CLK_TSADC_TSEN_SEL_100M <<
1262				      CLK_TSADC_TSEN_SEL_SHIFT) |
1263				     (src_clk_div - 1) <<
1264				     CLK_TSADC_TSEN_DIV_SHIFT);
1265		}
1266		break;
1267	case CLK_TSADC:
1268			prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1269			src_clk_div = DIV_ROUND_UP(prate, rate);
1270			assert(src_clk_div - 1 <= 128);
1271			rk_clrsetreg(&cru->clksel_con[51],
1272				     CLK_TSADC_DIV_MASK,
1273				     (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1274		break;
1275	default:
1276		return -ENOENT;
1277	}
1278	return rk3568_adc_get_clk(priv, clk_id);
1279}
1280
1281static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1282{
1283	struct rk3568_cru *cru = priv->cru;
1284	u32 sel, con;
1285
1286	switch (clk_id) {
1287	case ACLK_SECURE_FLASH:
1288	case ACLK_CRYPTO_NS:
1289		con = readl(&cru->clksel_con[27]);
1290		sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >>
1291		      ACLK_SECURE_FLASH_SEL_SHIFT;
1292		if (sel == ACLK_SECURE_FLASH_SEL_200M)
1293			return 200 * MHz;
1294		else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1295			return 150 * MHz;
1296		else if (sel == ACLK_SECURE_FLASH_SEL_100M)
1297			return 100 * MHz;
1298		else
1299			return 24 * MHz;
1300	case HCLK_SECURE_FLASH:
1301	case HCLK_CRYPTO_NS:
1302	case CLK_CRYPTO_NS_RNG:
1303		con = readl(&cru->clksel_con[27]);
1304		sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >>
1305		      HCLK_SECURE_FLASH_SEL_SHIFT;
1306		if (sel == HCLK_SECURE_FLASH_SEL_150M)
1307			return 150 * MHz;
1308		else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1309			return 100 * MHz;
1310		else if (sel == HCLK_SECURE_FLASH_SEL_75M)
1311			return 75 * MHz;
1312		else
1313			return 24 * MHz;
1314	case CLK_CRYPTO_NS_CORE:
1315		con = readl(&cru->clksel_con[27]);
1316		sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >>
1317		      CLK_CRYPTO_CORE_SEL_SHIFT;
1318		if (sel == CLK_CRYPTO_CORE_SEL_200M)
1319			return 200 * MHz;
1320		else if (sel == CLK_CRYPTO_CORE_SEL_150M)
1321			return 150 * MHz;
1322		else
1323			return 100 * MHz;
1324	case CLK_CRYPTO_NS_PKA:
1325		con = readl(&cru->clksel_con[27]);
1326		sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >>
1327		      CLK_CRYPTO_PKA_SEL_SHIFT;
1328		if (sel == CLK_CRYPTO_PKA_SEL_300M)
1329			return 300 * MHz;
1330		else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1331			return 200 * MHz;
1332		else
1333			return 100 * MHz;
1334	default:
1335		return -ENOENT;
1336	}
1337}
1338
1339static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1340				    ulong clk_id, ulong rate)
1341{
1342	struct rk3568_cru *cru = priv->cru;
1343	u32 src_clk, mask, shift;
1344
1345	switch (clk_id) {
1346	case ACLK_SECURE_FLASH:
1347	case ACLK_CRYPTO_NS:
1348		mask = ACLK_SECURE_FLASH_SEL_MASK;
1349		shift = ACLK_SECURE_FLASH_SEL_SHIFT;
1350		if (rate == 200 * MHz)
1351			src_clk = ACLK_SECURE_FLASH_SEL_200M;
1352		else if (rate == 150 * MHz)
1353			src_clk = ACLK_SECURE_FLASH_SEL_150M;
1354		else if (rate == 100 * MHz)
1355			src_clk = ACLK_SECURE_FLASH_SEL_100M;
1356		else
1357			src_clk = ACLK_SECURE_FLASH_SEL_24M;
1358		break;
1359	case HCLK_SECURE_FLASH:
1360	case HCLK_CRYPTO_NS:
1361	case CLK_CRYPTO_NS_RNG:
1362		mask = HCLK_SECURE_FLASH_SEL_MASK;
1363		shift = HCLK_SECURE_FLASH_SEL_SHIFT;
1364		if (rate == 150 * MHz)
1365			src_clk = HCLK_SECURE_FLASH_SEL_150M;
1366		else if (rate == 100 * MHz)
1367			src_clk = HCLK_SECURE_FLASH_SEL_100M;
1368		else if (rate == 75 * MHz)
1369			src_clk = HCLK_SECURE_FLASH_SEL_75M;
1370		else
1371			src_clk = HCLK_SECURE_FLASH_SEL_24M;
1372		break;
1373	case CLK_CRYPTO_NS_CORE:
1374		mask = CLK_CRYPTO_CORE_SEL_MASK;
1375		shift = CLK_CRYPTO_CORE_SEL_SHIFT;
1376		if (rate == 200 * MHz)
1377			src_clk = CLK_CRYPTO_CORE_SEL_200M;
1378		else if (rate == 150 * MHz)
1379			src_clk = CLK_CRYPTO_CORE_SEL_150M;
1380		else
1381			src_clk = CLK_CRYPTO_CORE_SEL_100M;
1382		break;
1383	case CLK_CRYPTO_NS_PKA:
1384		mask = CLK_CRYPTO_PKA_SEL_MASK;
1385		shift = CLK_CRYPTO_PKA_SEL_SHIFT;
1386		if (rate == 300 * MHz)
1387			src_clk = CLK_CRYPTO_PKA_SEL_300M;
1388		else if (rate == 200 * MHz)
1389			src_clk = CLK_CRYPTO_PKA_SEL_200M;
1390		else
1391			src_clk = CLK_CRYPTO_PKA_SEL_100M;
1392		break;
1393	default:
1394		return -ENOENT;
1395	}
1396
1397	rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1398
1399	return rk3568_crypto_get_rate(priv, clk_id);
1400}
1401
1402static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1403{
1404	struct rk3568_cru *cru = priv->cru;
1405	u32 sel, con;
1406
1407	switch (clk_id) {
1408	case HCLK_SDMMC0:
1409	case CLK_SDMMC0:
1410		con = readl(&cru->clksel_con[30]);
1411		sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1412		break;
1413	case CLK_SDMMC1:
1414		con = readl(&cru->clksel_con[30]);
1415		sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1416		break;
1417	case CLK_SDMMC2:
1418		con = readl(&cru->clksel_con[32]);
1419		sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1420		break;
1421	default:
1422		return -ENOENT;
1423	}
1424
1425	switch (sel) {
1426	case CLK_SDMMC_SEL_24M:
1427		return OSC_HZ;
1428	case CLK_SDMMC_SEL_400M:
1429		return 400 * MHz;
1430	case CLK_SDMMC_SEL_300M:
1431		return 300 * MHz;
1432	case CLK_SDMMC_SEL_100M:
1433		return 100 * MHz;
1434	case CLK_SDMMC_SEL_50M:
1435		return 50 * MHz;
1436	case CLK_SDMMC_SEL_750K:
1437		return 750 * KHz;
1438	default:
1439		return -ENOENT;
1440	}
1441}
1442
1443static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1444				  ulong clk_id, ulong rate)
1445{
1446	struct rk3568_cru *cru = priv->cru;
1447	int src_clk;
1448
1449	switch (rate) {
1450	case OSC_HZ:
1451	case 26 * MHz:
1452	case 25 * MHz:
1453		src_clk = CLK_SDMMC_SEL_24M;
1454		break;
1455	case 400 * MHz:
1456		src_clk = CLK_SDMMC_SEL_400M;
1457		break;
1458	case 300 * MHz:
1459		src_clk = CLK_SDMMC_SEL_300M;
1460		break;
1461	case 100 * MHz:
1462		src_clk = CLK_SDMMC_SEL_100M;
1463		break;
1464	case 52 * MHz:
1465	case 50 * MHz:
1466		src_clk = CLK_SDMMC_SEL_50M;
1467		break;
1468	case 750 * KHz:
1469	case 400 * KHz:
1470		src_clk = CLK_SDMMC_SEL_750K;
1471		break;
1472	default:
1473		return -ENOENT;
1474	}
1475
1476	switch (clk_id) {
1477	case HCLK_SDMMC0:
1478	case CLK_SDMMC0:
1479		rk_clrsetreg(&cru->clksel_con[30],
1480			     CLK_SDMMC0_SEL_MASK,
1481			     src_clk << CLK_SDMMC0_SEL_SHIFT);
1482		break;
1483	case CLK_SDMMC1:
1484		rk_clrsetreg(&cru->clksel_con[30],
1485			     CLK_SDMMC1_SEL_MASK,
1486			     src_clk << CLK_SDMMC1_SEL_SHIFT);
1487		break;
1488	case CLK_SDMMC2:
1489		rk_clrsetreg(&cru->clksel_con[32],
1490			     CLK_SDMMC2_SEL_MASK,
1491			     src_clk << CLK_SDMMC2_SEL_SHIFT);
1492		break;
1493	default:
1494		return -ENOENT;
1495	}
1496
1497	return rk3568_sdmmc_get_clk(priv, clk_id);
1498}
1499
1500static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1501{
1502	struct rk3568_cru *cru = priv->cru;
1503	u32 sel, con;
1504
1505	con = readl(&cru->clksel_con[28]);
1506	sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1507	switch (sel) {
1508	case SCLK_SFC_SEL_24M:
1509		return OSC_HZ;
1510	case SCLK_SFC_SEL_50M:
1511		return 50 * MHz;
1512	case SCLK_SFC_SEL_75M:
1513		return 75 * MHz;
1514	case SCLK_SFC_SEL_100M:
1515		return 100 * MHz;
1516	case SCLK_SFC_SEL_125M:
1517		return 125 * MHz;
1518	case SCLK_SFC_SEL_150M:
1519		return 150 * MHz;
1520	default:
1521		return -ENOENT;
1522	}
1523}
1524
1525static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1526{
1527	struct rk3568_cru *cru = priv->cru;
1528	int src_clk;
1529
1530	if (rate >= 150 * MHz)
1531		src_clk = SCLK_SFC_SEL_150M;
1532	else if (rate >= 125 * MHz)
1533		src_clk = SCLK_SFC_SEL_125M;
1534	else if (rate >= 100 * MHz)
1535		src_clk = SCLK_SFC_SEL_100M;
1536	else if (rate >= 75 * MHz)
1537		src_clk = SCLK_SFC_SEL_75M;
1538	else if (rate >= 50 * MHz)
1539		src_clk = SCLK_SFC_SEL_50M;
1540	else if (rate >= OSC_HZ)
1541		src_clk = SCLK_SFC_SEL_24M;
1542	else
1543		return -ENOENT;
1544
1545	rk_clrsetreg(&cru->clksel_con[28],
1546		     SCLK_SFC_SEL_MASK,
1547		     src_clk << SCLK_SFC_SEL_SHIFT);
1548
1549	return rk3568_sfc_get_clk(priv);
1550}
1551
1552static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1553{
1554	struct rk3568_cru *cru = priv->cru;
1555	u32 sel, con;
1556
1557	con = readl(&cru->clksel_con[28]);
1558	sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1559	switch (sel) {
1560	case NCLK_NANDC_SEL_200M:
1561		return 200 * MHz;
1562	case NCLK_NANDC_SEL_150M:
1563		return 150 * MHz;
1564	case NCLK_NANDC_SEL_100M:
1565		return 100 * MHz;
1566	case NCLK_NANDC_SEL_24M:
1567		return OSC_HZ;
1568	default:
1569		return -ENOENT;
1570	}
1571}
1572
1573static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1574{
1575	struct rk3568_cru *cru = priv->cru;
1576	int src_clk;
1577
1578	switch (rate) {
1579	case OSC_HZ:
1580		src_clk = NCLK_NANDC_SEL_24M;
1581		break;
1582	case 100 * MHz:
1583		src_clk = NCLK_NANDC_SEL_100M;
1584		break;
1585	case 150 * MHz:
1586		src_clk = NCLK_NANDC_SEL_150M;
1587		break;
1588	case 200 * MHz:
1589		src_clk = NCLK_NANDC_SEL_200M;
1590		break;
1591	default:
1592		return -ENOENT;
1593	}
1594
1595	rk_clrsetreg(&cru->clksel_con[28],
1596		     NCLK_NANDC_SEL_MASK,
1597		     src_clk << NCLK_NANDC_SEL_SHIFT);
1598
1599	return rk3568_nand_get_clk(priv);
1600}
1601
1602static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1603{
1604	struct rk3568_cru *cru = priv->cru;
1605	u32 sel, con;
1606
1607	con = readl(&cru->clksel_con[28]);
1608	sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1609	switch (sel) {
1610	case CCLK_EMMC_SEL_200M:
1611		return 200 * MHz;
1612	case CCLK_EMMC_SEL_150M:
1613		return 150 * MHz;
1614	case CCLK_EMMC_SEL_100M:
1615		return 100 * MHz;
1616	case CCLK_EMMC_SEL_50M:
1617		return 50 * MHz;
1618	case CCLK_EMMC_SEL_375K:
1619		return 375 * KHz;
1620	case CCLK_EMMC_SEL_24M:
1621		return OSC_HZ;
1622	default:
1623		return -ENOENT;
1624	}
1625}
1626
1627static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1628{
1629	struct rk3568_cru *cru = priv->cru;
1630	int src_clk;
1631
1632	switch (rate) {
1633	case OSC_HZ:
1634	case 26 * MHz:
1635	case 25 * MHz:
1636		src_clk = CCLK_EMMC_SEL_24M;
1637		break;
1638	case 52 * MHz:
1639	case 50 * MHz:
1640		src_clk = CCLK_EMMC_SEL_50M;
1641		break;
1642	case 100 * MHz:
1643		src_clk = CCLK_EMMC_SEL_100M;
1644		break;
1645	case 150 * MHz:
1646		src_clk = CCLK_EMMC_SEL_150M;
1647		break;
1648	case 200 * MHz:
1649		src_clk = CCLK_EMMC_SEL_200M;
1650		break;
1651	case 400 * KHz:
1652	case 375 * KHz:
1653		src_clk = CCLK_EMMC_SEL_375K;
1654		break;
1655	default:
1656		return -ENOENT;
1657	}
1658
1659	rk_clrsetreg(&cru->clksel_con[28],
1660		     CCLK_EMMC_SEL_MASK,
1661		     src_clk << CCLK_EMMC_SEL_SHIFT);
1662
1663	return rk3568_emmc_get_clk(priv);
1664}
1665
1666static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1667{
1668	struct rk3568_cru *cru = priv->cru;
1669	u32 sel, con;
1670
1671	con = readl(&cru->clksel_con[28]);
1672	sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1673	switch (sel) {
1674	case BCLK_EMMC_SEL_200M:
1675		return 200 * MHz;
1676	case BCLK_EMMC_SEL_150M:
1677		return 150 * MHz;
1678	case BCLK_EMMC_SEL_125M:
1679		return 125 * MHz;
1680	default:
1681		return -ENOENT;
1682	}
1683}
1684
1685static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1686{
1687	struct rk3568_cru *cru = priv->cru;
1688	int src_clk;
1689
1690	switch (rate) {
1691	case 200 * MHz:
1692		src_clk = BCLK_EMMC_SEL_200M;
1693		break;
1694	case 150 * MHz:
1695		src_clk = BCLK_EMMC_SEL_150M;
1696		break;
1697	case 125 * MHz:
1698		src_clk = BCLK_EMMC_SEL_125M;
1699		break;
1700	default:
1701		return -ENOENT;
1702	}
1703
1704	rk_clrsetreg(&cru->clksel_con[28],
1705		     BCLK_EMMC_SEL_MASK,
1706		     src_clk << BCLK_EMMC_SEL_SHIFT);
1707
1708	return rk3568_emmc_get_bclk(priv);
1709}
1710
1711#ifndef CONFIG_SPL_BUILD
1712static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1713{
1714	struct rk3568_cru *cru = priv->cru;
1715	u32 div, sel, con, parent;
1716
1717	con = readl(&cru->clksel_con[38]);
1718	div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1719	sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1720	if (sel == ACLK_VOP_PRE_SEL_GPLL)
1721		parent = priv->gpll_hz;
1722	else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1723		parent = priv->cpll_hz;
1724	else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1725		parent = priv->vpll_hz;
1726	else
1727		parent = priv->hpll_hz;
1728
1729	return DIV_TO_RATE(parent, div);
1730}
1731
1732static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1733{
1734	struct rk3568_cru *cru = priv->cru;
1735	int src_clk_div, src_clk_mux;
1736
1737	if ((priv->cpll_hz % rate) == 0) {
1738		src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1739		src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1740	} else {
1741		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1742		src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1743	}
1744	assert(src_clk_div - 1 <= 31);
1745	rk_clrsetreg(&cru->clksel_con[38],
1746		     ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1747		     src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1748		     (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1749
1750	return rk3568_aclk_vop_get_clk(priv);
1751}
1752
1753static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1754{
1755	struct rk3568_cru *cru = priv->cru;
1756	u32 conid, div, sel, con, parent;
1757
1758	switch (clk_id) {
1759	case DCLK_VOP0:
1760		conid = 39;
1761		break;
1762	case DCLK_VOP1:
1763		conid = 40;
1764		break;
1765	case DCLK_VOP2:
1766		conid = 41;
1767		break;
1768	default:
1769		return -ENOENT;
1770	}
1771
1772	con = readl(&cru->clksel_con[conid]);
1773	div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1774	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1775	if (sel == DCLK_VOP_SEL_HPLL)
1776		parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1777	else if (sel == DCLK_VOP_SEL_VPLL)
1778		parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1779					       priv->cru, VPLL);
1780	else if (sel == DCLK_VOP_SEL_GPLL)
1781		parent = priv->gpll_hz;
1782	else if (sel == DCLK_VOP_SEL_CPLL)
1783		parent = priv->cpll_hz;
1784	else
1785		return -ENOENT;
1786
1787	return DIV_TO_RATE(parent, div);
1788}
1789
1790#define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1791
1792static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1793				     ulong clk_id, ulong rate)
1794{
1795	struct rk3568_cru *cru = priv->cru;
1796	ulong pll_rate, now, best_rate = 0;
1797	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1798
1799	switch (clk_id) {
1800	case DCLK_VOP0:
1801		conid = 39;
1802		break;
1803	case DCLK_VOP1:
1804		conid = 40;
1805		break;
1806	case DCLK_VOP2:
1807		conid = 41;
1808		break;
1809	default:
1810		return -ENOENT;
1811	}
1812
1813	con = readl(&cru->clksel_con[conid]);
1814	sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1815
1816	if (sel == DCLK_VOP_SEL_HPLL) {
1817		div = 1;
1818		rk_clrsetreg(&cru->clksel_con[conid],
1819			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1820			     (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1821			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1822		rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1823	} else if (sel == DCLK_VOP_SEL_VPLL) {
1824		div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1825		rk_clrsetreg(&cru->clksel_con[conid],
1826			     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1827			     (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1828			     ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1829		rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1830				      priv->cru, VPLL, div * rate);
1831	} else {
1832		for (i = sel; i <= DCLK_VOP_SEL_CPLL; i++) {
1833			switch (i) {
1834			case DCLK_VOP_SEL_GPLL:
1835				pll_rate = priv->gpll_hz;
1836				break;
1837			case DCLK_VOP_SEL_CPLL:
1838				pll_rate = priv->cpll_hz;
1839				break;
1840			default:
1841				printf("do not support this vop pll sel\n");
1842				return -EINVAL;
1843			}
1844
1845			div = DIV_ROUND_UP(pll_rate, rate);
1846			if (div > 255)
1847				continue;
1848			now = pll_rate / div;
1849			if (abs(rate - now) < abs(rate - best_rate)) {
1850				best_rate = now;
1851				best_div = div;
1852				best_sel = i;
1853			}
1854			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1855			      pll_rate, best_rate, best_div, best_sel);
1856		}
1857
1858		if (best_rate) {
1859			rk_clrsetreg(&cru->clksel_con[conid],
1860				     DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1861				     best_sel << DCLK0_VOP_SEL_SHIFT |
1862				     (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1863		} else {
1864			printf("do not support this vop freq %lu\n", rate);
1865			return -EINVAL;
1866		}
1867	}
1868	return rk3568_dclk_vop_get_clk(priv, clk_id);
1869}
1870
1871static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1872				     ulong mac_id)
1873{
1874	struct rk3568_cru *cru = priv->cru;
1875	u32 sel, con;
1876
1877	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1878	sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1879
1880	switch (sel) {
1881	case CLK_MAC0_2TOP_SEL_125M:
1882		return 125 * MHz;
1883	case CLK_MAC0_2TOP_SEL_50M:
1884		return 50 * MHz;
1885	case CLK_MAC0_2TOP_SEL_25M:
1886		return 25 * MHz;
1887	case CLK_MAC0_2TOP_SEL_PPLL:
1888		return rk3568_pmu_pll_get_rate(priv, HPLL);
1889	default:
1890		return -ENOENT;
1891	}
1892}
1893
1894static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1895				     ulong mac_id, ulong rate)
1896{
1897	struct rk3568_cru *cru = priv->cru;
1898	int src_clk;
1899
1900	switch (rate) {
1901	case 125 * MHz:
1902		src_clk = CLK_MAC0_2TOP_SEL_125M;
1903		break;
1904	case 50 * MHz:
1905		src_clk = CLK_MAC0_2TOP_SEL_50M;
1906		break;
1907	case 25 * MHz:
1908		src_clk = CLK_MAC0_2TOP_SEL_25M;
1909		break;
1910	default:
1911		return -ENOENT;
1912	}
1913
1914	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1915		     CLK_MAC0_2TOP_SEL_MASK,
1916		     src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1917
1918	return rk3568_gmac_src_get_clk(priv, mac_id);
1919}
1920
1921static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1922				     ulong mac_id)
1923{
1924	struct rk3568_cru *cru = priv->cru;
1925	u32 sel, con;
1926
1927	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1928	sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1929
1930	switch (sel) {
1931	case CLK_MAC0_OUT_SEL_125M:
1932		return 125 * MHz;
1933	case CLK_MAC0_OUT_SEL_50M:
1934		return 50 * MHz;
1935	case CLK_MAC0_OUT_SEL_25M:
1936		return 25 * MHz;
1937	case CLK_MAC0_OUT_SEL_24M:
1938		return OSC_HZ;
1939	default:
1940		return -ENOENT;
1941	}
1942}
1943
1944static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1945				     ulong mac_id, ulong rate)
1946{
1947	struct rk3568_cru *cru = priv->cru;
1948	int src_clk;
1949
1950	switch (rate) {
1951	case 125 * MHz:
1952		src_clk = CLK_MAC0_OUT_SEL_125M;
1953		break;
1954	case 50 * MHz:
1955		src_clk = CLK_MAC0_OUT_SEL_50M;
1956		break;
1957	case 25 * MHz:
1958		src_clk = CLK_MAC0_OUT_SEL_25M;
1959		break;
1960	case 24 * MHz:
1961		src_clk = CLK_MAC0_OUT_SEL_24M;
1962		break;
1963	default:
1964		return -ENOENT;
1965	}
1966
1967	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1968		     CLK_MAC0_OUT_SEL_MASK,
1969		     src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1970
1971	return rk3568_gmac_out_get_clk(priv, mac_id);
1972}
1973
1974static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1975					 ulong mac_id)
1976{
1977	struct rk3568_cru *cru = priv->cru;
1978	u32 sel, con;
1979
1980	con = readl(&cru->clksel_con[31 + mac_id * 2]);
1981	sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1982
1983	switch (sel) {
1984	case CLK_GMAC0_PTP_REF_SEL_62_5M:
1985		return 62500 * KHz;
1986	case CLK_GMAC0_PTP_REF_SEL_100M:
1987		return 100 * MHz;
1988	case CLK_GMAC0_PTP_REF_SEL_50M:
1989		return 50 * MHz;
1990	case CLK_GMAC0_PTP_REF_SEL_24M:
1991		return OSC_HZ;
1992	default:
1993		return -ENOENT;
1994	}
1995}
1996
1997static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1998					 ulong mac_id, ulong rate)
1999{
2000	struct rk3568_cru *cru = priv->cru;
2001	int src_clk;
2002
2003	switch (rate) {
2004	case 62500 * KHz:
2005		src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2006		break;
2007	case 100 * MHz:
2008		src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2009		break;
2010	case 50 * MHz:
2011		src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2012		break;
2013	case 24 * MHz:
2014		src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2015		break;
2016	default:
2017		return -ENOENT;
2018	}
2019
2020	rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2021		     CLK_GMAC0_PTP_REF_SEL_MASK,
2022		     src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2023
2024	return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2025}
2026
2027static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2028				       ulong mac_id, ulong rate)
2029{
2030	struct rk3568_cru *cru = priv->cru;
2031	u32 con, sel, div_sel;
2032
2033	con = readl(&cru->clksel_con[31 + mac_id * 2]);
2034	sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2035
2036	if (sel == RMII0_MODE_SEL_RGMII) {
2037		if (rate == 2500000)
2038			div_sel = RGMII0_CLK_SEL_2_5M;
2039		else if (rate == 25000000)
2040			div_sel = RGMII0_CLK_SEL_25M;
2041		else
2042			div_sel = RGMII0_CLK_SEL_125M;
2043		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2044			     RGMII0_CLK_SEL_MASK,
2045			     div_sel << RGMII0_CLK_SEL_SHIFT);
2046	} else if (sel == RMII0_MODE_SEL_RMII) {
2047		if (rate == 2500000)
2048			div_sel = RMII0_CLK_SEL_2_5M;
2049		else
2050			div_sel = RMII0_CLK_SEL_25M;
2051		rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2052			     RMII0_CLK_SEL_MASK,
2053			     div_sel << RMII0_CLK_SEL_SHIFT);
2054	}
2055
2056	return 0;
2057}
2058
2059static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2060{
2061	struct rk3568_cru *cru = priv->cru;
2062	u32 con, div, p_rate;
2063
2064	con = readl(&cru->clksel_con[79]);
2065	div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2066	p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2067
2068	con = readl(&cru->clksel_con[43]);
2069	div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2070	switch (div) {
2071	case DCLK_EBC_SEL_GPLL_400M:
2072		return 400 * MHz;
2073	case DCLK_EBC_SEL_CPLL_333M:
2074		return p_rate;
2075	case DCLK_EBC_SEL_GPLL_200M:
2076		return 200 * MHz;
2077	default:
2078		return -ENOENT;
2079	}
2080}
2081
2082static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2083{
2084	struct rk3568_cru *cru = priv->cru;
2085	int src_clk_div;
2086
2087	src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2088	assert(src_clk_div - 1 <= 31);
2089	rk_clrsetreg(&cru->clksel_con[79],
2090		     CPLL_333M_DIV_MASK,
2091		     (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2092	rk_clrsetreg(&cru->clksel_con[43],
2093		     DCLK_EBC_SEL_MASK,
2094		     DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2095
2096	return rk3568_ebc_get_clk(priv);
2097}
2098
2099static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2100{
2101	struct rk3568_cru *cru = priv->cru;
2102	u32 con, div, src, p_rate;
2103
2104	switch (clk_id) {
2105	case ACLK_RKVDEC_PRE:
2106	case ACLK_RKVDEC:
2107		con = readl(&cru->clksel_con[47]);
2108		src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2109		div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2110		if (src == ACLK_RKVDEC_SEL_CPLL)
2111			p_rate = priv->cpll_hz;
2112		else
2113			p_rate = priv->gpll_hz;
2114		return DIV_TO_RATE(p_rate, div);
2115	case CLK_RKVDEC_CORE:
2116		con = readl(&cru->clksel_con[49]);
2117		src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2118		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2119		div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2120		      >> CLK_RKVDEC_CORE_DIV_SHIFT;
2121		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2122			p_rate = priv->cpll_hz;
2123		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2124			p_rate = priv->npll_hz;
2125		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2126			p_rate = priv->vpll_hz;
2127		else
2128			p_rate = priv->gpll_hz;
2129		return DIV_TO_RATE(p_rate, div);
2130	default:
2131		return -ENOENT;
2132	}
2133}
2134
2135static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2136				   ulong clk_id, ulong rate)
2137{
2138	struct rk3568_cru *cru = priv->cru;
2139	int src_clk_div, src, p_rate;
2140
2141	switch (clk_id) {
2142	case ACLK_RKVDEC_PRE:
2143	case ACLK_RKVDEC:
2144		src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2145		      >> ACLK_RKVDEC_SEL_SHIFT;
2146		if (src == ACLK_RKVDEC_SEL_CPLL)
2147			p_rate = priv->cpll_hz;
2148		else
2149			p_rate = priv->gpll_hz;
2150		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2151		assert(src_clk_div - 1 <= 31);
2152		rk_clrsetreg(&cru->clksel_con[47],
2153			     ACLK_RKVDEC_SEL_MASK |
2154			     ACLK_RKVDEC_DIV_MASK,
2155			     (src << ACLK_RKVDEC_SEL_SHIFT) |
2156			     (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2157		break;
2158	case CLK_RKVDEC_CORE:
2159		src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2160		      >> CLK_RKVDEC_CORE_SEL_SHIFT;
2161		if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2162			p_rate = priv->cpll_hz;
2163		else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2164			p_rate = priv->npll_hz;
2165		else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2166			p_rate = priv->vpll_hz;
2167		else
2168			p_rate = priv->gpll_hz;
2169		src_clk_div = DIV_ROUND_UP(p_rate, rate);
2170		assert(src_clk_div - 1 <= 31);
2171		rk_clrsetreg(&cru->clksel_con[49],
2172			     CLK_RKVDEC_CORE_SEL_MASK |
2173			     CLK_RKVDEC_CORE_DIV_MASK,
2174			     (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2175			     (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2176		break;
2177	default:
2178		return -ENOENT;
2179	}
2180
2181	return rk3568_rkvdec_get_clk(priv, clk_id);
2182}
2183#endif
2184
2185static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2186{
2187	struct rk3568_cru *cru = priv->cru;
2188	u32 reg, con, fracdiv, div, src, p_src, p_rate;
2189	unsigned long m, n;
2190
2191	switch (clk_id) {
2192	case SCLK_UART1:
2193		reg = 52;
2194		break;
2195	case SCLK_UART2:
2196		reg = 54;
2197		break;
2198	case SCLK_UART3:
2199		reg = 56;
2200		break;
2201	case SCLK_UART4:
2202		reg = 58;
2203		break;
2204	case SCLK_UART5:
2205		reg = 60;
2206		break;
2207	case SCLK_UART6:
2208		reg = 62;
2209		break;
2210	case SCLK_UART7:
2211		reg = 64;
2212		break;
2213	case SCLK_UART8:
2214		reg = 66;
2215		break;
2216	case SCLK_UART9:
2217		reg = 68;
2218		break;
2219	default:
2220		return -ENOENT;
2221	}
2222	con = readl(&cru->clksel_con[reg]);
2223	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2224	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2225	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2226	if (p_src == CLK_UART_SRC_SEL_GPLL)
2227		p_rate = priv->gpll_hz;
2228	else if (p_src == CLK_UART_SRC_SEL_CPLL)
2229		p_rate = priv->cpll_hz;
2230	else
2231		p_rate = 480000000;
2232	if (src == CLK_UART_SEL_SRC) {
2233		return DIV_TO_RATE(p_rate, div);
2234	} else if (src == CLK_UART_SEL_FRAC) {
2235		fracdiv = readl(&cru->clksel_con[reg + 1]);
2236		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2237		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2238		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2239		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2240		return DIV_TO_RATE(p_rate, div) * n / m;
2241	} else {
2242		return OSC_HZ;
2243	}
2244}
2245
2246static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2247				  ulong clk_id, ulong rate)
2248{
2249	struct rk3568_cru *cru = priv->cru;
2250	u32 reg, clk_src, uart_src, div;
2251	unsigned long m = 0, n = 0, val;
2252
2253	if (priv->gpll_hz % rate == 0) {
2254		clk_src = CLK_UART_SRC_SEL_GPLL;
2255		uart_src = CLK_UART_SEL_SRC;
2256		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2257	} else if (priv->cpll_hz % rate == 0) {
2258		clk_src = CLK_UART_SRC_SEL_CPLL;
2259		uart_src = CLK_UART_SEL_SRC;
2260		div = DIV_ROUND_UP(priv->gpll_hz, rate);
2261	} else if (rate == OSC_HZ) {
2262		clk_src = CLK_UART_SRC_SEL_GPLL;
2263		uart_src = CLK_UART_SEL_XIN24M;
2264		div = 2;
2265	} else {
2266		clk_src = CLK_UART_SRC_SEL_GPLL;
2267		uart_src = CLK_UART_SEL_FRAC;
2268		div = 2;
2269		rational_best_approximation(rate, priv->gpll_hz / div,
2270					    GENMASK(16 - 1, 0),
2271					    GENMASK(16 - 1, 0),
2272					    &m, &n);
2273	}
2274
2275	switch (clk_id) {
2276	case SCLK_UART1:
2277		reg = 52;
2278		break;
2279	case SCLK_UART2:
2280		reg = 54;
2281		break;
2282	case SCLK_UART3:
2283		reg = 56;
2284		break;
2285	case SCLK_UART4:
2286		reg = 58;
2287		break;
2288	case SCLK_UART5:
2289		reg = 60;
2290		break;
2291	case SCLK_UART6:
2292		reg = 62;
2293		break;
2294	case SCLK_UART7:
2295		reg = 64;
2296		break;
2297	case SCLK_UART8:
2298		reg = 66;
2299		break;
2300	case SCLK_UART9:
2301		reg = 68;
2302		break;
2303	default:
2304		return -ENOENT;
2305	}
2306	rk_clrsetreg(&cru->clksel_con[reg],
2307		     CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2308		     CLK_UART_SRC_DIV_MASK,
2309		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2310		     (uart_src << CLK_UART_SEL_SHIFT) |
2311		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2312	if (m && n) {
2313		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2314		writel(val, &cru->clksel_con[reg + 1]);
2315	}
2316
2317	return rk3568_uart_get_rate(priv, clk_id);
2318}
2319
2320static ulong rk3568_clk_get_rate(struct clk *clk)
2321{
2322	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2323	ulong rate = 0;
2324
2325	if (!priv->gpll_hz) {
2326		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2327		return -ENOENT;
2328	}
2329
2330	switch (clk->id) {
2331	case PLL_APLL:
2332	case ARMCLK:
2333		rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2334					     APLL);
2335		break;
2336	case PLL_CPLL:
2337		rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2338					     CPLL);
2339		break;
2340	case PLL_GPLL:
2341		rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2342					     GPLL);
2343		break;
2344	case PLL_NPLL:
2345		rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2346					     NPLL);
2347		break;
2348	case PLL_VPLL:
2349		rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2350					     VPLL);
2351		break;
2352	case PLL_DPLL:
2353		rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2354					     DPLL);
2355		break;
2356	case ACLK_BUS:
2357	case PCLK_BUS:
2358	case PCLK_WDT_NS:
2359		rate = rk3568_bus_get_clk(priv, clk->id);
2360		break;
2361	case ACLK_PERIMID:
2362	case HCLK_PERIMID:
2363		rate = rk3568_perimid_get_clk(priv, clk->id);
2364		break;
2365	case ACLK_TOP_HIGH:
2366	case ACLK_TOP_LOW:
2367	case HCLK_TOP:
2368	case PCLK_TOP:
2369		rate = rk3568_top_get_clk(priv, clk->id);
2370		break;
2371	case CLK_I2C1:
2372	case CLK_I2C2:
2373	case CLK_I2C3:
2374	case CLK_I2C4:
2375	case CLK_I2C5:
2376		rate = rk3568_i2c_get_clk(priv, clk->id);
2377		break;
2378	case CLK_SPI0:
2379	case CLK_SPI1:
2380	case CLK_SPI2:
2381	case CLK_SPI3:
2382		rate = rk3568_spi_get_clk(priv, clk->id);
2383		break;
2384	case CLK_PWM1:
2385	case CLK_PWM2:
2386	case CLK_PWM3:
2387		rate = rk3568_pwm_get_clk(priv, clk->id);
2388		break;
2389	case CLK_SARADC:
2390	case CLK_TSADC_TSEN:
2391	case CLK_TSADC:
2392		rate = rk3568_adc_get_clk(priv, clk->id);
2393		break;
2394	case HCLK_SDMMC0:
2395	case CLK_SDMMC0:
2396	case CLK_SDMMC1:
2397	case CLK_SDMMC2:
2398		rate = rk3568_sdmmc_get_clk(priv, clk->id);
2399		break;
2400	case SCLK_SFC:
2401		rate = rk3568_sfc_get_clk(priv);
2402		break;
2403	case NCLK_NANDC:
2404		rate = rk3568_nand_get_clk(priv);
2405		break;
2406	case CCLK_EMMC:
2407		rate = rk3568_emmc_get_clk(priv);
2408		break;
2409	case BCLK_EMMC:
2410		rate = rk3568_emmc_get_bclk(priv);
2411		break;
2412	case CLK_USB3OTG0_REF:
2413	case CLK_USB3OTG1_REF:
2414	case TCLK_EMMC:
2415		rate = OSC_HZ;
2416		break;
2417#ifndef CONFIG_SPL_BUILD
2418	case ACLK_VOP:
2419		rate = rk3568_aclk_vop_get_clk(priv);
2420		break;
2421	case DCLK_VOP0:
2422	case DCLK_VOP1:
2423	case DCLK_VOP2:
2424		rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2425		break;
2426	case SCLK_GMAC0:
2427	case CLK_MAC0_2TOP:
2428	case CLK_MAC0_REFOUT:
2429		rate = rk3568_gmac_src_get_clk(priv, 0);
2430		break;
2431	case CLK_MAC0_OUT:
2432		rate = rk3568_gmac_out_get_clk(priv, 0);
2433		break;
2434	case CLK_GMAC0_PTP_REF:
2435		rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2436		break;
2437	case SCLK_GMAC1:
2438	case CLK_MAC1_2TOP:
2439	case CLK_MAC1_REFOUT:
2440		rate = rk3568_gmac_src_get_clk(priv, 1);
2441		break;
2442	case CLK_MAC1_OUT:
2443		rate = rk3568_gmac_out_get_clk(priv, 1);
2444		break;
2445	case CLK_GMAC1_PTP_REF:
2446		rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2447		break;
2448	case DCLK_EBC:
2449		rate = rk3568_ebc_get_clk(priv);
2450		break;
2451	case ACLK_RKVDEC_PRE:
2452	case ACLK_RKVDEC:
2453	case CLK_RKVDEC_CORE:
2454		rate = rk3568_rkvdec_get_clk(priv, clk->id);
2455		break;
2456	case TCLK_WDT_NS:
2457		rate = OSC_HZ;
2458		break;
2459#endif
2460	case SCLK_UART1:
2461	case SCLK_UART2:
2462	case SCLK_UART3:
2463	case SCLK_UART4:
2464	case SCLK_UART5:
2465	case SCLK_UART6:
2466	case SCLK_UART7:
2467	case SCLK_UART8:
2468	case SCLK_UART9:
2469		rate = rk3568_uart_get_rate(priv, clk->id);
2470		break;
2471	case ACLK_SECURE_FLASH:
2472	case ACLK_CRYPTO_NS:
2473	case HCLK_SECURE_FLASH:
2474	case HCLK_CRYPTO_NS:
2475	case CLK_CRYPTO_NS_RNG:
2476	case CLK_CRYPTO_NS_CORE:
2477	case CLK_CRYPTO_NS_PKA:
2478		rate = rk3568_crypto_get_rate(priv, clk->id);
2479		break;
2480	case CPLL_500M:
2481	case CPLL_333M:
2482	case CPLL_250M:
2483	case CPLL_125M:
2484	case CPLL_100M:
2485	case CPLL_62P5M:
2486	case CPLL_50M:
2487	case CPLL_25M:
2488		rate = rk3568_cpll_div_get_rate(priv, clk->id);
2489		break;
2490	default:
2491		return -ENOENT;
2492	}
2493
2494	return rate;
2495};
2496
2497static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2498{
2499	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2500	ulong ret = 0;
2501
2502	if (!priv->gpll_hz) {
2503		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2504		return -ENOENT;
2505	}
2506
2507	switch (clk->id) {
2508	case PLL_APLL:
2509	case ARMCLK:
2510		if (priv->armclk_hz)
2511			rk3568_armclk_set_clk(priv, rate);
2512		priv->armclk_hz = rate;
2513		break;
2514	case PLL_CPLL:
2515		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2516					    CPLL, rate);
2517		priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2518						      priv->cru, CPLL);
2519		break;
2520	case PLL_GPLL:
2521		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2522					    GPLL, rate);
2523		priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2524						      priv->cru, GPLL);
2525		break;
2526	case PLL_NPLL:
2527		ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2528					    NPLL, rate);
2529		break;
2530	case PLL_VPLL:
2531		ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2532					    VPLL, rate);
2533		priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2534						      priv->cru,
2535						      VPLL);
2536		break;
2537	case ACLK_BUS:
2538	case PCLK_BUS:
2539	case PCLK_WDT_NS:
2540		ret = rk3568_bus_set_clk(priv, clk->id, rate);
2541		break;
2542	case ACLK_PERIMID:
2543	case HCLK_PERIMID:
2544		ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2545		break;
2546	case ACLK_TOP_HIGH:
2547	case ACLK_TOP_LOW:
2548	case HCLK_TOP:
2549	case PCLK_TOP:
2550		ret = rk3568_top_set_clk(priv, clk->id, rate);
2551		break;
2552	case CLK_I2C1:
2553	case CLK_I2C2:
2554	case CLK_I2C3:
2555	case CLK_I2C4:
2556	case CLK_I2C5:
2557		ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2558		break;
2559	case CLK_SPI0:
2560	case CLK_SPI1:
2561	case CLK_SPI2:
2562	case CLK_SPI3:
2563		ret = rk3568_spi_set_clk(priv, clk->id, rate);
2564		break;
2565	case CLK_PWM1:
2566	case CLK_PWM2:
2567	case CLK_PWM3:
2568		ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2569		break;
2570	case CLK_SARADC:
2571	case CLK_TSADC_TSEN:
2572	case CLK_TSADC:
2573		ret = rk3568_adc_set_clk(priv, clk->id, rate);
2574		break;
2575	case HCLK_SDMMC0:
2576	case CLK_SDMMC0:
2577	case CLK_SDMMC1:
2578	case CLK_SDMMC2:
2579		ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2580		break;
2581	case SCLK_SFC:
2582		ret = rk3568_sfc_set_clk(priv, rate);
2583		break;
2584	case NCLK_NANDC:
2585		ret = rk3568_nand_set_clk(priv, rate);
2586		break;
2587	case CCLK_EMMC:
2588		ret = rk3568_emmc_set_clk(priv, rate);
2589		break;
2590	case BCLK_EMMC:
2591		ret = rk3568_emmc_set_bclk(priv, rate);
2592		break;
2593	case CLK_USB3OTG0_REF:
2594	case CLK_USB3OTG1_REF:
2595	case TCLK_EMMC:
2596		ret = OSC_HZ;
2597		break;
2598#ifndef CONFIG_SPL_BUILD
2599	case ACLK_VOP:
2600		ret = rk3568_aclk_vop_set_clk(priv, rate);
2601		break;
2602	case DCLK_VOP0:
2603	case DCLK_VOP1:
2604	case DCLK_VOP2:
2605		ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2606		break;
2607	case SCLK_GMAC0:
2608	case CLK_MAC0_2TOP:
2609	case CLK_MAC0_REFOUT:
2610		ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2611		break;
2612	case CLK_MAC0_OUT:
2613		ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2614		break;
2615	case SCLK_GMAC0_RX_TX:
2616		ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2617		break;
2618	case CLK_GMAC0_PTP_REF:
2619		ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2620		break;
2621	case SCLK_GMAC1:
2622	case CLK_MAC1_2TOP:
2623	case CLK_MAC1_REFOUT:
2624		ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2625		break;
2626	case CLK_MAC1_OUT:
2627		ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2628		break;
2629	case SCLK_GMAC1_RX_TX:
2630		ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2631		break;
2632	case CLK_GMAC1_PTP_REF:
2633		ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2634		break;
2635	case DCLK_EBC:
2636		ret = rk3568_ebc_set_clk(priv, rate);
2637		break;
2638	case ACLK_RKVDEC_PRE:
2639	case ACLK_RKVDEC:
2640	case CLK_RKVDEC_CORE:
2641		ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2642		break;
2643	case TCLK_WDT_NS:
2644		ret = OSC_HZ;
2645		break;
2646#endif
2647	case SCLK_UART1:
2648	case SCLK_UART2:
2649	case SCLK_UART3:
2650	case SCLK_UART4:
2651	case SCLK_UART5:
2652	case SCLK_UART6:
2653	case SCLK_UART7:
2654	case SCLK_UART8:
2655	case SCLK_UART9:
2656		ret = rk3568_uart_set_rate(priv, clk->id, rate);
2657		break;
2658	case ACLK_SECURE_FLASH:
2659	case ACLK_CRYPTO_NS:
2660	case HCLK_SECURE_FLASH:
2661	case HCLK_CRYPTO_NS:
2662	case CLK_CRYPTO_NS_RNG:
2663	case CLK_CRYPTO_NS_CORE:
2664	case CLK_CRYPTO_NS_PKA:
2665		ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2666		break;
2667	case CPLL_500M:
2668	case CPLL_333M:
2669	case CPLL_250M:
2670	case CPLL_125M:
2671	case CPLL_100M:
2672	case CPLL_62P5M:
2673	case CPLL_50M:
2674	case CPLL_25M:
2675		ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2676		break;
2677	default:
2678		return -ENOENT;
2679	}
2680
2681	return ret;
2682};
2683
2684#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2685static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2686{
2687	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2688	struct rk3568_cru *cru = priv->cru;
2689
2690	if (parent->id == CLK_MAC0_2TOP)
2691		rk_clrsetreg(&cru->clksel_con[31],
2692			     RMII0_EXTCLK_SEL_MASK,
2693			     RMII0_EXTCLK_SEL_MAC0_TOP <<
2694			     RMII0_EXTCLK_SEL_SHIFT);
2695	else
2696		rk_clrsetreg(&cru->clksel_con[31],
2697			     RMII0_EXTCLK_SEL_MASK,
2698			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2699	return 0;
2700}
2701
2702static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2703{
2704	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2705	struct rk3568_cru *cru = priv->cru;
2706
2707	if (parent->id == CLK_MAC1_2TOP)
2708		rk_clrsetreg(&cru->clksel_con[33],
2709			     RMII0_EXTCLK_SEL_MASK,
2710			     RMII0_EXTCLK_SEL_MAC0_TOP <<
2711			     RMII0_EXTCLK_SEL_SHIFT);
2712	else
2713		rk_clrsetreg(&cru->clksel_con[33],
2714			     RMII0_EXTCLK_SEL_MASK,
2715			     RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2716	return 0;
2717}
2718
2719static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2720{
2721	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2722	struct rk3568_cru *cru = priv->cru;
2723
2724	if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2725		rk_clrsetreg(&cru->clksel_con[31],
2726			     RMII0_MODE_MASK,
2727			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2728	else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2729		rk_clrsetreg(&cru->clksel_con[31],
2730			     RMII0_MODE_MASK,
2731			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2732	else
2733		rk_clrsetreg(&cru->clksel_con[31],
2734			     RMII0_MODE_MASK,
2735			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2736
2737	return 0;
2738}
2739
2740static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2741{
2742	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2743	struct rk3568_cru *cru = priv->cru;
2744
2745	if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2746		rk_clrsetreg(&cru->clksel_con[33],
2747			     RMII0_MODE_MASK,
2748			     RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2749	else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2750		rk_clrsetreg(&cru->clksel_con[33],
2751			     RMII0_MODE_MASK,
2752			     RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2753	else
2754		rk_clrsetreg(&cru->clksel_con[33],
2755			     RMII0_MODE_MASK,
2756			     RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2757
2758	return 0;
2759}
2760
2761static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2762{
2763	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2764	struct rk3568_cru *cru = priv->cru;
2765	u32 con_id;
2766
2767	switch (clk->id) {
2768	case DCLK_VOP0:
2769		con_id = 39;
2770		break;
2771	case DCLK_VOP1:
2772		con_id = 40;
2773		break;
2774	case DCLK_VOP2:
2775		con_id = 41;
2776		break;
2777	default:
2778		return -EINVAL;
2779	}
2780	if (parent->id == PLL_VPLL) {
2781		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2782			     DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
2783	} else if (parent->id == PLL_HPLL) {
2784		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2785			     DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
2786	} else if (parent->id == PLL_CPLL) {
2787		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2788			     DCLK_VOP_SEL_CPLL << DCLK0_VOP_SEL_SHIFT);
2789	} else {
2790		rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2791			     DCLK_VOP_SEL_GPLL << DCLK0_VOP_SEL_SHIFT);
2792	}
2793
2794	return 0;
2795}
2796
2797static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2798{
2799	struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2800	struct rk3568_cru *cru = priv->cru;
2801	u32 con_id, mask, shift;
2802
2803	switch (clk->id) {
2804	case ACLK_RKVDEC_PRE:
2805		con_id = 47;
2806		mask = ACLK_RKVDEC_SEL_MASK;
2807		shift = ACLK_RKVDEC_SEL_SHIFT;
2808		break;
2809	case CLK_RKVDEC_CORE:
2810		con_id = 49;
2811		mask = CLK_RKVDEC_CORE_SEL_MASK;
2812		shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2813		break;
2814	default:
2815		return -EINVAL;
2816	}
2817	if (parent->id == PLL_CPLL) {
2818		rk_clrsetreg(&cru->clksel_con[con_id], mask,
2819			     ACLK_RKVDEC_SEL_CPLL << shift);
2820	} else {
2821		rk_clrsetreg(&cru->clksel_con[con_id], mask,
2822			     ACLK_RKVDEC_SEL_GPLL << shift);
2823	}
2824
2825	return 0;
2826}
2827
2828static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2829{
2830	switch (clk->id) {
2831	case SCLK_GMAC0:
2832		return rk3568_gmac0_src_set_parent(clk, parent);
2833	case SCLK_GMAC1:
2834		return rk3568_gmac1_src_set_parent(clk, parent);
2835	case SCLK_GMAC0_RX_TX:
2836		return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2837	case SCLK_GMAC1_RX_TX:
2838		return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2839	case DCLK_VOP0:
2840	case DCLK_VOP1:
2841	case DCLK_VOP2:
2842		return rk3568_dclk_vop_set_parent(clk, parent);
2843	case ACLK_RKVDEC_PRE:
2844	case CLK_RKVDEC_CORE:
2845		return rk3568_rkvdec_set_parent(clk, parent);
2846	case I2S1_MCLKOUT_TX:
2847	case SCLK_GMAC0_RGMII_SPEED:
2848	case SCLK_GMAC0_RMII_SPEED:
2849	case SCLK_GMAC1_RGMII_SPEED:
2850	case SCLK_GMAC1_RMII_SPEED:
2851		break;
2852	default:
2853		return -ENOENT;
2854	}
2855
2856	return 0;
2857}
2858#endif
2859
2860static struct clk_ops rk3568_clk_ops = {
2861	.get_rate = rk3568_clk_get_rate,
2862	.set_rate = rk3568_clk_set_rate,
2863#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2864	.set_parent = rk3568_clk_set_parent,
2865#endif
2866};
2867
2868static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2869{
2870	int ret;
2871
2872	priv->sync_kernel = false;
2873	if (!priv->armclk_enter_hz) {
2874		priv->armclk_enter_hz =
2875			rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2876					      priv->cru, APLL);
2877		priv->armclk_init_hz = priv->armclk_enter_hz;
2878	}
2879
2880	if (priv->armclk_init_hz != APLL_HZ) {
2881		ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2882		if (!ret)
2883			priv->armclk_init_hz = APLL_HZ;
2884	}
2885	if (priv->cpll_hz != CPLL_HZ) {
2886		ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2887					    CPLL, CPLL_HZ);
2888		if (!ret)
2889			priv->cpll_hz = CPLL_HZ;
2890	}
2891	if (priv->gpll_hz != GPLL_HZ) {
2892		ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2893					    GPLL, GPLL_HZ);
2894		if (!ret)
2895			priv->gpll_hz = GPLL_HZ;
2896	}
2897
2898#ifdef CONFIG_SPL_BUILD
2899	ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2900	if (ret < 0)
2901		printf("Fail to set the ACLK_BUS clock.\n");
2902#endif
2903
2904	priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2905	priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2906}
2907
2908static int rk3568_clk_probe(struct udevice *dev)
2909{
2910	struct rk3568_clk_priv *priv = dev_get_priv(dev);
2911	int ret;
2912
2913	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2914	if (IS_ERR(priv->grf))
2915		return PTR_ERR(priv->grf);
2916
2917	rk3568_clk_init(priv);
2918
2919	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2920	ret = clk_set_defaults(dev, 1);
2921	if (ret)
2922		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2923	else
2924		priv->sync_kernel = true;
2925
2926	return 0;
2927}
2928
2929static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2930{
2931	struct rk3568_clk_priv *priv = dev_get_priv(dev);
2932
2933	priv->cru = dev_read_addr_ptr(dev);
2934
2935	return 0;
2936}
2937
2938static int rk3568_clk_bind(struct udevice *dev)
2939{
2940	int ret;
2941	struct udevice *sys_child;
2942	struct sysreset_reg *priv;
2943
2944	/* The reset driver does not have a device node, so bind it here */
2945	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2946				 &sys_child);
2947	if (ret) {
2948		debug("Warning: No sysreset driver: ret=%d\n", ret);
2949	} else {
2950		priv = malloc(sizeof(struct sysreset_reg));
2951		priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2952						    glb_srst_fst);
2953		priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2954						    glb_srsr_snd);
2955		dev_set_priv(sys_child, priv);
2956	}
2957
2958#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2959	ret = offsetof(struct rk3568_cru, softrst_con[0]);
2960	ret = rockchip_reset_bind(dev, ret, 30);
2961	if (ret)
2962		debug("Warning: software reset driver bind failed\n");
2963#endif
2964
2965	return 0;
2966}
2967
2968static const struct udevice_id rk3568_clk_ids[] = {
2969	{ .compatible = "rockchip,rk3568-cru" },
2970	{ }
2971};
2972
2973U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2974	.name		= "rockchip_rk3568_cru",
2975	.id		= UCLASS_CLK,
2976	.of_match	= rk3568_clk_ids,
2977	.priv_auto = sizeof(struct rk3568_clk_priv),
2978	.of_to_plat = rk3568_clk_ofdata_to_platdata,
2979	.ops		= &rk3568_clk_ops,
2980	.bind		= rk3568_clk_bind,
2981	.probe		= rk3568_clk_probe,
2982#if CONFIG_IS_ENABLED(OF_PLATDATA)
2983	.plat_auto	= sizeof(struct rk3568_clk_plat),
2984#endif
2985};
2986