xref: /openbmc/u-boot/drivers/clk/rockchip/clk_rk3399.c (revision d024236e5a31a2b4b82cbcc98b31b8170fc88d28)
1 /*
2  * (C) Copyright 2015 Google, Inc
3  * (C) 2017 Theobroma Systems Design und Consulting GmbH
4  *
5  * SPDX-License-Identifier:	GPL-2.0
6  */
7 
8 #include <common.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <dt-structs.h>
12 #include <errno.h>
13 #include <mapmem.h>
14 #include <syscon.h>
15 #include <bitfield.h>
16 #include <asm/io.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/cru_rk3399.h>
19 #include <asm/arch/hardware.h>
20 #include <dm/lists.h>
21 #include <dt-bindings/clock/rk3399-cru.h>
22 
23 #if CONFIG_IS_ENABLED(OF_PLATDATA)
24 struct rk3399_clk_plat {
25 	struct dtd_rockchip_rk3399_cru dtd;
26 };
27 
28 struct rk3399_pmuclk_plat {
29 	struct dtd_rockchip_rk3399_pmucru dtd;
30 };
31 #endif
32 
33 struct pll_div {
34 	u32 refdiv;
35 	u32 fbdiv;
36 	u32 postdiv1;
37 	u32 postdiv2;
38 	u32 frac;
39 };
40 
41 #define RATE_TO_DIV(input_rate, output_rate) \
42 	((input_rate) / (output_rate) - 1);
43 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
44 
45 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
46 	.refdiv = _refdiv,\
47 	.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
48 	.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
49 
50 #if defined(CONFIG_SPL_BUILD)
51 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
52 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
53 #else
54 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
55 #endif
56 
57 static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1);
58 static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
59 
60 static const struct pll_div *apll_l_cfgs[] = {
61 	[APLL_L_1600_MHZ] = &apll_l_1600_cfg,
62 	[APLL_L_600_MHZ] = &apll_l_600_cfg,
63 };
64 
65 enum {
66 	/* PLL_CON0 */
67 	PLL_FBDIV_MASK			= 0xfff,
68 	PLL_FBDIV_SHIFT			= 0,
69 
70 	/* PLL_CON1 */
71 	PLL_POSTDIV2_SHIFT		= 12,
72 	PLL_POSTDIV2_MASK		= 0x7 << PLL_POSTDIV2_SHIFT,
73 	PLL_POSTDIV1_SHIFT		= 8,
74 	PLL_POSTDIV1_MASK		= 0x7 << PLL_POSTDIV1_SHIFT,
75 	PLL_REFDIV_MASK			= 0x3f,
76 	PLL_REFDIV_SHIFT		= 0,
77 
78 	/* PLL_CON2 */
79 	PLL_LOCK_STATUS_SHIFT		= 31,
80 	PLL_LOCK_STATUS_MASK		= 1 << PLL_LOCK_STATUS_SHIFT,
81 	PLL_FRACDIV_MASK		= 0xffffff,
82 	PLL_FRACDIV_SHIFT		= 0,
83 
84 	/* PLL_CON3 */
85 	PLL_MODE_SHIFT			= 8,
86 	PLL_MODE_MASK			= 3 << PLL_MODE_SHIFT,
87 	PLL_MODE_SLOW			= 0,
88 	PLL_MODE_NORM,
89 	PLL_MODE_DEEP,
90 	PLL_DSMPD_SHIFT			= 3,
91 	PLL_DSMPD_MASK			= 1 << PLL_DSMPD_SHIFT,
92 	PLL_INTEGER_MODE		= 1,
93 
94 	/* PMUCRU_CLKSEL_CON0 */
95 	PMU_PCLK_DIV_CON_MASK		= 0x1f,
96 	PMU_PCLK_DIV_CON_SHIFT		= 0,
97 
98 	/* PMUCRU_CLKSEL_CON1 */
99 	SPI3_PLL_SEL_SHIFT		= 7,
100 	SPI3_PLL_SEL_MASK		= 1 << SPI3_PLL_SEL_SHIFT,
101 	SPI3_PLL_SEL_24M		= 0,
102 	SPI3_PLL_SEL_PPLL		= 1,
103 	SPI3_DIV_CON_SHIFT		= 0x0,
104 	SPI3_DIV_CON_MASK		= 0x7f,
105 
106 	/* PMUCRU_CLKSEL_CON2 */
107 	I2C_DIV_CON_MASK		= 0x7f,
108 	CLK_I2C8_DIV_CON_SHIFT		= 8,
109 	CLK_I2C0_DIV_CON_SHIFT		= 0,
110 
111 	/* PMUCRU_CLKSEL_CON3 */
112 	CLK_I2C4_DIV_CON_SHIFT		= 0,
113 
114 	/* CLKSEL_CON0 */
115 	ACLKM_CORE_L_DIV_CON_SHIFT	= 8,
116 	ACLKM_CORE_L_DIV_CON_MASK	= 0x1f << ACLKM_CORE_L_DIV_CON_SHIFT,
117 	CLK_CORE_L_PLL_SEL_SHIFT	= 6,
118 	CLK_CORE_L_PLL_SEL_MASK		= 3 << CLK_CORE_L_PLL_SEL_SHIFT,
119 	CLK_CORE_L_PLL_SEL_ALPLL	= 0x0,
120 	CLK_CORE_L_PLL_SEL_ABPLL	= 0x1,
121 	CLK_CORE_L_PLL_SEL_DPLL		= 0x10,
122 	CLK_CORE_L_PLL_SEL_GPLL		= 0x11,
123 	CLK_CORE_L_DIV_MASK		= 0x1f,
124 	CLK_CORE_L_DIV_SHIFT		= 0,
125 
126 	/* CLKSEL_CON1 */
127 	PCLK_DBG_L_DIV_SHIFT		= 0x8,
128 	PCLK_DBG_L_DIV_MASK		= 0x1f << PCLK_DBG_L_DIV_SHIFT,
129 	ATCLK_CORE_L_DIV_SHIFT		= 0,
130 	ATCLK_CORE_L_DIV_MASK		= 0x1f << ATCLK_CORE_L_DIV_SHIFT,
131 
132 	/* CLKSEL_CON14 */
133 	PCLK_PERIHP_DIV_CON_SHIFT	= 12,
134 	PCLK_PERIHP_DIV_CON_MASK	= 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
135 	HCLK_PERIHP_DIV_CON_SHIFT	= 8,
136 	HCLK_PERIHP_DIV_CON_MASK	= 3 << HCLK_PERIHP_DIV_CON_SHIFT,
137 	ACLK_PERIHP_PLL_SEL_SHIFT	= 7,
138 	ACLK_PERIHP_PLL_SEL_MASK	= 1 << ACLK_PERIHP_PLL_SEL_SHIFT,
139 	ACLK_PERIHP_PLL_SEL_CPLL	= 0,
140 	ACLK_PERIHP_PLL_SEL_GPLL	= 1,
141 	ACLK_PERIHP_DIV_CON_SHIFT	= 0,
142 	ACLK_PERIHP_DIV_CON_MASK	= 0x1f,
143 
144 	/* CLKSEL_CON21 */
145 	ACLK_EMMC_PLL_SEL_SHIFT         = 7,
146 	ACLK_EMMC_PLL_SEL_MASK          = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT,
147 	ACLK_EMMC_PLL_SEL_GPLL          = 0x1,
148 	ACLK_EMMC_DIV_CON_SHIFT         = 0,
149 	ACLK_EMMC_DIV_CON_MASK          = 0x1f,
150 
151 	/* CLKSEL_CON22 */
152 	CLK_EMMC_PLL_SHIFT              = 8,
153 	CLK_EMMC_PLL_MASK               = 0x7 << CLK_EMMC_PLL_SHIFT,
154 	CLK_EMMC_PLL_SEL_GPLL           = 0x1,
155 	CLK_EMMC_PLL_SEL_24M            = 0x5,
156 	CLK_EMMC_DIV_CON_SHIFT          = 0,
157 	CLK_EMMC_DIV_CON_MASK           = 0x7f << CLK_EMMC_DIV_CON_SHIFT,
158 
159 	/* CLKSEL_CON23 */
160 	PCLK_PERILP0_DIV_CON_SHIFT	= 12,
161 	PCLK_PERILP0_DIV_CON_MASK	= 0x7 << PCLK_PERILP0_DIV_CON_SHIFT,
162 	HCLK_PERILP0_DIV_CON_SHIFT	= 8,
163 	HCLK_PERILP0_DIV_CON_MASK	= 3 << HCLK_PERILP0_DIV_CON_SHIFT,
164 	ACLK_PERILP0_PLL_SEL_SHIFT	= 7,
165 	ACLK_PERILP0_PLL_SEL_MASK	= 1 << ACLK_PERILP0_PLL_SEL_SHIFT,
166 	ACLK_PERILP0_PLL_SEL_CPLL	= 0,
167 	ACLK_PERILP0_PLL_SEL_GPLL	= 1,
168 	ACLK_PERILP0_DIV_CON_SHIFT	= 0,
169 	ACLK_PERILP0_DIV_CON_MASK	= 0x1f,
170 
171 	/* CLKSEL_CON25 */
172 	PCLK_PERILP1_DIV_CON_SHIFT	= 8,
173 	PCLK_PERILP1_DIV_CON_MASK	= 0x7 << PCLK_PERILP1_DIV_CON_SHIFT,
174 	HCLK_PERILP1_PLL_SEL_SHIFT	= 7,
175 	HCLK_PERILP1_PLL_SEL_MASK	= 1 << HCLK_PERILP1_PLL_SEL_SHIFT,
176 	HCLK_PERILP1_PLL_SEL_CPLL	= 0,
177 	HCLK_PERILP1_PLL_SEL_GPLL	= 1,
178 	HCLK_PERILP1_DIV_CON_SHIFT	= 0,
179 	HCLK_PERILP1_DIV_CON_MASK	= 0x1f,
180 
181 	/* CLKSEL_CON26 */
182 	CLK_SARADC_DIV_CON_SHIFT	= 8,
183 	CLK_SARADC_DIV_CON_MASK		= GENMASK(15, 8),
184 	CLK_SARADC_DIV_CON_WIDTH	= 8,
185 
186 	/* CLKSEL_CON27 */
187 	CLK_TSADC_SEL_X24M		= 0x0,
188 	CLK_TSADC_SEL_SHIFT		= 15,
189 	CLK_TSADC_SEL_MASK		= 1 << CLK_TSADC_SEL_SHIFT,
190 	CLK_TSADC_DIV_CON_SHIFT		= 0,
191 	CLK_TSADC_DIV_CON_MASK		= 0x3ff,
192 
193 	/* CLKSEL_CON47 & CLKSEL_CON48 */
194 	ACLK_VOP_PLL_SEL_SHIFT		= 6,
195 	ACLK_VOP_PLL_SEL_MASK		= 0x3 << ACLK_VOP_PLL_SEL_SHIFT,
196 	ACLK_VOP_PLL_SEL_CPLL		= 0x1,
197 	ACLK_VOP_DIV_CON_SHIFT		= 0,
198 	ACLK_VOP_DIV_CON_MASK		= 0x1f << ACLK_VOP_DIV_CON_SHIFT,
199 
200 	/* CLKSEL_CON49 & CLKSEL_CON50 */
201 	DCLK_VOP_DCLK_SEL_SHIFT         = 11,
202 	DCLK_VOP_DCLK_SEL_MASK          = 1 << DCLK_VOP_DCLK_SEL_SHIFT,
203 	DCLK_VOP_DCLK_SEL_DIVOUT        = 0,
204 	DCLK_VOP_PLL_SEL_SHIFT          = 8,
205 	DCLK_VOP_PLL_SEL_MASK           = 3 << DCLK_VOP_PLL_SEL_SHIFT,
206 	DCLK_VOP_PLL_SEL_VPLL           = 0,
207 	DCLK_VOP_DIV_CON_MASK           = 0xff,
208 	DCLK_VOP_DIV_CON_SHIFT          = 0,
209 
210 	/* CLKSEL_CON58 */
211 	CLK_SPI_PLL_SEL_WIDTH = 1,
212 	CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1),
213 	CLK_SPI_PLL_SEL_CPLL = 0,
214 	CLK_SPI_PLL_SEL_GPLL = 1,
215 	CLK_SPI_PLL_DIV_CON_WIDTH = 7,
216 	CLK_SPI_PLL_DIV_CON_MASK = ((1 << CLK_SPI_PLL_DIV_CON_WIDTH) - 1),
217 
218 	CLK_SPI5_PLL_DIV_CON_SHIFT      = 8,
219 	CLK_SPI5_PLL_SEL_SHIFT	        = 15,
220 
221 	/* CLKSEL_CON59 */
222 	CLK_SPI1_PLL_SEL_SHIFT		= 15,
223 	CLK_SPI1_PLL_DIV_CON_SHIFT	= 8,
224 	CLK_SPI0_PLL_SEL_SHIFT		= 7,
225 	CLK_SPI0_PLL_DIV_CON_SHIFT	= 0,
226 
227 	/* CLKSEL_CON60 */
228 	CLK_SPI4_PLL_SEL_SHIFT		= 15,
229 	CLK_SPI4_PLL_DIV_CON_SHIFT	= 8,
230 	CLK_SPI2_PLL_SEL_SHIFT		= 7,
231 	CLK_SPI2_PLL_DIV_CON_SHIFT	= 0,
232 
233 	/* CLKSEL_CON61 */
234 	CLK_I2C_PLL_SEL_MASK		= 1,
235 	CLK_I2C_PLL_SEL_CPLL		= 0,
236 	CLK_I2C_PLL_SEL_GPLL		= 1,
237 	CLK_I2C5_PLL_SEL_SHIFT		= 15,
238 	CLK_I2C5_DIV_CON_SHIFT		= 8,
239 	CLK_I2C1_PLL_SEL_SHIFT		= 7,
240 	CLK_I2C1_DIV_CON_SHIFT		= 0,
241 
242 	/* CLKSEL_CON62 */
243 	CLK_I2C6_PLL_SEL_SHIFT		= 15,
244 	CLK_I2C6_DIV_CON_SHIFT		= 8,
245 	CLK_I2C2_PLL_SEL_SHIFT		= 7,
246 	CLK_I2C2_DIV_CON_SHIFT		= 0,
247 
248 	/* CLKSEL_CON63 */
249 	CLK_I2C7_PLL_SEL_SHIFT		= 15,
250 	CLK_I2C7_DIV_CON_SHIFT		= 8,
251 	CLK_I2C3_PLL_SEL_SHIFT		= 7,
252 	CLK_I2C3_DIV_CON_SHIFT		= 0,
253 
254 	/* CRU_SOFTRST_CON4 */
255 	RESETN_DDR0_REQ_SHIFT		= 8,
256 	RESETN_DDR0_REQ_MASK		= 1 << RESETN_DDR0_REQ_SHIFT,
257 	RESETN_DDRPHY0_REQ_SHIFT	= 9,
258 	RESETN_DDRPHY0_REQ_MASK		= 1 << RESETN_DDRPHY0_REQ_SHIFT,
259 	RESETN_DDR1_REQ_SHIFT		= 12,
260 	RESETN_DDR1_REQ_MASK		= 1 << RESETN_DDR1_REQ_SHIFT,
261 	RESETN_DDRPHY1_REQ_SHIFT	= 13,
262 	RESETN_DDRPHY1_REQ_MASK		= 1 << RESETN_DDRPHY1_REQ_SHIFT,
263 };
264 
265 #define VCO_MAX_KHZ	(3200 * (MHz / KHz))
266 #define VCO_MIN_KHZ	(800 * (MHz / KHz))
267 #define OUTPUT_MAX_KHZ	(3200 * (MHz / KHz))
268 #define OUTPUT_MIN_KHZ	(16 * (MHz / KHz))
269 
270 /*
271  *  the div restructions of pll in integer mode, these are defined in
272  *  * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
273  */
274 #define PLL_DIV_MIN	16
275 #define PLL_DIV_MAX	3200
276 
277 /*
278  * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
279  * Formulas also embedded within the Fractional PLL Verilog model:
280  * If DSMPD = 1 (DSM is disabled, "integer mode")
281  * FOUTVCO = FREF / REFDIV * FBDIV
282  * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
283  * Where:
284  * FOUTVCO = Fractional PLL non-divided output frequency
285  * FOUTPOSTDIV = Fractional PLL divided output frequency
286  *               (output of second post divider)
287  * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
288  * REFDIV = Fractional PLL input reference clock divider
289  * FBDIV = Integer value programmed into feedback divide
290  *
291  */
292 static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div)
293 {
294 	/* All 8 PLLs have same VCO and output frequency range restrictions. */
295 	u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
296 	u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
297 
298 	debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, "
299 			   "postdiv2=%d, vco=%u khz, output=%u khz\n",
300 			   pll_con, div->fbdiv, div->refdiv, div->postdiv1,
301 			   div->postdiv2, vco_khz, output_khz);
302 	assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
303 	       output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
304 	       div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
305 
306 	/*
307 	 * When power on or changing PLL setting,
308 	 * we must force PLL into slow mode to ensure output stable clock.
309 	 */
310 	rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
311 		     PLL_MODE_SLOW << PLL_MODE_SHIFT);
312 
313 	/* use integer mode */
314 	rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK,
315 		     PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
316 
317 	rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK,
318 		     div->fbdiv << PLL_FBDIV_SHIFT);
319 	rk_clrsetreg(&pll_con[1],
320 		     PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK |
321 		     PLL_REFDIV_MASK | PLL_REFDIV_SHIFT,
322 		     (div->postdiv2 << PLL_POSTDIV2_SHIFT) |
323 		     (div->postdiv1 << PLL_POSTDIV1_SHIFT) |
324 		     (div->refdiv << PLL_REFDIV_SHIFT));
325 
326 	/* waiting for pll lock */
327 	while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT)))
328 		udelay(1);
329 
330 	/* pll enter normal mode */
331 	rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
332 		     PLL_MODE_NORM << PLL_MODE_SHIFT);
333 }
334 
335 static int pll_para_config(u32 freq_hz, struct pll_div *div)
336 {
337 	u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
338 	u32 postdiv1, postdiv2 = 1;
339 	u32 fref_khz;
340 	u32 diff_khz, best_diff_khz;
341 	const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
342 	const u32 max_postdiv1 = 7, max_postdiv2 = 7;
343 	u32 vco_khz;
344 	u32 freq_khz = freq_hz / KHz;
345 
346 	if (!freq_hz) {
347 		printf("%s: the frequency can't be 0 Hz\n", __func__);
348 		return -1;
349 	}
350 
351 	postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
352 	if (postdiv1 > max_postdiv1) {
353 		postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
354 		postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
355 	}
356 
357 	vco_khz = freq_khz * postdiv1 * postdiv2;
358 
359 	if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ ||
360 	    postdiv2 > max_postdiv2) {
361 		printf("%s: Cannot find out a supported VCO"
362 		       " for Frequency (%uHz).\n", __func__, freq_hz);
363 		return -1;
364 	}
365 
366 	div->postdiv1 = postdiv1;
367 	div->postdiv2 = postdiv2;
368 
369 	best_diff_khz = vco_khz;
370 	for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
371 		fref_khz = ref_khz / refdiv;
372 
373 		fbdiv = vco_khz / fref_khz;
374 		if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
375 			continue;
376 		diff_khz = vco_khz - fbdiv * fref_khz;
377 		if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
378 			fbdiv++;
379 			diff_khz = fref_khz - diff_khz;
380 		}
381 
382 		if (diff_khz >= best_diff_khz)
383 			continue;
384 
385 		best_diff_khz = diff_khz;
386 		div->refdiv = refdiv;
387 		div->fbdiv = fbdiv;
388 	}
389 
390 	if (best_diff_khz > 4 * (MHz/KHz)) {
391 		printf("%s: Failed to match output frequency %u, "
392 		       "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
393 		       best_diff_khz * KHz);
394 		return -1;
395 	}
396 	return 0;
397 }
398 
399 void rk3399_configure_cpu(struct rk3399_cru *cru,
400 			  enum apll_l_frequencies apll_l_freq)
401 {
402 	u32 aclkm_div;
403 	u32 pclk_dbg_div;
404 	u32 atclk_div;
405 
406 	rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
407 
408 	aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1;
409 	assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ &&
410 	       aclkm_div < 0x1f);
411 
412 	pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1;
413 	assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ &&
414 	       pclk_dbg_div < 0x1f);
415 
416 	atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1;
417 	assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ &&
418 	       atclk_div < 0x1f);
419 
420 	rk_clrsetreg(&cru->clksel_con[0],
421 		     ACLKM_CORE_L_DIV_CON_MASK | CLK_CORE_L_PLL_SEL_MASK |
422 		     CLK_CORE_L_DIV_MASK,
423 		     aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT |
424 		     CLK_CORE_L_PLL_SEL_ALPLL << CLK_CORE_L_PLL_SEL_SHIFT |
425 		     0 << CLK_CORE_L_DIV_SHIFT);
426 
427 	rk_clrsetreg(&cru->clksel_con[1],
428 		     PCLK_DBG_L_DIV_MASK | ATCLK_CORE_L_DIV_MASK,
429 		     pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
430 		     atclk_div << ATCLK_CORE_L_DIV_SHIFT);
431 }
432 #define I2C_CLK_REG_MASK(bus) \
433 			(I2C_DIV_CON_MASK << \
434 			CLK_I2C ##bus## _DIV_CON_SHIFT | \
435 			CLK_I2C_PLL_SEL_MASK << \
436 			CLK_I2C ##bus## _PLL_SEL_SHIFT)
437 
438 #define I2C_CLK_REG_VALUE(bus, clk_div) \
439 			      ((clk_div - 1) << \
440 					CLK_I2C ##bus## _DIV_CON_SHIFT | \
441 			      CLK_I2C_PLL_SEL_GPLL << \
442 					CLK_I2C ##bus## _PLL_SEL_SHIFT)
443 
444 #define I2C_CLK_DIV_VALUE(con, bus) \
445 			(con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \
446 				I2C_DIV_CON_MASK;
447 
448 #define I2C_PMUCLK_REG_MASK(bus) \
449 			(I2C_DIV_CON_MASK << \
450 			 CLK_I2C ##bus## _DIV_CON_SHIFT)
451 
452 #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \
453 				((clk_div - 1) << \
454 				CLK_I2C ##bus## _DIV_CON_SHIFT)
455 
456 static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id)
457 {
458 	u32 div, con;
459 
460 	switch (clk_id) {
461 	case SCLK_I2C1:
462 		con = readl(&cru->clksel_con[61]);
463 		div = I2C_CLK_DIV_VALUE(con, 1);
464 		break;
465 	case SCLK_I2C2:
466 		con = readl(&cru->clksel_con[62]);
467 		div = I2C_CLK_DIV_VALUE(con, 2);
468 		break;
469 	case SCLK_I2C3:
470 		con = readl(&cru->clksel_con[63]);
471 		div = I2C_CLK_DIV_VALUE(con, 3);
472 		break;
473 	case SCLK_I2C5:
474 		con = readl(&cru->clksel_con[61]);
475 		div = I2C_CLK_DIV_VALUE(con, 5);
476 		break;
477 	case SCLK_I2C6:
478 		con = readl(&cru->clksel_con[62]);
479 		div = I2C_CLK_DIV_VALUE(con, 6);
480 		break;
481 	case SCLK_I2C7:
482 		con = readl(&cru->clksel_con[63]);
483 		div = I2C_CLK_DIV_VALUE(con, 7);
484 		break;
485 	default:
486 		printf("do not support this i2c bus\n");
487 		return -EINVAL;
488 	}
489 
490 	return DIV_TO_RATE(GPLL_HZ, div);
491 }
492 
493 static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
494 {
495 	int src_clk_div;
496 
497 	/* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
498 	src_clk_div = GPLL_HZ / hz;
499 	assert(src_clk_div - 1 < 127);
500 
501 	switch (clk_id) {
502 	case SCLK_I2C1:
503 		rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(1),
504 			     I2C_CLK_REG_VALUE(1, src_clk_div));
505 		break;
506 	case SCLK_I2C2:
507 		rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(2),
508 			     I2C_CLK_REG_VALUE(2, src_clk_div));
509 		break;
510 	case SCLK_I2C3:
511 		rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(3),
512 			     I2C_CLK_REG_VALUE(3, src_clk_div));
513 		break;
514 	case SCLK_I2C5:
515 		rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(5),
516 			     I2C_CLK_REG_VALUE(5, src_clk_div));
517 		break;
518 	case SCLK_I2C6:
519 		rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(6),
520 			     I2C_CLK_REG_VALUE(6, src_clk_div));
521 		break;
522 	case SCLK_I2C7:
523 		rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(7),
524 			     I2C_CLK_REG_VALUE(7, src_clk_div));
525 		break;
526 	default:
527 		printf("do not support this i2c bus\n");
528 		return -EINVAL;
529 	}
530 
531 	return rk3399_i2c_get_clk(cru, clk_id);
532 }
533 
534 /*
535  * RK3399 SPI clocks have a common divider-width (7 bits) and a single bit
536  * to select either CPLL or GPLL as the clock-parent. The location within
537  * the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable.
538  */
539 
540 struct spi_clkreg {
541 	uint8_t reg;  /* CLKSEL_CON[reg] register in CRU */
542 	uint8_t div_shift;
543 	uint8_t sel_shift;
544 };
545 
546 /*
547  * The entries are numbered relative to their offset from SCLK_SPI0.
548  *
549  * Note that SCLK_SPI3 (which is configured via PMUCRU and requires different
550  * logic is not supported).
551  */
552 static const struct spi_clkreg spi_clkregs[] = {
553 	[0] = { .reg = 59,
554 		.div_shift = CLK_SPI0_PLL_DIV_CON_SHIFT,
555 		.sel_shift = CLK_SPI0_PLL_SEL_SHIFT, },
556 	[1] = { .reg = 59,
557 		.div_shift = CLK_SPI1_PLL_DIV_CON_SHIFT,
558 		.sel_shift = CLK_SPI1_PLL_SEL_SHIFT, },
559 	[2] = { .reg = 60,
560 		.div_shift = CLK_SPI2_PLL_DIV_CON_SHIFT,
561 		.sel_shift = CLK_SPI2_PLL_SEL_SHIFT, },
562 	[3] = { .reg = 60,
563 		.div_shift = CLK_SPI4_PLL_DIV_CON_SHIFT,
564 		.sel_shift = CLK_SPI4_PLL_SEL_SHIFT, },
565 	[4] = { .reg = 58,
566 		.div_shift = CLK_SPI5_PLL_DIV_CON_SHIFT,
567 		.sel_shift = CLK_SPI5_PLL_SEL_SHIFT, },
568 };
569 
570 static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id)
571 {
572 	const struct spi_clkreg *spiclk = NULL;
573 	u32 div, val;
574 
575 	switch (clk_id) {
576 	case SCLK_SPI0 ... SCLK_SPI5:
577 		spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
578 		break;
579 
580 	default:
581 		pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
582 		return -EINVAL;
583 	}
584 
585 	val = readl(&cru->clksel_con[spiclk->reg]);
586 	div = bitfield_extract(val, spiclk->div_shift,
587 			       CLK_SPI_PLL_DIV_CON_WIDTH);
588 
589 	return DIV_TO_RATE(GPLL_HZ, div);
590 }
591 
592 static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
593 {
594 	const struct spi_clkreg *spiclk = NULL;
595 	int src_clk_div;
596 
597 	src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
598 	assert(src_clk_div < 128);
599 
600 	switch (clk_id) {
601 	case SCLK_SPI1 ... SCLK_SPI5:
602 		spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
603 		break;
604 
605 	default:
606 		pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
607 		return -EINVAL;
608 	}
609 
610 	rk_clrsetreg(&cru->clksel_con[spiclk->reg],
611 		     ((CLK_SPI_PLL_DIV_CON_MASK << spiclk->div_shift) |
612 		       (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)),
613 		     ((src_clk_div << spiclk->div_shift) |
614 		      (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)));
615 
616 	return rk3399_spi_get_clk(cru, clk_id);
617 }
618 
619 static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
620 {
621 	struct pll_div vpll_config = {0};
622 	int aclk_vop = 198*MHz;
623 	void *aclkreg_addr, *dclkreg_addr;
624 	u32 div;
625 
626 	switch (clk_id) {
627 	case DCLK_VOP0:
628 		aclkreg_addr = &cru->clksel_con[47];
629 		dclkreg_addr = &cru->clksel_con[49];
630 		break;
631 	case DCLK_VOP1:
632 		aclkreg_addr = &cru->clksel_con[48];
633 		dclkreg_addr = &cru->clksel_con[50];
634 		break;
635 	default:
636 		return -EINVAL;
637 	}
638 	/* vop aclk source clk: cpll */
639 	div = CPLL_HZ / aclk_vop;
640 	assert(div - 1 < 32);
641 
642 	rk_clrsetreg(aclkreg_addr,
643 		     ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
644 		     ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
645 		     (div - 1) << ACLK_VOP_DIV_CON_SHIFT);
646 
647 	/* vop dclk source from vpll, and equals to vpll(means div == 1) */
648 	if (pll_para_config(hz, &vpll_config))
649 		return -1;
650 
651 	rkclk_set_pll(&cru->vpll_con[0], &vpll_config);
652 
653 	rk_clrsetreg(dclkreg_addr,
654 		     DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK|
655 		     DCLK_VOP_DIV_CON_MASK,
656 		     DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT |
657 		     DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT |
658 		     (1 - 1) << DCLK_VOP_DIV_CON_SHIFT);
659 
660 	return hz;
661 }
662 
663 static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
664 {
665 	u32 div, con;
666 
667 	switch (clk_id) {
668 	case HCLK_SDMMC:
669 	case SCLK_SDMMC:
670 		con = readl(&cru->clksel_con[16]);
671 		/* dwmmc controller have internal div 2 */
672 		div = 2;
673 		break;
674 	case SCLK_EMMC:
675 		con = readl(&cru->clksel_con[21]);
676 		div = 1;
677 		break;
678 	default:
679 		return -EINVAL;
680 	}
681 
682 	div *= (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
683 	if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
684 			== CLK_EMMC_PLL_SEL_24M)
685 		return DIV_TO_RATE(OSC_HZ, div);
686 	else
687 		return DIV_TO_RATE(GPLL_HZ, div);
688 }
689 
690 static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
691 				ulong clk_id, ulong set_rate)
692 {
693 	int src_clk_div;
694 	int aclk_emmc = 198*MHz;
695 
696 	switch (clk_id) {
697 	case HCLK_SDMMC:
698 	case SCLK_SDMMC:
699 		/* Select clk_sdmmc source from GPLL by default */
700 		/* mmc clock defaulg div 2 internal, provide double in cru */
701 		src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
702 
703 		if (src_clk_div > 128) {
704 			/* use 24MHz source for 400KHz clock */
705 			src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
706 			assert(src_clk_div - 1 < 128);
707 			rk_clrsetreg(&cru->clksel_con[16],
708 				     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
709 				     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
710 				     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
711 		} else {
712 			rk_clrsetreg(&cru->clksel_con[16],
713 				     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
714 				     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
715 				     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
716 		}
717 		break;
718 	case SCLK_EMMC:
719 		/* Select aclk_emmc source from GPLL */
720 		src_clk_div = DIV_ROUND_UP(GPLL_HZ , aclk_emmc);
721 		assert(src_clk_div - 1 < 32);
722 
723 		rk_clrsetreg(&cru->clksel_con[21],
724 			     ACLK_EMMC_PLL_SEL_MASK | ACLK_EMMC_DIV_CON_MASK,
725 			     ACLK_EMMC_PLL_SEL_GPLL << ACLK_EMMC_PLL_SEL_SHIFT |
726 			     (src_clk_div - 1) << ACLK_EMMC_DIV_CON_SHIFT);
727 
728 		/* Select clk_emmc source from GPLL too */
729 		src_clk_div = DIV_ROUND_UP(GPLL_HZ, set_rate);
730 		assert(src_clk_div - 1 < 128);
731 
732 		rk_clrsetreg(&cru->clksel_con[22],
733 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
734 			     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
735 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
736 		break;
737 	default:
738 		return -EINVAL;
739 	}
740 	return rk3399_mmc_get_clk(cru, clk_id);
741 }
742 
743 static ulong rk3399_gmac_set_clk(struct rk3399_cru *cru, ulong rate)
744 {
745 	ulong ret;
746 
747 	/*
748 	 * The RGMII CLK can be derived either from an external "clkin"
749 	 * or can be generated from internally by a divider from SCLK_MAC.
750 	 */
751 	if (readl(&cru->clksel_con[19]) & BIT(4)) {
752 		/* An external clock will always generate the right rate... */
753 		ret = rate;
754 	} else {
755 		/*
756 		 * No platform uses an internal clock to date.
757 		 * Implement this once it becomes necessary and print an error
758 		 * if someone tries to use it (while it remains unimplemented).
759 		 */
760 		pr_err("%s: internal clock is UNIMPLEMENTED\n", __func__);
761 		ret = 0;
762 	}
763 
764 	return ret;
765 }
766 
767 #define PMUSGRF_DDR_RGN_CON16 0xff330040
768 static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
769 				ulong set_rate)
770 {
771 	struct pll_div dpll_cfg;
772 
773 	/*  IC ECO bug, need to set this register */
774 	writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
775 
776 	/*  clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
777 	switch (set_rate) {
778 	case 200*MHz:
779 		dpll_cfg = (struct pll_div)
780 		{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
781 		break;
782 	case 300*MHz:
783 		dpll_cfg = (struct pll_div)
784 		{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
785 		break;
786 	case 666*MHz:
787 		dpll_cfg = (struct pll_div)
788 		{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
789 		break;
790 	case 800*MHz:
791 		dpll_cfg = (struct pll_div)
792 		{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
793 		break;
794 	case 933*MHz:
795 		dpll_cfg = (struct pll_div)
796 		{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
797 		break;
798 	default:
799 		pr_err("Unsupported SDRAM frequency!,%ld\n", set_rate);
800 	}
801 	rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
802 
803 	return set_rate;
804 }
805 
806 static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
807 {
808 	u32 div, val;
809 
810 	val = readl(&cru->clksel_con[26]);
811 	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
812 			       CLK_SARADC_DIV_CON_WIDTH);
813 
814 	return DIV_TO_RATE(OSC_HZ, div);
815 }
816 
817 static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz)
818 {
819 	int src_clk_div;
820 
821 	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
822 	assert(src_clk_div < 128);
823 
824 	rk_clrsetreg(&cru->clksel_con[26],
825 		     CLK_SARADC_DIV_CON_MASK,
826 		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
827 
828 	return rk3399_saradc_get_clk(cru);
829 }
830 
831 static ulong rk3399_clk_get_rate(struct clk *clk)
832 {
833 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
834 	ulong rate = 0;
835 
836 	switch (clk->id) {
837 	case 0 ... 63:
838 		return 0;
839 	case HCLK_SDMMC:
840 	case SCLK_SDMMC:
841 	case SCLK_EMMC:
842 		rate = rk3399_mmc_get_clk(priv->cru, clk->id);
843 		break;
844 	case SCLK_I2C1:
845 	case SCLK_I2C2:
846 	case SCLK_I2C3:
847 	case SCLK_I2C5:
848 	case SCLK_I2C6:
849 	case SCLK_I2C7:
850 		rate = rk3399_i2c_get_clk(priv->cru, clk->id);
851 		break;
852 	case SCLK_SPI0...SCLK_SPI5:
853 		rate = rk3399_spi_get_clk(priv->cru, clk->id);
854 		break;
855 	case SCLK_UART0:
856 	case SCLK_UART2:
857 		return 24000000;
858 		break;
859 	case PCLK_HDMI_CTRL:
860 		break;
861 	case DCLK_VOP0:
862 	case DCLK_VOP1:
863 		break;
864 	case PCLK_EFUSE1024NS:
865 		break;
866 	case SCLK_SARADC:
867 		rate = rk3399_saradc_get_clk(priv->cru);
868 		break;
869 	default:
870 		return -ENOENT;
871 	}
872 
873 	return rate;
874 }
875 
876 static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
877 {
878 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
879 	ulong ret = 0;
880 
881 	switch (clk->id) {
882 	case 0 ... 63:
883 		return 0;
884 
885 	case ACLK_PERIHP:
886 	case HCLK_PERIHP:
887 	case PCLK_PERIHP:
888 		return 0;
889 
890 	case ACLK_PERILP0:
891 	case HCLK_PERILP0:
892 	case PCLK_PERILP0:
893 		return 0;
894 
895 	case ACLK_CCI:
896 		return 0;
897 
898 	case HCLK_PERILP1:
899 	case PCLK_PERILP1:
900 		return 0;
901 
902 	case HCLK_SDMMC:
903 	case SCLK_SDMMC:
904 	case SCLK_EMMC:
905 		ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate);
906 		break;
907 	case SCLK_MAC:
908 		ret = rk3399_gmac_set_clk(priv->cru, rate);
909 		break;
910 	case SCLK_I2C1:
911 	case SCLK_I2C2:
912 	case SCLK_I2C3:
913 	case SCLK_I2C5:
914 	case SCLK_I2C6:
915 	case SCLK_I2C7:
916 		ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate);
917 		break;
918 	case SCLK_SPI0...SCLK_SPI5:
919 		ret = rk3399_spi_set_clk(priv->cru, clk->id, rate);
920 		break;
921 	case PCLK_HDMI_CTRL:
922 	case PCLK_VIO_GRF:
923 		/* the PCLK gates for video are enabled by default */
924 		break;
925 	case DCLK_VOP0:
926 	case DCLK_VOP1:
927 		ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
928 		break;
929 	case SCLK_DDRCLK:
930 		ret = rk3399_ddr_set_clk(priv->cru, rate);
931 		break;
932 	case PCLK_EFUSE1024NS:
933 		break;
934 	case SCLK_SARADC:
935 		ret = rk3399_saradc_set_clk(priv->cru, rate);
936 		break;
937 	default:
938 		return -ENOENT;
939 	}
940 
941 	return ret;
942 }
943 
944 static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *parent)
945 {
946 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
947 	const char *clock_output_name;
948 	int ret;
949 
950 	/*
951 	 * If the requested parent is in the same clock-controller and
952 	 * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock.
953 	 */
954 	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) {
955 		debug("%s: switching RGMII to SCLK_MAC\n", __func__);
956 		rk_clrreg(&priv->cru->clksel_con[19], BIT(4));
957 		return 0;
958 	}
959 
960 	/*
961 	 * Otherwise, we need to check the clock-output-names of the
962 	 * requested parent to see if the requested id is "clkin_gmac".
963 	 */
964 	ret = dev_read_string_index(parent->dev, "clock-output-names",
965 				    parent->id, &clock_output_name);
966 	if (ret < 0)
967 		return -ENODATA;
968 
969 	/* If this is "clkin_gmac", switch to the external clock input */
970 	if (!strcmp(clock_output_name, "clkin_gmac")) {
971 		debug("%s: switching RGMII to CLKIN\n", __func__);
972 		rk_setreg(&priv->cru->clksel_con[19], BIT(4));
973 		return 0;
974 	}
975 
976 	return -EINVAL;
977 }
978 
979 static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent)
980 {
981 	switch (clk->id) {
982 	case SCLK_RMII_SRC:
983 		return rk3399_gmac_set_parent(clk, parent);
984 	}
985 
986 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
987 	return -ENOENT;
988 }
989 
990 static int rk3399_clk_enable(struct clk *clk)
991 {
992 	switch (clk->id) {
993 	case HCLK_HOST0:
994 	case HCLK_HOST0_ARB:
995 	case HCLK_HOST1:
996 	case HCLK_HOST1_ARB:
997 		return 0;
998 
999 	case SCLK_MAC:
1000 	case SCLK_MAC_RX:
1001 	case SCLK_MAC_TX:
1002 	case SCLK_MACREF:
1003 	case SCLK_MACREF_OUT:
1004 	case ACLK_GMAC:
1005 	case PCLK_GMAC:
1006 		/* Required to successfully probe the Designware GMAC driver */
1007 		return 0;
1008 	}
1009 
1010 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
1011 	return -ENOENT;
1012 }
1013 
1014 static struct clk_ops rk3399_clk_ops = {
1015 	.get_rate = rk3399_clk_get_rate,
1016 	.set_rate = rk3399_clk_set_rate,
1017 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1018 	.set_parent = rk3399_clk_set_parent,
1019 #endif
1020 	.enable = rk3399_clk_enable,
1021 };
1022 
1023 #ifdef CONFIG_SPL_BUILD
1024 static void rkclk_init(struct rk3399_cru *cru)
1025 {
1026 	u32 aclk_div;
1027 	u32 hclk_div;
1028 	u32 pclk_div;
1029 
1030 	rk3399_configure_cpu(cru, APLL_L_600_MHZ);
1031 	/*
1032 	 * some cru registers changed by bootrom, we'd better reset them to
1033 	 * reset/default values described in TRM to avoid confusion in kernel.
1034 	 * Please consider these three lines as a fix of bootrom bug.
1035 	 */
1036 	rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101);
1037 	rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f);
1038 	rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003);
1039 
1040 	/* configure gpll cpll */
1041 	rkclk_set_pll(&cru->gpll_con[0], &gpll_init_cfg);
1042 	rkclk_set_pll(&cru->cpll_con[0], &cpll_init_cfg);
1043 
1044 	/* configure perihp aclk, hclk, pclk */
1045 	aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
1046 	assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
1047 
1048 	hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
1049 	assert((hclk_div + 1) * PERIHP_HCLK_HZ ==
1050 	       PERIHP_ACLK_HZ && (hclk_div < 0x4));
1051 
1052 	pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
1053 	assert((pclk_div + 1) * PERIHP_PCLK_HZ ==
1054 	       PERIHP_ACLK_HZ && (pclk_div < 0x7));
1055 
1056 	rk_clrsetreg(&cru->clksel_con[14],
1057 		     PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK |
1058 		     ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
1059 		     pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
1060 		     hclk_div << HCLK_PERIHP_DIV_CON_SHIFT |
1061 		     ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
1062 		     aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
1063 
1064 	/* configure perilp0 aclk, hclk, pclk */
1065 	aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1;
1066 	assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
1067 
1068 	hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1;
1069 	assert((hclk_div + 1) * PERILP0_HCLK_HZ ==
1070 	       PERILP0_ACLK_HZ && (hclk_div < 0x4));
1071 
1072 	pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1;
1073 	assert((pclk_div + 1) * PERILP0_PCLK_HZ ==
1074 	       PERILP0_ACLK_HZ && (pclk_div < 0x7));
1075 
1076 	rk_clrsetreg(&cru->clksel_con[23],
1077 		     PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK |
1078 		     ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK,
1079 		     pclk_div << PCLK_PERILP0_DIV_CON_SHIFT |
1080 		     hclk_div << HCLK_PERILP0_DIV_CON_SHIFT |
1081 		     ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT |
1082 		     aclk_div << ACLK_PERILP0_DIV_CON_SHIFT);
1083 
1084 	/* perilp1 hclk select gpll as source */
1085 	hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1;
1086 	assert((hclk_div + 1) * PERILP1_HCLK_HZ ==
1087 	       GPLL_HZ && (hclk_div < 0x1f));
1088 
1089 	pclk_div = PERILP1_HCLK_HZ / PERILP1_HCLK_HZ - 1;
1090 	assert((pclk_div + 1) * PERILP1_HCLK_HZ ==
1091 	       PERILP1_HCLK_HZ && (hclk_div < 0x7));
1092 
1093 	rk_clrsetreg(&cru->clksel_con[25],
1094 		     PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK |
1095 		     HCLK_PERILP1_PLL_SEL_MASK,
1096 		     pclk_div << PCLK_PERILP1_DIV_CON_SHIFT |
1097 		     hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
1098 		     HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
1099 }
1100 #endif
1101 
1102 static int rk3399_clk_probe(struct udevice *dev)
1103 {
1104 #ifdef CONFIG_SPL_BUILD
1105 	struct rk3399_clk_priv *priv = dev_get_priv(dev);
1106 
1107 #if CONFIG_IS_ENABLED(OF_PLATDATA)
1108 	struct rk3399_clk_plat *plat = dev_get_platdata(dev);
1109 
1110 	priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
1111 #endif
1112 	rkclk_init(priv->cru);
1113 #endif
1114 	return 0;
1115 }
1116 
1117 static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
1118 {
1119 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
1120 	struct rk3399_clk_priv *priv = dev_get_priv(dev);
1121 
1122 	priv->cru = dev_read_addr_ptr(dev);
1123 #endif
1124 	return 0;
1125 }
1126 
1127 static int rk3399_clk_bind(struct udevice *dev)
1128 {
1129 	int ret;
1130 	struct udevice *sys_child;
1131 	struct sysreset_reg *priv;
1132 
1133 	/* The reset driver does not have a device node, so bind it here */
1134 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1135 				 &sys_child);
1136 	if (ret) {
1137 		debug("Warning: No sysreset driver: ret=%d\n", ret);
1138 	} else {
1139 		priv = malloc(sizeof(struct sysreset_reg));
1140 		priv->glb_srst_fst_value = offsetof(struct rk3399_cru,
1141 						    glb_srst_fst_value);
1142 		priv->glb_srst_snd_value = offsetof(struct rk3399_cru,
1143 						    glb_srst_snd_value);
1144 		sys_child->priv = priv;
1145 	}
1146 
1147 #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
1148 	ret = offsetof(struct rk3399_cru, softrst_con[0]);
1149 	ret = rockchip_reset_bind(dev, ret, 21);
1150 	if (ret)
1151 		debug("Warning: software reset driver bind faile\n");
1152 #endif
1153 
1154 	return 0;
1155 }
1156 
1157 static const struct udevice_id rk3399_clk_ids[] = {
1158 	{ .compatible = "rockchip,rk3399-cru" },
1159 	{ }
1160 };
1161 
1162 U_BOOT_DRIVER(clk_rk3399) = {
1163 	.name		= "rockchip_rk3399_cru",
1164 	.id		= UCLASS_CLK,
1165 	.of_match	= rk3399_clk_ids,
1166 	.priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
1167 	.ofdata_to_platdata = rk3399_clk_ofdata_to_platdata,
1168 	.ops		= &rk3399_clk_ops,
1169 	.bind		= rk3399_clk_bind,
1170 	.probe		= rk3399_clk_probe,
1171 #if CONFIG_IS_ENABLED(OF_PLATDATA)
1172 	.platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
1173 #endif
1174 };
1175 
1176 static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
1177 {
1178 	u32 div, con;
1179 
1180 	switch (clk_id) {
1181 	case SCLK_I2C0_PMU:
1182 		con = readl(&pmucru->pmucru_clksel[2]);
1183 		div = I2C_CLK_DIV_VALUE(con, 0);
1184 		break;
1185 	case SCLK_I2C4_PMU:
1186 		con = readl(&pmucru->pmucru_clksel[3]);
1187 		div = I2C_CLK_DIV_VALUE(con, 4);
1188 		break;
1189 	case SCLK_I2C8_PMU:
1190 		con = readl(&pmucru->pmucru_clksel[2]);
1191 		div = I2C_CLK_DIV_VALUE(con, 8);
1192 		break;
1193 	default:
1194 		printf("do not support this i2c bus\n");
1195 		return -EINVAL;
1196 	}
1197 
1198 	return DIV_TO_RATE(PPLL_HZ, div);
1199 }
1200 
1201 static ulong rk3399_i2c_set_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id,
1202 				   uint hz)
1203 {
1204 	int src_clk_div;
1205 
1206 	src_clk_div = PPLL_HZ / hz;
1207 	assert(src_clk_div - 1 < 127);
1208 
1209 	switch (clk_id) {
1210 	case SCLK_I2C0_PMU:
1211 		rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(0),
1212 			     I2C_PMUCLK_REG_VALUE(0, src_clk_div));
1213 		break;
1214 	case SCLK_I2C4_PMU:
1215 		rk_clrsetreg(&pmucru->pmucru_clksel[3], I2C_PMUCLK_REG_MASK(4),
1216 			     I2C_PMUCLK_REG_VALUE(4, src_clk_div));
1217 		break;
1218 	case SCLK_I2C8_PMU:
1219 		rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(8),
1220 			     I2C_PMUCLK_REG_VALUE(8, src_clk_div));
1221 		break;
1222 	default:
1223 		printf("do not support this i2c bus\n");
1224 		return -EINVAL;
1225 	}
1226 
1227 	return DIV_TO_RATE(PPLL_HZ, src_clk_div);
1228 }
1229 
1230 static ulong rk3399_pwm_get_clk(struct rk3399_pmucru *pmucru)
1231 {
1232 	u32 div, con;
1233 
1234 	/* PWM closk rate is same as pclk_pmu */
1235 	con = readl(&pmucru->pmucru_clksel[0]);
1236 	div = con & PMU_PCLK_DIV_CON_MASK;
1237 
1238 	return DIV_TO_RATE(PPLL_HZ, div);
1239 }
1240 
1241 static ulong rk3399_pmuclk_get_rate(struct clk *clk)
1242 {
1243 	struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
1244 	ulong rate = 0;
1245 
1246 	switch (clk->id) {
1247 	case PLL_PPLL:
1248 		return PPLL_HZ;
1249 	case PCLK_RKPWM_PMU:
1250 		rate = rk3399_pwm_get_clk(priv->pmucru);
1251 		break;
1252 	case SCLK_I2C0_PMU:
1253 	case SCLK_I2C4_PMU:
1254 	case SCLK_I2C8_PMU:
1255 		rate = rk3399_i2c_get_pmuclk(priv->pmucru, clk->id);
1256 		break;
1257 	default:
1258 		return -ENOENT;
1259 	}
1260 
1261 	return rate;
1262 }
1263 
1264 static ulong rk3399_pmuclk_set_rate(struct clk *clk, ulong rate)
1265 {
1266 	struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
1267 	ulong ret = 0;
1268 
1269 	switch (clk->id) {
1270 	case PLL_PPLL:
1271 		/*
1272 		 * This has already been set up and we don't want/need
1273 		 * to change it here.  Accept the request though, as the
1274 		 * device-tree has this in an 'assigned-clocks' list.
1275 		 */
1276 		return PPLL_HZ;
1277 	case SCLK_I2C0_PMU:
1278 	case SCLK_I2C4_PMU:
1279 	case SCLK_I2C8_PMU:
1280 		ret = rk3399_i2c_set_pmuclk(priv->pmucru, clk->id, rate);
1281 		break;
1282 	default:
1283 		return -ENOENT;
1284 	}
1285 
1286 	return ret;
1287 }
1288 
1289 static struct clk_ops rk3399_pmuclk_ops = {
1290 	.get_rate = rk3399_pmuclk_get_rate,
1291 	.set_rate = rk3399_pmuclk_set_rate,
1292 };
1293 
1294 #ifndef CONFIG_SPL_BUILD
1295 static void pmuclk_init(struct rk3399_pmucru *pmucru)
1296 {
1297 	u32 pclk_div;
1298 
1299 	/*  configure pmu pll(ppll) */
1300 	rkclk_set_pll(&pmucru->ppll_con[0], &ppll_init_cfg);
1301 
1302 	/*  configure pmu pclk */
1303 	pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
1304 	rk_clrsetreg(&pmucru->pmucru_clksel[0],
1305 		     PMU_PCLK_DIV_CON_MASK,
1306 		     pclk_div << PMU_PCLK_DIV_CON_SHIFT);
1307 }
1308 #endif
1309 
1310 static int rk3399_pmuclk_probe(struct udevice *dev)
1311 {
1312 #if CONFIG_IS_ENABLED(OF_PLATDATA) || !defined(CONFIG_SPL_BUILD)
1313 	struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
1314 #endif
1315 
1316 #if CONFIG_IS_ENABLED(OF_PLATDATA)
1317 	struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
1318 
1319 	priv->pmucru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
1320 #endif
1321 
1322 #ifndef CONFIG_SPL_BUILD
1323 	pmuclk_init(priv->pmucru);
1324 #endif
1325 	return 0;
1326 }
1327 
1328 static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
1329 {
1330 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
1331 	struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
1332 
1333 	priv->pmucru = dev_read_addr_ptr(dev);
1334 #endif
1335 	return 0;
1336 }
1337 
1338 static int rk3399_pmuclk_bind(struct udevice *dev)
1339 {
1340 #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
1341 	int ret;
1342 
1343 	ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]);
1344 	ret = rockchip_reset_bind(dev, ret, 2);
1345 	if (ret)
1346 		debug("Warning: software reset driver bind faile\n");
1347 #endif
1348 	return 0;
1349 }
1350 
1351 static const struct udevice_id rk3399_pmuclk_ids[] = {
1352 	{ .compatible = "rockchip,rk3399-pmucru" },
1353 	{ }
1354 };
1355 
1356 U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
1357 	.name		= "rockchip_rk3399_pmucru",
1358 	.id		= UCLASS_CLK,
1359 	.of_match	= rk3399_pmuclk_ids,
1360 	.priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
1361 	.ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
1362 	.ops		= &rk3399_pmuclk_ops,
1363 	.probe		= rk3399_pmuclk_probe,
1364 	.bind		= rk3399_pmuclk_bind,
1365 #if CONFIG_IS_ENABLED(OF_PLATDATA)
1366 	.platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
1367 #endif
1368 };
1369