1*41793000SKever Yang /*
2*41793000SKever Yang  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3*41793000SKever Yang  *
4*41793000SKever Yang  * SPDX-License-Identifier:	GPL-2.0
5*41793000SKever Yang  */
6*41793000SKever Yang 
7*41793000SKever Yang #include <common.h>
8*41793000SKever Yang #include <clk-uclass.h>
9*41793000SKever Yang #include <dm.h>
10*41793000SKever Yang #include <errno.h>
11*41793000SKever Yang #include <syscon.h>
12*41793000SKever Yang #include <asm/arch/clock.h>
13*41793000SKever Yang #include <asm/arch/cru_rk3328.h>
14*41793000SKever Yang #include <asm/arch/hardware.h>
15*41793000SKever Yang #include <asm/io.h>
16*41793000SKever Yang #include <dm/lists.h>
17*41793000SKever Yang #include <dt-bindings/clock/rk3328-cru.h>
18*41793000SKever Yang 
19*41793000SKever Yang DECLARE_GLOBAL_DATA_PTR;
20*41793000SKever Yang 
21*41793000SKever Yang struct pll_div {
22*41793000SKever Yang 	u32 refdiv;
23*41793000SKever Yang 	u32 fbdiv;
24*41793000SKever Yang 	u32 postdiv1;
25*41793000SKever Yang 	u32 postdiv2;
26*41793000SKever Yang 	u32 frac;
27*41793000SKever Yang };
28*41793000SKever Yang 
29*41793000SKever Yang #define RATE_TO_DIV(input_rate, output_rate) \
30*41793000SKever Yang 	((input_rate) / (output_rate) - 1);
31*41793000SKever Yang #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
32*41793000SKever Yang 
33*41793000SKever Yang #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
34*41793000SKever Yang 	.refdiv = _refdiv,\
35*41793000SKever Yang 	.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
36*41793000SKever Yang 	.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
37*41793000SKever Yang 
38*41793000SKever Yang static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1);
39*41793000SKever Yang static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1);
40*41793000SKever Yang 
41*41793000SKever Yang static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1);
42*41793000SKever Yang static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1);
43*41793000SKever Yang 
44*41793000SKever Yang static const struct pll_div *apll_cfgs[] = {
45*41793000SKever Yang 	[APLL_816_MHZ] = &apll_816_cfg,
46*41793000SKever Yang 	[APLL_600_MHZ] = &apll_600_cfg,
47*41793000SKever Yang };
48*41793000SKever Yang 
49*41793000SKever Yang enum {
50*41793000SKever Yang 	/* PLL_CON0 */
51*41793000SKever Yang 	PLL_POSTDIV1_SHIFT		= 12,
52*41793000SKever Yang 	PLL_POSTDIV1_MASK		= 0x7 << PLL_POSTDIV1_SHIFT,
53*41793000SKever Yang 	PLL_FBDIV_SHIFT			= 0,
54*41793000SKever Yang 	PLL_FBDIV_MASK			= 0xfff,
55*41793000SKever Yang 
56*41793000SKever Yang 	/* PLL_CON1 */
57*41793000SKever Yang 	PLL_DSMPD_SHIFT			= 12,
58*41793000SKever Yang 	PLL_DSMPD_MASK			= 1 << PLL_DSMPD_SHIFT,
59*41793000SKever Yang 	PLL_INTEGER_MODE		= 1,
60*41793000SKever Yang 	PLL_LOCK_STATUS_SHIFT		= 10,
61*41793000SKever Yang 	PLL_LOCK_STATUS_MASK		= 1 << PLL_LOCK_STATUS_SHIFT,
62*41793000SKever Yang 	PLL_POSTDIV2_SHIFT		= 6,
63*41793000SKever Yang 	PLL_POSTDIV2_MASK		= 0x7 << PLL_POSTDIV2_SHIFT,
64*41793000SKever Yang 	PLL_REFDIV_SHIFT		= 0,
65*41793000SKever Yang 	PLL_REFDIV_MASK			= 0x3f,
66*41793000SKever Yang 
67*41793000SKever Yang 	/* PLL_CON2 */
68*41793000SKever Yang 	PLL_FRACDIV_SHIFT		= 0,
69*41793000SKever Yang 	PLL_FRACDIV_MASK		= 0xffffff,
70*41793000SKever Yang 
71*41793000SKever Yang 	/* MODE_CON */
72*41793000SKever Yang 	APLL_MODE_SHIFT			= 0,
73*41793000SKever Yang 	NPLL_MODE_SHIFT			= 1,
74*41793000SKever Yang 	DPLL_MODE_SHIFT			= 4,
75*41793000SKever Yang 	CPLL_MODE_SHIFT			= 8,
76*41793000SKever Yang 	GPLL_MODE_SHIFT			= 12,
77*41793000SKever Yang 	PLL_MODE_SLOW			= 0,
78*41793000SKever Yang 	PLL_MODE_NORM,
79*41793000SKever Yang 
80*41793000SKever Yang 	/* CLKSEL_CON0 */
81*41793000SKever Yang 	CLK_CORE_PLL_SEL_APLL		= 0,
82*41793000SKever Yang 	CLK_CORE_PLL_SEL_GPLL,
83*41793000SKever Yang 	CLK_CORE_PLL_SEL_DPLL,
84*41793000SKever Yang 	CLK_CORE_PLL_SEL_NPLL,
85*41793000SKever Yang 	CLK_CORE_PLL_SEL_SHIFT		= 6,
86*41793000SKever Yang 	CLK_CORE_PLL_SEL_MASK		= 3 << CLK_CORE_PLL_SEL_SHIFT,
87*41793000SKever Yang 	CLK_CORE_DIV_SHIFT		= 0,
88*41793000SKever Yang 	CLK_CORE_DIV_MASK		= 0x1f,
89*41793000SKever Yang 
90*41793000SKever Yang 	/* CLKSEL_CON1 */
91*41793000SKever Yang 	ACLKM_CORE_DIV_SHIFT		= 4,
92*41793000SKever Yang 	ACLKM_CORE_DIV_MASK		= 0x7 << ACLKM_CORE_DIV_SHIFT,
93*41793000SKever Yang 	PCLK_DBG_DIV_SHIFT		= 0,
94*41793000SKever Yang 	PCLK_DBG_DIV_MASK		= 0xF << PCLK_DBG_DIV_SHIFT,
95*41793000SKever Yang 
96*41793000SKever Yang 	/* CLKSEL_CON28 */
97*41793000SKever Yang 	ACLK_PERIHP_PLL_SEL_CPLL	= 0,
98*41793000SKever Yang 	ACLK_PERIHP_PLL_SEL_GPLL,
99*41793000SKever Yang 	ACLK_PERIHP_PLL_SEL_HDMIPHY,
100*41793000SKever Yang 	ACLK_PERIHP_PLL_SEL_SHIFT	= 6,
101*41793000SKever Yang 	ACLK_PERIHP_PLL_SEL_MASK	= 3 << ACLK_PERIHP_PLL_SEL_SHIFT,
102*41793000SKever Yang 	ACLK_PERIHP_DIV_CON_SHIFT	= 0,
103*41793000SKever Yang 	ACLK_PERIHP_DIV_CON_MASK	= 0x1f,
104*41793000SKever Yang 
105*41793000SKever Yang 	/* CLKSEL_CON29 */
106*41793000SKever Yang 	PCLK_PERIHP_DIV_CON_SHIFT	= 4,
107*41793000SKever Yang 	PCLK_PERIHP_DIV_CON_MASK	= 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
108*41793000SKever Yang 	HCLK_PERIHP_DIV_CON_SHIFT	= 0,
109*41793000SKever Yang 	HCLK_PERIHP_DIV_CON_MASK	= 3 << HCLK_PERIHP_DIV_CON_SHIFT,
110*41793000SKever Yang 
111*41793000SKever Yang 	/* CLKSEL_CON22 */
112*41793000SKever Yang 	CLK_TSADC_DIV_CON_SHIFT		= 0,
113*41793000SKever Yang 	CLK_TSADC_DIV_CON_MASK		= 0x3ff,
114*41793000SKever Yang 
115*41793000SKever Yang 	/* CLKSEL_CON23 */
116*41793000SKever Yang 	CLK_SARADC_DIV_CON_SHIFT	= 0,
117*41793000SKever Yang 	CLK_SARADC_DIV_CON_MASK		= 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
118*41793000SKever Yang 
119*41793000SKever Yang 	/* CLKSEL_CON24 */
120*41793000SKever Yang 	CLK_PWM_PLL_SEL_CPLL		= 0,
121*41793000SKever Yang 	CLK_PWM_PLL_SEL_GPLL,
122*41793000SKever Yang 	CLK_PWM_PLL_SEL_SHIFT		= 15,
123*41793000SKever Yang 	CLK_PWM_PLL_SEL_MASK		= 1 << CLK_PWM_PLL_SEL_SHIFT,
124*41793000SKever Yang 	CLK_PWM_DIV_CON_SHIFT		= 8,
125*41793000SKever Yang 	CLK_PWM_DIV_CON_MASK		= 0x7f << CLK_PWM_DIV_CON_SHIFT,
126*41793000SKever Yang 
127*41793000SKever Yang 	CLK_SPI_PLL_SEL_CPLL		= 0,
128*41793000SKever Yang 	CLK_SPI_PLL_SEL_GPLL,
129*41793000SKever Yang 	CLK_SPI_PLL_SEL_SHIFT		= 7,
130*41793000SKever Yang 	CLK_SPI_PLL_SEL_MASK		= 1 << CLK_SPI_PLL_SEL_SHIFT,
131*41793000SKever Yang 	CLK_SPI_DIV_CON_SHIFT		= 0,
132*41793000SKever Yang 	CLK_SPI_DIV_CON_MASK		= 0x7f << CLK_SPI_DIV_CON_SHIFT,
133*41793000SKever Yang 
134*41793000SKever Yang 	/* CLKSEL_CON30 */
135*41793000SKever Yang 	CLK_SDMMC_PLL_SEL_CPLL		= 0,
136*41793000SKever Yang 	CLK_SDMMC_PLL_SEL_GPLL,
137*41793000SKever Yang 	CLK_SDMMC_PLL_SEL_24M,
138*41793000SKever Yang 	CLK_SDMMC_PLL_SEL_USBPHY,
139*41793000SKever Yang 	CLK_SDMMC_PLL_SHIFT		= 8,
140*41793000SKever Yang 	CLK_SDMMC_PLL_MASK		= 0x3 << CLK_SDMMC_PLL_SHIFT,
141*41793000SKever Yang 	CLK_SDMMC_DIV_CON_SHIFT          = 0,
142*41793000SKever Yang 	CLK_SDMMC_DIV_CON_MASK           = 0xff << CLK_SDMMC_DIV_CON_SHIFT,
143*41793000SKever Yang 
144*41793000SKever Yang 	/* CLKSEL_CON32 */
145*41793000SKever Yang 	CLK_EMMC_PLL_SEL_CPLL		= 0,
146*41793000SKever Yang 	CLK_EMMC_PLL_SEL_GPLL,
147*41793000SKever Yang 	CLK_EMMC_PLL_SEL_24M,
148*41793000SKever Yang 	CLK_EMMC_PLL_SEL_USBPHY,
149*41793000SKever Yang 	CLK_EMMC_PLL_SHIFT		= 8,
150*41793000SKever Yang 	CLK_EMMC_PLL_MASK		= 0x3 << CLK_EMMC_PLL_SHIFT,
151*41793000SKever Yang 	CLK_EMMC_DIV_CON_SHIFT          = 0,
152*41793000SKever Yang 	CLK_EMMC_DIV_CON_MASK           = 0xff << CLK_EMMC_DIV_CON_SHIFT,
153*41793000SKever Yang 
154*41793000SKever Yang 	/* CLKSEL_CON34 */
155*41793000SKever Yang 	CLK_I2C_PLL_SEL_CPLL		= 0,
156*41793000SKever Yang 	CLK_I2C_PLL_SEL_GPLL,
157*41793000SKever Yang 	CLK_I2C_DIV_CON_MASK		= 0x7f,
158*41793000SKever Yang 	CLK_I2C_PLL_SEL_MASK		= 1,
159*41793000SKever Yang 	CLK_I2C1_PLL_SEL_SHIFT		= 15,
160*41793000SKever Yang 	CLK_I2C1_DIV_CON_SHIFT		= 8,
161*41793000SKever Yang 	CLK_I2C0_PLL_SEL_SHIFT		= 7,
162*41793000SKever Yang 	CLK_I2C0_DIV_CON_SHIFT		= 0,
163*41793000SKever Yang 
164*41793000SKever Yang 	/* CLKSEL_CON35 */
165*41793000SKever Yang 	CLK_I2C3_PLL_SEL_SHIFT		= 15,
166*41793000SKever Yang 	CLK_I2C3_DIV_CON_SHIFT		= 8,
167*41793000SKever Yang 	CLK_I2C2_PLL_SEL_SHIFT		= 7,
168*41793000SKever Yang 	CLK_I2C2_DIV_CON_SHIFT		= 0,
169*41793000SKever Yang };
170*41793000SKever Yang 
171*41793000SKever Yang #define VCO_MAX_KHZ	(3200 * (MHz / KHz))
172*41793000SKever Yang #define VCO_MIN_KHZ	(800 * (MHz / KHz))
173*41793000SKever Yang #define OUTPUT_MAX_KHZ	(3200 * (MHz / KHz))
174*41793000SKever Yang #define OUTPUT_MIN_KHZ	(16 * (MHz / KHz))
175*41793000SKever Yang 
176*41793000SKever Yang /*
177*41793000SKever Yang  *  the div restructions of pll in integer mode, these are defined in
178*41793000SKever Yang  *  * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
179*41793000SKever Yang  */
180*41793000SKever Yang #define PLL_DIV_MIN	16
181*41793000SKever Yang #define PLL_DIV_MAX	3200
182*41793000SKever Yang 
183*41793000SKever Yang /*
184*41793000SKever Yang  * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
185*41793000SKever Yang  * Formulas also embedded within the Fractional PLL Verilog model:
186*41793000SKever Yang  * If DSMPD = 1 (DSM is disabled, "integer mode")
187*41793000SKever Yang  * FOUTVCO = FREF / REFDIV * FBDIV
188*41793000SKever Yang  * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
189*41793000SKever Yang  * Where:
190*41793000SKever Yang  * FOUTVCO = Fractional PLL non-divided output frequency
191*41793000SKever Yang  * FOUTPOSTDIV = Fractional PLL divided output frequency
192*41793000SKever Yang  *               (output of second post divider)
193*41793000SKever Yang  * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
194*41793000SKever Yang  * REFDIV = Fractional PLL input reference clock divider
195*41793000SKever Yang  * FBDIV = Integer value programmed into feedback divide
196*41793000SKever Yang  *
197*41793000SKever Yang  */
198*41793000SKever Yang static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id,
199*41793000SKever Yang 			const struct pll_div *div)
200*41793000SKever Yang {
201*41793000SKever Yang 	u32 *pll_con;
202*41793000SKever Yang 	u32 mode_shift, mode_mask;
203*41793000SKever Yang 
204*41793000SKever Yang 	pll_con = NULL;
205*41793000SKever Yang 	mode_shift = 0;
206*41793000SKever Yang 	switch (clk_id) {
207*41793000SKever Yang 	case CLK_ARM:
208*41793000SKever Yang 		pll_con = cru->apll_con;
209*41793000SKever Yang 		mode_shift = APLL_MODE_SHIFT;
210*41793000SKever Yang 		break;
211*41793000SKever Yang 	case CLK_DDR:
212*41793000SKever Yang 		pll_con = cru->dpll_con;
213*41793000SKever Yang 		mode_shift = DPLL_MODE_SHIFT;
214*41793000SKever Yang 		break;
215*41793000SKever Yang 	case CLK_CODEC:
216*41793000SKever Yang 		pll_con = cru->cpll_con;
217*41793000SKever Yang 		mode_shift = CPLL_MODE_SHIFT;
218*41793000SKever Yang 		break;
219*41793000SKever Yang 	case CLK_GENERAL:
220*41793000SKever Yang 		pll_con = cru->gpll_con;
221*41793000SKever Yang 		mode_shift = GPLL_MODE_SHIFT;
222*41793000SKever Yang 		break;
223*41793000SKever Yang 	case CLK_NEW:
224*41793000SKever Yang 		pll_con = cru->npll_con;
225*41793000SKever Yang 		mode_shift = NPLL_MODE_SHIFT;
226*41793000SKever Yang 		break;
227*41793000SKever Yang 	default:
228*41793000SKever Yang 		break;
229*41793000SKever Yang 	}
230*41793000SKever Yang 	mode_mask = 1 << mode_shift;
231*41793000SKever Yang 
232*41793000SKever Yang 	/* All 8 PLLs have same VCO and output frequency range restrictions. */
233*41793000SKever Yang 	u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
234*41793000SKever Yang 	u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
235*41793000SKever Yang 
236*41793000SKever Yang 	debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \
237*41793000SKever Yang 	      postdiv2=%d, vco=%u khz, output=%u khz\n",
238*41793000SKever Yang 	      pll_con, div->fbdiv, div->refdiv, div->postdiv1,
239*41793000SKever Yang 	      div->postdiv2, vco_khz, output_khz);
240*41793000SKever Yang 	assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
241*41793000SKever Yang 	       output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
242*41793000SKever Yang 	       div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
243*41793000SKever Yang 
244*41793000SKever Yang 	/*
245*41793000SKever Yang 	 * When power on or changing PLL setting,
246*41793000SKever Yang 	 * we must force PLL into slow mode to ensure output stable clock.
247*41793000SKever Yang 	 */
248*41793000SKever Yang 	rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift);
249*41793000SKever Yang 
250*41793000SKever Yang 	/* use integer mode */
251*41793000SKever Yang 	rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK,
252*41793000SKever Yang 		     PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
253*41793000SKever Yang 
254*41793000SKever Yang 	rk_clrsetreg(&pll_con[0],
255*41793000SKever Yang 		     PLL_FBDIV_MASK | PLL_POSTDIV1_MASK,
256*41793000SKever Yang 		     (div->fbdiv << PLL_FBDIV_SHIFT) |
257*41793000SKever Yang 		     (div->postdiv1 << PLL_POSTDIV1_SHIFT));
258*41793000SKever Yang 	rk_clrsetreg(&pll_con[1],
259*41793000SKever Yang 		     PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
260*41793000SKever Yang 		     (div->postdiv2 << PLL_POSTDIV2_SHIFT) |
261*41793000SKever Yang 		     (div->refdiv << PLL_REFDIV_SHIFT));
262*41793000SKever Yang 
263*41793000SKever Yang 	/* waiting for pll lock */
264*41793000SKever Yang 	while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT)))
265*41793000SKever Yang 		udelay(1);
266*41793000SKever Yang 
267*41793000SKever Yang 	/* pll enter normal mode */
268*41793000SKever Yang 	rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift);
269*41793000SKever Yang }
270*41793000SKever Yang 
271*41793000SKever Yang static void rkclk_init(struct rk3328_cru *cru)
272*41793000SKever Yang {
273*41793000SKever Yang 	u32 aclk_div;
274*41793000SKever Yang 	u32 hclk_div;
275*41793000SKever Yang 	u32 pclk_div;
276*41793000SKever Yang 
277*41793000SKever Yang 	/* configure gpll cpll */
278*41793000SKever Yang 	rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
279*41793000SKever Yang 	rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
280*41793000SKever Yang 
281*41793000SKever Yang 	/* configure perihp aclk, hclk, pclk */
282*41793000SKever Yang 	aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
283*41793000SKever Yang 	hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
284*41793000SKever Yang 	pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
285*41793000SKever Yang 
286*41793000SKever Yang 	rk_clrsetreg(&cru->clksel_con[28],
287*41793000SKever Yang 		     ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
288*41793000SKever Yang 		     ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
289*41793000SKever Yang 		     aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
290*41793000SKever Yang 	rk_clrsetreg(&cru->clksel_con[29],
291*41793000SKever Yang 		     PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK,
292*41793000SKever Yang 		     pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
293*41793000SKever Yang 		     hclk_div << HCLK_PERIHP_DIV_CON_SHIFT);
294*41793000SKever Yang }
295*41793000SKever Yang 
296*41793000SKever Yang void rk3328_configure_cpu(struct rk3328_cru *cru,
297*41793000SKever Yang 			  enum apll_frequencies apll_freq)
298*41793000SKever Yang {
299*41793000SKever Yang 	u32 clk_core_div;
300*41793000SKever Yang 	u32 aclkm_div;
301*41793000SKever Yang 	u32 pclk_dbg_div;
302*41793000SKever Yang 
303*41793000SKever Yang 	rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]);
304*41793000SKever Yang 
305*41793000SKever Yang 	clk_core_div = APLL_HZ / CLK_CORE_HZ - 1;
306*41793000SKever Yang 	aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1;
307*41793000SKever Yang 	pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1;
308*41793000SKever Yang 
309*41793000SKever Yang 	rk_clrsetreg(&cru->clksel_con[0],
310*41793000SKever Yang 		     CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK,
311*41793000SKever Yang 		     CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT |
312*41793000SKever Yang 		     clk_core_div << CLK_CORE_DIV_SHIFT);
313*41793000SKever Yang 
314*41793000SKever Yang 	rk_clrsetreg(&cru->clksel_con[1],
315*41793000SKever Yang 		     PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK,
316*41793000SKever Yang 		     pclk_dbg_div << PCLK_DBG_DIV_SHIFT |
317*41793000SKever Yang 		     aclkm_div << ACLKM_CORE_DIV_SHIFT);
318*41793000SKever Yang }
319*41793000SKever Yang 
320*41793000SKever Yang 
321*41793000SKever Yang static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id)
322*41793000SKever Yang {
323*41793000SKever Yang 	u32 div, con;
324*41793000SKever Yang 
325*41793000SKever Yang 	switch (clk_id) {
326*41793000SKever Yang 	case SCLK_I2C0:
327*41793000SKever Yang 		con = readl(&cru->clksel_con[34]);
328*41793000SKever Yang 		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
329*41793000SKever Yang 		break;
330*41793000SKever Yang 	case SCLK_I2C1:
331*41793000SKever Yang 		con = readl(&cru->clksel_con[34]);
332*41793000SKever Yang 		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
333*41793000SKever Yang 		break;
334*41793000SKever Yang 	case SCLK_I2C2:
335*41793000SKever Yang 		con = readl(&cru->clksel_con[35]);
336*41793000SKever Yang 		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
337*41793000SKever Yang 		break;
338*41793000SKever Yang 	case SCLK_I2C3:
339*41793000SKever Yang 		con = readl(&cru->clksel_con[35]);
340*41793000SKever Yang 		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
341*41793000SKever Yang 		break;
342*41793000SKever Yang 	default:
343*41793000SKever Yang 		printf("do not support this i2c bus\n");
344*41793000SKever Yang 		return -EINVAL;
345*41793000SKever Yang 	}
346*41793000SKever Yang 
347*41793000SKever Yang 	return DIV_TO_RATE(GPLL_HZ, div);
348*41793000SKever Yang }
349*41793000SKever Yang 
350*41793000SKever Yang static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz)
351*41793000SKever Yang {
352*41793000SKever Yang 	int src_clk_div;
353*41793000SKever Yang 
354*41793000SKever Yang 	src_clk_div = GPLL_HZ / hz;
355*41793000SKever Yang 	assert(src_clk_div - 1 < 127);
356*41793000SKever Yang 
357*41793000SKever Yang 	switch (clk_id) {
358*41793000SKever Yang 	case SCLK_I2C0:
359*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[34],
360*41793000SKever Yang 			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
361*41793000SKever Yang 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
362*41793000SKever Yang 			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
363*41793000SKever Yang 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
364*41793000SKever Yang 		break;
365*41793000SKever Yang 	case SCLK_I2C1:
366*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[34],
367*41793000SKever Yang 			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
368*41793000SKever Yang 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
369*41793000SKever Yang 			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
370*41793000SKever Yang 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
371*41793000SKever Yang 		break;
372*41793000SKever Yang 	case SCLK_I2C2:
373*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[35],
374*41793000SKever Yang 			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
375*41793000SKever Yang 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
376*41793000SKever Yang 			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
377*41793000SKever Yang 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
378*41793000SKever Yang 		break;
379*41793000SKever Yang 	case SCLK_I2C3:
380*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[35],
381*41793000SKever Yang 			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
382*41793000SKever Yang 			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
383*41793000SKever Yang 			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
384*41793000SKever Yang 			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
385*41793000SKever Yang 		break;
386*41793000SKever Yang 	default:
387*41793000SKever Yang 		printf("do not support this i2c bus\n");
388*41793000SKever Yang 		return -EINVAL;
389*41793000SKever Yang 	}
390*41793000SKever Yang 
391*41793000SKever Yang 	return DIV_TO_RATE(GPLL_HZ, src_clk_div);
392*41793000SKever Yang }
393*41793000SKever Yang 
394*41793000SKever Yang static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id)
395*41793000SKever Yang {
396*41793000SKever Yang 	u32 div, con, con_id;
397*41793000SKever Yang 
398*41793000SKever Yang 	switch (clk_id) {
399*41793000SKever Yang 	case HCLK_SDMMC:
400*41793000SKever Yang 		con_id = 30;
401*41793000SKever Yang 		break;
402*41793000SKever Yang 	case HCLK_EMMC:
403*41793000SKever Yang 		con_id = 32;
404*41793000SKever Yang 		break;
405*41793000SKever Yang 	default:
406*41793000SKever Yang 		return -EINVAL;
407*41793000SKever Yang 	}
408*41793000SKever Yang 	con = readl(&cru->clksel_con[con_id]);
409*41793000SKever Yang 	div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
410*41793000SKever Yang 
411*41793000SKever Yang 	if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
412*41793000SKever Yang 	    == CLK_EMMC_PLL_SEL_24M)
413*41793000SKever Yang 		return DIV_TO_RATE(OSC_HZ, div);
414*41793000SKever Yang 	else
415*41793000SKever Yang 		return DIV_TO_RATE(GPLL_HZ, div);
416*41793000SKever Yang }
417*41793000SKever Yang 
418*41793000SKever Yang static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
419*41793000SKever Yang 				ulong clk_id, ulong set_rate)
420*41793000SKever Yang {
421*41793000SKever Yang 	int src_clk_div;
422*41793000SKever Yang 	u32 con_id;
423*41793000SKever Yang 
424*41793000SKever Yang 	switch (clk_id) {
425*41793000SKever Yang 	case HCLK_SDMMC:
426*41793000SKever Yang 		con_id = 30;
427*41793000SKever Yang 		break;
428*41793000SKever Yang 	case HCLK_EMMC:
429*41793000SKever Yang 		con_id = 32;
430*41793000SKever Yang 		break;
431*41793000SKever Yang 	default:
432*41793000SKever Yang 		return -EINVAL;
433*41793000SKever Yang 	}
434*41793000SKever Yang 	/* Select clk_sdmmc/emmc source from GPLL by default */
435*41793000SKever Yang 	src_clk_div = GPLL_HZ / set_rate;
436*41793000SKever Yang 
437*41793000SKever Yang 	if (src_clk_div > 127) {
438*41793000SKever Yang 		/* use 24MHz source for 400KHz clock */
439*41793000SKever Yang 		src_clk_div = OSC_HZ / set_rate;
440*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[con_id],
441*41793000SKever Yang 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
442*41793000SKever Yang 			     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
443*41793000SKever Yang 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
444*41793000SKever Yang 	} else {
445*41793000SKever Yang 		rk_clrsetreg(&cru->clksel_con[con_id],
446*41793000SKever Yang 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
447*41793000SKever Yang 			     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
448*41793000SKever Yang 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
449*41793000SKever Yang 	}
450*41793000SKever Yang 
451*41793000SKever Yang 	return rk3328_mmc_get_clk(cru, clk_id);
452*41793000SKever Yang }
453*41793000SKever Yang 
454*41793000SKever Yang static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru)
455*41793000SKever Yang {
456*41793000SKever Yang 	u32 div, con;
457*41793000SKever Yang 
458*41793000SKever Yang 	con = readl(&cru->clksel_con[24]);
459*41793000SKever Yang 	div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
460*41793000SKever Yang 
461*41793000SKever Yang 	return DIV_TO_RATE(GPLL_HZ, div);
462*41793000SKever Yang }
463*41793000SKever Yang 
464*41793000SKever Yang static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
465*41793000SKever Yang {
466*41793000SKever Yang 	u32 div = GPLL_HZ / hz;
467*41793000SKever Yang 
468*41793000SKever Yang 	rk_clrsetreg(&cru->clksel_con[24],
469*41793000SKever Yang 		     CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
470*41793000SKever Yang 		     CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT |
471*41793000SKever Yang 		     (div - 1) << CLK_PWM_DIV_CON_SHIFT);
472*41793000SKever Yang 
473*41793000SKever Yang 	return DIV_TO_RATE(GPLL_HZ, div);
474*41793000SKever Yang }
475*41793000SKever Yang 
476*41793000SKever Yang static ulong rk3328_clk_get_rate(struct clk *clk)
477*41793000SKever Yang {
478*41793000SKever Yang 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
479*41793000SKever Yang 	ulong rate = 0;
480*41793000SKever Yang 
481*41793000SKever Yang 	switch (clk->id) {
482*41793000SKever Yang 	case 0 ... 29:
483*41793000SKever Yang 		return 0;
484*41793000SKever Yang 	case HCLK_SDMMC:
485*41793000SKever Yang 	case HCLK_EMMC:
486*41793000SKever Yang 		rate = rk3328_mmc_get_clk(priv->cru, clk->id);
487*41793000SKever Yang 		break;
488*41793000SKever Yang 	case SCLK_I2C0:
489*41793000SKever Yang 	case SCLK_I2C1:
490*41793000SKever Yang 	case SCLK_I2C2:
491*41793000SKever Yang 	case SCLK_I2C3:
492*41793000SKever Yang 		rate = rk3328_i2c_get_clk(priv->cru, clk->id);
493*41793000SKever Yang 		break;
494*41793000SKever Yang 	case SCLK_PWM:
495*41793000SKever Yang 		rate = rk3328_pwm_get_clk(priv->cru);
496*41793000SKever Yang 		break;
497*41793000SKever Yang 	default:
498*41793000SKever Yang 		return -ENOENT;
499*41793000SKever Yang 	}
500*41793000SKever Yang 
501*41793000SKever Yang 	return rate;
502*41793000SKever Yang }
503*41793000SKever Yang 
504*41793000SKever Yang static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
505*41793000SKever Yang {
506*41793000SKever Yang 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
507*41793000SKever Yang 	ulong ret = 0;
508*41793000SKever Yang 
509*41793000SKever Yang 	switch (clk->id) {
510*41793000SKever Yang 	case 0 ... 29:
511*41793000SKever Yang 		return 0;
512*41793000SKever Yang 	case HCLK_SDMMC:
513*41793000SKever Yang 	case HCLK_EMMC:
514*41793000SKever Yang 		ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate);
515*41793000SKever Yang 		break;
516*41793000SKever Yang 	case SCLK_I2C0:
517*41793000SKever Yang 	case SCLK_I2C1:
518*41793000SKever Yang 	case SCLK_I2C2:
519*41793000SKever Yang 	case SCLK_I2C3:
520*41793000SKever Yang 		ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate);
521*41793000SKever Yang 		break;
522*41793000SKever Yang 	case SCLK_PWM:
523*41793000SKever Yang 		ret = rk3328_pwm_set_clk(priv->cru, rate);
524*41793000SKever Yang 		break;
525*41793000SKever Yang 	default:
526*41793000SKever Yang 		return -ENOENT;
527*41793000SKever Yang 	}
528*41793000SKever Yang 
529*41793000SKever Yang 	return ret;
530*41793000SKever Yang }
531*41793000SKever Yang 
532*41793000SKever Yang static struct clk_ops rk3328_clk_ops = {
533*41793000SKever Yang 	.get_rate = rk3328_clk_get_rate,
534*41793000SKever Yang 	.set_rate = rk3328_clk_set_rate,
535*41793000SKever Yang };
536*41793000SKever Yang 
537*41793000SKever Yang static int rk3328_clk_probe(struct udevice *dev)
538*41793000SKever Yang {
539*41793000SKever Yang 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
540*41793000SKever Yang 
541*41793000SKever Yang 	rkclk_init(priv->cru);
542*41793000SKever Yang 
543*41793000SKever Yang 	return 0;
544*41793000SKever Yang }
545*41793000SKever Yang 
546*41793000SKever Yang static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
547*41793000SKever Yang {
548*41793000SKever Yang 	struct rk3328_clk_priv *priv = dev_get_priv(dev);
549*41793000SKever Yang 
550*41793000SKever Yang 	priv->cru = (struct rk3328_cru *)dev_get_addr(dev);
551*41793000SKever Yang 
552*41793000SKever Yang 	return 0;
553*41793000SKever Yang }
554*41793000SKever Yang 
555*41793000SKever Yang static int rk3328_clk_bind(struct udevice *dev)
556*41793000SKever Yang {
557*41793000SKever Yang 	int ret;
558*41793000SKever Yang 
559*41793000SKever Yang 	/* The reset driver does not have a device node, so bind it here */
560*41793000SKever Yang 	ret = device_bind_driver(gd->dm_root, "rk3328_sysreset", "reset", &dev);
561*41793000SKever Yang 	if (ret)
562*41793000SKever Yang 		printf("Warning: No RK3328 reset driver: ret=%d\n", ret);
563*41793000SKever Yang 
564*41793000SKever Yang 	return ret;
565*41793000SKever Yang }
566*41793000SKever Yang 
567*41793000SKever Yang static const struct udevice_id rk3328_clk_ids[] = {
568*41793000SKever Yang 	{ .compatible = "rockchip,rk3328-cru" },
569*41793000SKever Yang 	{ }
570*41793000SKever Yang };
571*41793000SKever Yang 
572*41793000SKever Yang U_BOOT_DRIVER(rockchip_rk3328_cru) = {
573*41793000SKever Yang 	.name		= "rockchip_rk3328_cru",
574*41793000SKever Yang 	.id		= UCLASS_CLK,
575*41793000SKever Yang 	.of_match	= rk3328_clk_ids,
576*41793000SKever Yang 	.priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
577*41793000SKever Yang 	.ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
578*41793000SKever Yang 	.ops		= &rk3328_clk_ops,
579*41793000SKever Yang 	.bind		= rk3328_clk_bind,
580*41793000SKever Yang 	.probe		= rk3328_clk_probe,
581*41793000SKever Yang };
582