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