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