1 /*
2  * Freescale i.MX28 Boot PMIC init
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  * on behalf of DENX Software Engineering GmbH
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <config.h>
12 #include <asm/io.h>
13 #include <asm/arch/imx-regs.h>
14 
15 #include "mxs_init.h"
16 
17 static void mxs_power_clock2xtal(void)
18 {
19 	struct mxs_clkctrl_regs *clkctrl_regs =
20 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
21 
22 	/* Set XTAL as CPU reference clock */
23 	writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
24 		&clkctrl_regs->hw_clkctrl_clkseq_set);
25 }
26 
27 static void mxs_power_clock2pll(void)
28 {
29 	struct mxs_clkctrl_regs *clkctrl_regs =
30 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
31 
32 	setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
33 			CLKCTRL_PLL0CTRL0_POWER);
34 	early_delay(100);
35 	setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
36 			CLKCTRL_CLKSEQ_BYPASS_CPU);
37 }
38 
39 static void mxs_power_clear_auto_restart(void)
40 {
41 	struct mxs_rtc_regs *rtc_regs =
42 		(struct mxs_rtc_regs *)MXS_RTC_BASE;
43 
44 	writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
45 	while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
46 		;
47 
48 	writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
49 	while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
50 		;
51 
52 	/*
53 	 * Due to the hardware design bug of mx28 EVK-A
54 	 * we need to set the AUTO_RESTART bit.
55 	 */
56 	if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
57 		return;
58 
59 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
60 		;
61 
62 	setbits_le32(&rtc_regs->hw_rtc_persistent0,
63 			RTC_PERSISTENT0_AUTO_RESTART);
64 	writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
65 	writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
66 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
67 		;
68 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
69 		;
70 }
71 
72 static void mxs_power_set_linreg(void)
73 {
74 	struct mxs_power_regs *power_regs =
75 		(struct mxs_power_regs *)MXS_POWER_BASE;
76 
77 	/* Set linear regulator 25mV below switching converter */
78 	clrsetbits_le32(&power_regs->hw_power_vdddctrl,
79 			POWER_VDDDCTRL_LINREG_OFFSET_MASK,
80 			POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
81 
82 	clrsetbits_le32(&power_regs->hw_power_vddactrl,
83 			POWER_VDDACTRL_LINREG_OFFSET_MASK,
84 			POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
85 
86 	clrsetbits_le32(&power_regs->hw_power_vddioctrl,
87 			POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
88 			POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
89 }
90 
91 static int mxs_get_batt_volt(void)
92 {
93 	struct mxs_power_regs *power_regs =
94 		(struct mxs_power_regs *)MXS_POWER_BASE;
95 	uint32_t volt = readl(&power_regs->hw_power_battmonitor);
96 	volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
97 	volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
98 	volt *= 8;
99 	return volt;
100 }
101 
102 static int mxs_is_batt_ready(void)
103 {
104 	return (mxs_get_batt_volt() >= 3600);
105 }
106 
107 static int mxs_is_batt_good(void)
108 {
109 	struct mxs_power_regs *power_regs =
110 		(struct mxs_power_regs *)MXS_POWER_BASE;
111 	uint32_t volt = mxs_get_batt_volt();
112 
113 	if ((volt >= 2400) && (volt <= 4300))
114 		return 1;
115 
116 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
117 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
118 		0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
119 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
120 		&power_regs->hw_power_5vctrl_clr);
121 
122 	clrsetbits_le32(&power_regs->hw_power_charge,
123 		POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
124 		POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
125 
126 	writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
127 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
128 		&power_regs->hw_power_5vctrl_clr);
129 
130 	early_delay(500000);
131 
132 	volt = mxs_get_batt_volt();
133 
134 	if (volt >= 3500)
135 		return 0;
136 
137 	if (volt >= 2400)
138 		return 1;
139 
140 	writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
141 		&power_regs->hw_power_charge_clr);
142 	writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
143 
144 	return 0;
145 }
146 
147 static void mxs_power_setup_5v_detect(void)
148 {
149 	struct mxs_power_regs *power_regs =
150 		(struct mxs_power_regs *)MXS_POWER_BASE;
151 
152 	/* Start 5V detection */
153 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
154 			POWER_5VCTRL_VBUSVALID_TRSH_MASK,
155 			POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
156 			POWER_5VCTRL_PWRUP_VBUS_CMPS);
157 }
158 
159 static void mxs_src_power_init(void)
160 {
161 	struct mxs_power_regs *power_regs =
162 		(struct mxs_power_regs *)MXS_POWER_BASE;
163 
164 	/* Improve efficieny and reduce transient ripple */
165 	writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
166 		POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
167 
168 	clrsetbits_le32(&power_regs->hw_power_dclimits,
169 			POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
170 			0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
171 
172 	setbits_le32(&power_regs->hw_power_battmonitor,
173 			POWER_BATTMONITOR_EN_BATADJ);
174 
175 	/* Increase the RCSCALE level for quick DCDC response to dynamic load */
176 	clrsetbits_le32(&power_regs->hw_power_loopctrl,
177 			POWER_LOOPCTRL_EN_RCSCALE_MASK,
178 			POWER_LOOPCTRL_RCSCALE_THRESH |
179 			POWER_LOOPCTRL_EN_RCSCALE_8X);
180 
181 	clrsetbits_le32(&power_regs->hw_power_minpwr,
182 			POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
183 
184 	/* 5V to battery handoff ... FIXME */
185 	setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
186 	early_delay(30);
187 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
188 }
189 
190 static void mxs_power_init_4p2_params(void)
191 {
192 	struct mxs_power_regs *power_regs =
193 		(struct mxs_power_regs *)MXS_POWER_BASE;
194 
195 	/* Setup 4P2 parameters */
196 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
197 		POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
198 		POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
199 
200 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
201 		POWER_5VCTRL_HEADROOM_ADJ_MASK,
202 		0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
203 
204 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
205 		POWER_DCDC4P2_DROPOUT_CTRL_MASK,
206 		POWER_DCDC4P2_DROPOUT_CTRL_100MV |
207 		POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
208 
209 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
210 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
211 		0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
212 }
213 
214 static void mxs_enable_4p2_dcdc_input(int xfer)
215 {
216 	struct mxs_power_regs *power_regs =
217 		(struct mxs_power_regs *)MXS_POWER_BASE;
218 	uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
219 	uint32_t prev_5v_brnout, prev_5v_droop;
220 
221 	prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
222 				POWER_5VCTRL_PWDN_5VBRNOUT;
223 	prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
224 				POWER_CTRL_ENIRQ_VDD5V_DROOP;
225 
226 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
227 	writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
228 		&power_regs->hw_power_reset);
229 
230 	clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
231 
232 	if (xfer && (readl(&power_regs->hw_power_5vctrl) &
233 			POWER_5VCTRL_ENABLE_DCDC)) {
234 		return;
235 	}
236 
237 	/*
238 	 * Recording orignal values that will be modified temporarlily
239 	 * to handle a chip bug. See chip errata for CQ ENGR00115837
240 	 */
241 	tmp = readl(&power_regs->hw_power_5vctrl);
242 	vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
243 	vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
244 
245 	pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
246 
247 	/*
248 	 * Disable mechanisms that get erroneously tripped by when setting
249 	 * the DCDC4P2 EN_DCDC
250 	 */
251 	clrbits_le32(&power_regs->hw_power_5vctrl,
252 		POWER_5VCTRL_VBUSVALID_5VDETECT |
253 		POWER_5VCTRL_VBUSVALID_TRSH_MASK);
254 
255 	writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
256 
257 	if (xfer) {
258 		setbits_le32(&power_regs->hw_power_5vctrl,
259 				POWER_5VCTRL_DCDC_XFER);
260 		early_delay(20);
261 		clrbits_le32(&power_regs->hw_power_5vctrl,
262 				POWER_5VCTRL_DCDC_XFER);
263 
264 		setbits_le32(&power_regs->hw_power_5vctrl,
265 				POWER_5VCTRL_ENABLE_DCDC);
266 	} else {
267 		setbits_le32(&power_regs->hw_power_dcdc4p2,
268 				POWER_DCDC4P2_ENABLE_DCDC);
269 	}
270 
271 	early_delay(25);
272 
273 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
274 			POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
275 
276 	if (vbus_5vdetect)
277 		writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
278 
279 	if (!pwd_bo)
280 		clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
281 
282 	while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
283 		writel(POWER_CTRL_VBUS_VALID_IRQ,
284 			&power_regs->hw_power_ctrl_clr);
285 
286 	if (prev_5v_brnout) {
287 		writel(POWER_5VCTRL_PWDN_5VBRNOUT,
288 			&power_regs->hw_power_5vctrl_set);
289 		writel(POWER_RESET_UNLOCK_KEY,
290 			&power_regs->hw_power_reset);
291 	} else {
292 		writel(POWER_5VCTRL_PWDN_5VBRNOUT,
293 			&power_regs->hw_power_5vctrl_clr);
294 		writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
295 			&power_regs->hw_power_reset);
296 	}
297 
298 	while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
299 		writel(POWER_CTRL_VDD5V_DROOP_IRQ,
300 			&power_regs->hw_power_ctrl_clr);
301 
302 	if (prev_5v_droop)
303 		clrbits_le32(&power_regs->hw_power_ctrl,
304 				POWER_CTRL_ENIRQ_VDD5V_DROOP);
305 	else
306 		setbits_le32(&power_regs->hw_power_ctrl,
307 				POWER_CTRL_ENIRQ_VDD5V_DROOP);
308 }
309 
310 static void mxs_power_init_4p2_regulator(void)
311 {
312 	struct mxs_power_regs *power_regs =
313 		(struct mxs_power_regs *)MXS_POWER_BASE;
314 	uint32_t tmp, tmp2;
315 
316 	setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
317 
318 	writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
319 
320 	writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
321 		&power_regs->hw_power_5vctrl_clr);
322 	clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
323 
324 	/* Power up the 4p2 rail and logic/control */
325 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
326 		&power_regs->hw_power_5vctrl_clr);
327 
328 	/*
329 	 * Start charging up the 4p2 capacitor. We ramp of this charge
330 	 * gradually to avoid large inrush current from the 5V cable which can
331 	 * cause transients/problems
332 	 */
333 	mxs_enable_4p2_dcdc_input(0);
334 
335 	if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
336 		/*
337 		 * If we arrived here, we were unable to recover from mx23 chip
338 		 * errata 5837. 4P2 is disabled and sufficient battery power is
339 		 * not present. Exiting to not enable DCDC power during 5V
340 		 * connected state.
341 		 */
342 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
343 			POWER_DCDC4P2_ENABLE_DCDC);
344 		writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
345 			&power_regs->hw_power_5vctrl_set);
346 		hang();
347 	}
348 
349 	/*
350 	 * Here we set the 4p2 brownout level to something very close to 4.2V.
351 	 * We then check the brownout status. If the brownout status is false,
352 	 * the voltage is already close to the target voltage of 4.2V so we
353 	 * can go ahead and set the 4P2 current limit to our max target limit.
354 	 * If the brownout status is true, we need to ramp us the current limit
355 	 * so that we don't cause large inrush current issues. We step up the
356 	 * current limit until the brownout status is false or until we've
357 	 * reached our maximum defined 4p2 current limit.
358 	 */
359 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
360 			POWER_DCDC4P2_BO_MASK,
361 			22 << POWER_DCDC4P2_BO_OFFSET);	/* 4.15V */
362 
363 	if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
364 		setbits_le32(&power_regs->hw_power_5vctrl,
365 			0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
366 	} else {
367 		tmp = (readl(&power_regs->hw_power_5vctrl) &
368 			POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
369 			POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
370 		while (tmp < 0x3f) {
371 			if (!(readl(&power_regs->hw_power_sts) &
372 					POWER_STS_DCDC_4P2_BO)) {
373 				tmp = readl(&power_regs->hw_power_5vctrl);
374 				tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
375 				early_delay(100);
376 				writel(tmp, &power_regs->hw_power_5vctrl);
377 				break;
378 			} else {
379 				tmp++;
380 				tmp2 = readl(&power_regs->hw_power_5vctrl);
381 				tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
382 				tmp2 |= tmp <<
383 					POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
384 				writel(tmp2, &power_regs->hw_power_5vctrl);
385 				early_delay(100);
386 			}
387 		}
388 	}
389 
390 	clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
391 	writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
392 }
393 
394 static void mxs_power_init_dcdc_4p2_source(void)
395 {
396 	struct mxs_power_regs *power_regs =
397 		(struct mxs_power_regs *)MXS_POWER_BASE;
398 
399 	if (!(readl(&power_regs->hw_power_dcdc4p2) &
400 		POWER_DCDC4P2_ENABLE_DCDC)) {
401 		hang();
402 	}
403 
404 	mxs_enable_4p2_dcdc_input(1);
405 
406 	if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
407 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
408 			POWER_DCDC4P2_ENABLE_DCDC);
409 		writel(POWER_5VCTRL_ENABLE_DCDC,
410 			&power_regs->hw_power_5vctrl_clr);
411 		writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
412 			&power_regs->hw_power_5vctrl_set);
413 	}
414 }
415 
416 static void mxs_power_enable_4p2(void)
417 {
418 	struct mxs_power_regs *power_regs =
419 		(struct mxs_power_regs *)MXS_POWER_BASE;
420 	uint32_t vdddctrl, vddactrl, vddioctrl;
421 	uint32_t tmp;
422 
423 	vdddctrl = readl(&power_regs->hw_power_vdddctrl);
424 	vddactrl = readl(&power_regs->hw_power_vddactrl);
425 	vddioctrl = readl(&power_regs->hw_power_vddioctrl);
426 
427 	setbits_le32(&power_regs->hw_power_vdddctrl,
428 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
429 		POWER_VDDDCTRL_PWDN_BRNOUT);
430 
431 	setbits_le32(&power_regs->hw_power_vddactrl,
432 		POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
433 		POWER_VDDACTRL_PWDN_BRNOUT);
434 
435 	setbits_le32(&power_regs->hw_power_vddioctrl,
436 		POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
437 
438 	mxs_power_init_4p2_params();
439 	mxs_power_init_4p2_regulator();
440 
441 	/* Shutdown battery (none present) */
442 	if (!mxs_is_batt_ready()) {
443 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
444 				POWER_DCDC4P2_BO_MASK);
445 		writel(POWER_CTRL_DCDC4P2_BO_IRQ,
446 				&power_regs->hw_power_ctrl_clr);
447 		writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
448 				&power_regs->hw_power_ctrl_clr);
449 	}
450 
451 	mxs_power_init_dcdc_4p2_source();
452 
453 	writel(vdddctrl, &power_regs->hw_power_vdddctrl);
454 	early_delay(20);
455 	writel(vddactrl, &power_regs->hw_power_vddactrl);
456 	early_delay(20);
457 	writel(vddioctrl, &power_regs->hw_power_vddioctrl);
458 
459 	/*
460 	 * Check if FET is enabled on either powerout and if so,
461 	 * disable load.
462 	 */
463 	tmp = 0;
464 	tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
465 			POWER_VDDDCTRL_DISABLE_FET);
466 	tmp |= !(readl(&power_regs->hw_power_vddactrl) &
467 			POWER_VDDACTRL_DISABLE_FET);
468 	tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
469 			POWER_VDDIOCTRL_DISABLE_FET);
470 	if (tmp)
471 		writel(POWER_CHARGE_ENABLE_LOAD,
472 			&power_regs->hw_power_charge_clr);
473 }
474 
475 static void mxs_boot_valid_5v(void)
476 {
477 	struct mxs_power_regs *power_regs =
478 		(struct mxs_power_regs *)MXS_POWER_BASE;
479 
480 	/*
481 	 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
482 	 * disconnect event. FIXME
483 	 */
484 	writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
485 		&power_regs->hw_power_5vctrl_set);
486 
487 	/* Configure polarity to check for 5V disconnection. */
488 	writel(POWER_CTRL_POLARITY_VBUSVALID |
489 		POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
490 		&power_regs->hw_power_ctrl_clr);
491 
492 	writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
493 		&power_regs->hw_power_ctrl_clr);
494 
495 	mxs_power_enable_4p2();
496 }
497 
498 static void mxs_powerdown(void)
499 {
500 	struct mxs_power_regs *power_regs =
501 		(struct mxs_power_regs *)MXS_POWER_BASE;
502 	writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
503 	writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
504 		&power_regs->hw_power_reset);
505 }
506 
507 static void mxs_batt_boot(void)
508 {
509 	struct mxs_power_regs *power_regs =
510 		(struct mxs_power_regs *)MXS_POWER_BASE;
511 
512 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
513 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
514 
515 	clrbits_le32(&power_regs->hw_power_dcdc4p2,
516 			POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
517 	writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
518 
519 	/* 5V to battery handoff. */
520 	setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
521 	early_delay(30);
522 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
523 
524 	writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
525 
526 	clrsetbits_le32(&power_regs->hw_power_minpwr,
527 			POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
528 
529 	mxs_power_set_linreg();
530 
531 	clrbits_le32(&power_regs->hw_power_vdddctrl,
532 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
533 
534 	clrbits_le32(&power_regs->hw_power_vddactrl,
535 		POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
536 
537 	clrbits_le32(&power_regs->hw_power_vddioctrl,
538 		POWER_VDDIOCTRL_DISABLE_FET);
539 
540 	setbits_le32(&power_regs->hw_power_5vctrl,
541 		POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
542 
543 	setbits_le32(&power_regs->hw_power_5vctrl,
544 		POWER_5VCTRL_ENABLE_DCDC);
545 
546 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
547 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
548 		0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
549 }
550 
551 static void mxs_handle_5v_conflict(void)
552 {
553 	struct mxs_power_regs *power_regs =
554 		(struct mxs_power_regs *)MXS_POWER_BASE;
555 	uint32_t tmp;
556 
557 	setbits_le32(&power_regs->hw_power_vddioctrl,
558 			POWER_VDDIOCTRL_BO_OFFSET_MASK);
559 
560 	for (;;) {
561 		tmp = readl(&power_regs->hw_power_sts);
562 
563 		if (tmp & POWER_STS_VDDIO_BO) {
564 			/*
565 			 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
566 			 * unreliable
567 			 */
568 			mxs_powerdown();
569 			break;
570 		}
571 
572 		if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
573 			mxs_boot_valid_5v();
574 			break;
575 		} else {
576 			mxs_powerdown();
577 			break;
578 		}
579 
580 		if (tmp & POWER_STS_PSWITCH_MASK) {
581 			mxs_batt_boot();
582 			break;
583 		}
584 	}
585 }
586 
587 static void mxs_5v_boot(void)
588 {
589 	struct mxs_power_regs *power_regs =
590 		(struct mxs_power_regs *)MXS_POWER_BASE;
591 
592 	/*
593 	 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
594 	 * but their implementation always returns 1 so we omit it here.
595 	 */
596 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
597 		mxs_boot_valid_5v();
598 		return;
599 	}
600 
601 	early_delay(1000);
602 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
603 		mxs_boot_valid_5v();
604 		return;
605 	}
606 
607 	mxs_handle_5v_conflict();
608 }
609 
610 static void mxs_init_batt_bo(void)
611 {
612 	struct mxs_power_regs *power_regs =
613 		(struct mxs_power_regs *)MXS_POWER_BASE;
614 
615 	/* Brownout at 3V */
616 	clrsetbits_le32(&power_regs->hw_power_battmonitor,
617 		POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
618 		15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
619 
620 	writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
621 	writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
622 }
623 
624 static void mxs_switch_vddd_to_dcdc_source(void)
625 {
626 	struct mxs_power_regs *power_regs =
627 		(struct mxs_power_regs *)MXS_POWER_BASE;
628 
629 	clrsetbits_le32(&power_regs->hw_power_vdddctrl,
630 		POWER_VDDDCTRL_LINREG_OFFSET_MASK,
631 		POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
632 
633 	clrbits_le32(&power_regs->hw_power_vdddctrl,
634 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
635 		POWER_VDDDCTRL_DISABLE_STEPPING);
636 }
637 
638 static void mxs_power_configure_power_source(void)
639 {
640 	int batt_ready, batt_good;
641 	struct mxs_power_regs *power_regs =
642 		(struct mxs_power_regs *)MXS_POWER_BASE;
643 	struct mxs_lradc_regs *lradc_regs =
644 		(struct mxs_lradc_regs *)MXS_LRADC_BASE;
645 
646 	mxs_src_power_init();
647 
648 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
649 		batt_ready = mxs_is_batt_ready();
650 		if (batt_ready) {
651 			/* 5V source detected, good battery detected. */
652 			mxs_batt_boot();
653 		} else {
654 			batt_good = mxs_is_batt_good();
655 			if (!batt_good) {
656 				/* 5V source detected, bad battery detected. */
657 				writel(LRADC_CONVERSION_AUTOMATIC,
658 					&lradc_regs->hw_lradc_conversion_clr);
659 				clrbits_le32(&power_regs->hw_power_battmonitor,
660 					POWER_BATTMONITOR_BATT_VAL_MASK);
661 			}
662 			mxs_5v_boot();
663 		}
664 	} else {
665 		/* 5V not detected, booting from battery. */
666 		mxs_batt_boot();
667 	}
668 
669 	mxs_power_clock2pll();
670 
671 	mxs_init_batt_bo();
672 
673 	mxs_switch_vddd_to_dcdc_source();
674 
675 #ifdef CONFIG_MX23
676 	/* Fire up the VDDMEM LinReg now that we're all set. */
677 	writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
678 		&power_regs->hw_power_vddmemctrl);
679 #endif
680 }
681 
682 static void mxs_enable_output_rail_protection(void)
683 {
684 	struct mxs_power_regs *power_regs =
685 		(struct mxs_power_regs *)MXS_POWER_BASE;
686 
687 	writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
688 		POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
689 
690 	setbits_le32(&power_regs->hw_power_vdddctrl,
691 			POWER_VDDDCTRL_PWDN_BRNOUT);
692 
693 	setbits_le32(&power_regs->hw_power_vddactrl,
694 			POWER_VDDACTRL_PWDN_BRNOUT);
695 
696 	setbits_le32(&power_regs->hw_power_vddioctrl,
697 			POWER_VDDIOCTRL_PWDN_BRNOUT);
698 }
699 
700 static int mxs_get_vddio_power_source_off(void)
701 {
702 	struct mxs_power_regs *power_regs =
703 		(struct mxs_power_regs *)MXS_POWER_BASE;
704 	uint32_t tmp;
705 
706 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
707 		tmp = readl(&power_regs->hw_power_vddioctrl);
708 		if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
709 			if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
710 				POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
711 				return 1;
712 			}
713 		}
714 
715 		if (!(readl(&power_regs->hw_power_5vctrl) &
716 			POWER_5VCTRL_ENABLE_DCDC)) {
717 			if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
718 				POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
719 				return 1;
720 			}
721 		}
722 	}
723 
724 	return 0;
725 
726 }
727 
728 static int mxs_get_vddd_power_source_off(void)
729 {
730 	struct mxs_power_regs *power_regs =
731 		(struct mxs_power_regs *)MXS_POWER_BASE;
732 	uint32_t tmp;
733 
734 	tmp = readl(&power_regs->hw_power_vdddctrl);
735 	if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
736 		if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
737 			POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
738 			return 1;
739 		}
740 	}
741 
742 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
743 		if (!(readl(&power_regs->hw_power_5vctrl) &
744 			POWER_5VCTRL_ENABLE_DCDC)) {
745 			return 1;
746 		}
747 	}
748 
749 	if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
750 		if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
751 			POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
752 			return 1;
753 		}
754 	}
755 
756 	return 0;
757 }
758 
759 struct mxs_vddx_cfg {
760 	uint32_t		*reg;
761 	uint8_t			step_mV;
762 	uint16_t		lowest_mV;
763 	int			(*powered_by_linreg)(void);
764 	uint32_t		trg_mask;
765 	uint32_t		bo_irq;
766 	uint32_t		bo_enirq;
767 	uint32_t		bo_offset_mask;
768 	uint32_t		bo_offset_offset;
769 };
770 
771 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
772 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
773 					hw_power_vddioctrl),
774 #if defined(CONFIG_MX23)
775 	.step_mV		= 25,
776 #else
777 	.step_mV		= 50,
778 #endif
779 	.lowest_mV		= 2800,
780 	.powered_by_linreg	= mxs_get_vddio_power_source_off,
781 	.trg_mask		= POWER_VDDIOCTRL_TRG_MASK,
782 	.bo_irq			= POWER_CTRL_VDDIO_BO_IRQ,
783 	.bo_enirq		= POWER_CTRL_ENIRQ_VDDIO_BO,
784 	.bo_offset_mask		= POWER_VDDIOCTRL_BO_OFFSET_MASK,
785 	.bo_offset_offset	= POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
786 };
787 
788 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
789 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
790 					hw_power_vdddctrl),
791 	.step_mV		= 25,
792 	.lowest_mV		= 800,
793 	.powered_by_linreg	= mxs_get_vddd_power_source_off,
794 	.trg_mask		= POWER_VDDDCTRL_TRG_MASK,
795 	.bo_irq			= POWER_CTRL_VDDD_BO_IRQ,
796 	.bo_enirq		= POWER_CTRL_ENIRQ_VDDD_BO,
797 	.bo_offset_mask		= POWER_VDDDCTRL_BO_OFFSET_MASK,
798 	.bo_offset_offset	= POWER_VDDDCTRL_BO_OFFSET_OFFSET,
799 };
800 
801 #ifdef CONFIG_MX23
802 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
803 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
804 					hw_power_vddmemctrl),
805 	.step_mV		= 50,
806 	.lowest_mV		= 1700,
807 	.powered_by_linreg	= NULL,
808 	.trg_mask		= POWER_VDDMEMCTRL_TRG_MASK,
809 	.bo_irq			= 0,
810 	.bo_enirq		= 0,
811 	.bo_offset_mask		= 0,
812 	.bo_offset_offset	= 0,
813 };
814 #endif
815 
816 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
817 				uint32_t new_target, uint32_t new_brownout)
818 {
819 	struct mxs_power_regs *power_regs =
820 		(struct mxs_power_regs *)MXS_POWER_BASE;
821 	uint32_t cur_target, diff, bo_int = 0;
822 	uint32_t powered_by_linreg = 0;
823 	int adjust_up, tmp;
824 
825 	new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
826 
827 	cur_target = readl(cfg->reg);
828 	cur_target &= cfg->trg_mask;
829 	cur_target *= cfg->step_mV;
830 	cur_target += cfg->lowest_mV;
831 
832 	adjust_up = new_target > cur_target;
833 	if (cfg->powered_by_linreg)
834 		powered_by_linreg = cfg->powered_by_linreg();
835 
836 	if (adjust_up && cfg->bo_irq) {
837 		if (powered_by_linreg) {
838 			bo_int = readl(cfg->reg);
839 			clrbits_le32(cfg->reg, cfg->bo_enirq);
840 		}
841 		setbits_le32(cfg->reg, cfg->bo_offset_mask);
842 	}
843 
844 	do {
845 		if (abs(new_target - cur_target) > 100) {
846 			if (adjust_up)
847 				diff = cur_target + 100;
848 			else
849 				diff = cur_target - 100;
850 		} else {
851 			diff = new_target;
852 		}
853 
854 		diff -= cfg->lowest_mV;
855 		diff /= cfg->step_mV;
856 
857 		clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
858 
859 		if (powered_by_linreg ||
860 			(readl(&power_regs->hw_power_sts) &
861 				POWER_STS_VDD5V_GT_VDDIO))
862 			early_delay(500);
863 		else {
864 			for (;;) {
865 				tmp = readl(&power_regs->hw_power_sts);
866 				if (tmp & POWER_STS_DC_OK)
867 					break;
868 			}
869 		}
870 
871 		cur_target = readl(cfg->reg);
872 		cur_target &= cfg->trg_mask;
873 		cur_target *= cfg->step_mV;
874 		cur_target += cfg->lowest_mV;
875 	} while (new_target > cur_target);
876 
877 	if (cfg->bo_irq) {
878 		if (adjust_up && powered_by_linreg) {
879 			writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
880 			if (bo_int & cfg->bo_enirq)
881 				setbits_le32(cfg->reg, cfg->bo_enirq);
882 		}
883 
884 		clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
885 				new_brownout << cfg->bo_offset_offset);
886 	}
887 }
888 
889 static void mxs_setup_batt_detect(void)
890 {
891 	mxs_lradc_init();
892 	mxs_lradc_enable_batt_measurement();
893 	early_delay(10);
894 }
895 
896 static void mxs_ungate_power(void)
897 {
898 #ifdef CONFIG_MX23
899 	struct mxs_power_regs *power_regs =
900 		(struct mxs_power_regs *)MXS_POWER_BASE;
901 
902 	writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
903 #endif
904 }
905 
906 void mxs_power_init(void)
907 {
908 	struct mxs_power_regs *power_regs =
909 		(struct mxs_power_regs *)MXS_POWER_BASE;
910 
911 	mxs_ungate_power();
912 
913 	mxs_power_clock2xtal();
914 	mxs_power_clear_auto_restart();
915 	mxs_power_set_linreg();
916 	mxs_power_setup_5v_detect();
917 
918 	mxs_setup_batt_detect();
919 
920 	mxs_power_configure_power_source();
921 	mxs_enable_output_rail_protection();
922 
923 	mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
924 	mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
925 #ifdef CONFIG_MX23
926 	mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
927 #endif
928 	writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
929 		POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
930 		POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
931 		POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
932 
933 	writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
934 
935 	early_delay(1000);
936 }
937 
938 #ifdef	CONFIG_SPL_MXS_PSWITCH_WAIT
939 void mxs_power_wait_pswitch(void)
940 {
941 	struct mxs_power_regs *power_regs =
942 		(struct mxs_power_regs *)MXS_POWER_BASE;
943 
944 	while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
945 		;
946 }
947 #endif
948