1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Freescale i.MX28 Boot PMIC init
4  *
5  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
6  * on behalf of DENX Software Engineering GmbH
7  */
8 
9 #include <common.h>
10 #include <config.h>
11 #include <asm/io.h>
12 #include <asm/arch/imx-regs.h>
13 
14 #include "mxs_init.h"
15 
16 #ifdef CONFIG_SYS_MXS_VDD5V_ONLY
17 #define DCDC4P2_DROPOUT_CONFIG	POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
18 				POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
19 #else
20 #define DCDC4P2_DROPOUT_CONFIG	POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
21 				POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
22 #endif
23 /**
24  * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
25  *
26  * This function switches the CPU core clock from PLL to 24MHz XTAL
27  * oscilator. This is necessary if the PLL is being reconfigured to
28  * prevent crash of the CPU core.
29  */
mxs_power_clock2xtal(void)30 static void mxs_power_clock2xtal(void)
31 {
32 	struct mxs_clkctrl_regs *clkctrl_regs =
33 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
34 
35 	debug("SPL: Switching CPU clock to 24MHz XTAL\n");
36 
37 	/* Set XTAL as CPU reference clock */
38 	writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
39 		&clkctrl_regs->hw_clkctrl_clkseq_set);
40 }
41 
42 /**
43  * mxs_power_clock2pll() - Switch CPU core clock source to PLL
44  *
45  * This function switches the CPU core clock from 24MHz XTAL oscilator
46  * to PLL. This can only be called once the PLL has re-locked and once
47  * the PLL is stable after reconfiguration.
48  */
mxs_power_clock2pll(void)49 static void mxs_power_clock2pll(void)
50 {
51 	struct mxs_clkctrl_regs *clkctrl_regs =
52 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
53 
54 	debug("SPL: Switching CPU core clock source to PLL\n");
55 
56 	/*
57 	 * TODO: Are we really? It looks like we turn on PLL0, but we then
58 	 * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already
59 	 * set by mxs_power_clock2xtal()). Clearing this bit here seems to
60 	 * introduce some instability (causing the CPU core to hang). Maybe
61 	 * we aren't giving PLL0 enough time to stabilise?
62 	 */
63 	setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
64 			CLKCTRL_PLL0CTRL0_POWER);
65 	early_delay(100);
66 
67 	/*
68 	 * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a
69 	 * wait on the PLL0 LOCK bit?
70 	 */
71 	setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
72 			CLKCTRL_CLKSEQ_BYPASS_CPU);
73 }
74 
75 /**
76  * mxs_power_set_auto_restart() - Set the auto-restart bit
77  *
78  * This function ungates the RTC block and sets the AUTO_RESTART
79  * bit to work around a design bug on MX28EVK Rev. A .
80  */
81 
mxs_power_set_auto_restart(void)82 static void mxs_power_set_auto_restart(void)
83 {
84 	struct mxs_rtc_regs *rtc_regs =
85 		(struct mxs_rtc_regs *)MXS_RTC_BASE;
86 
87 	debug("SPL: Setting auto-restart bit\n");
88 
89 	writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
90 	while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
91 		;
92 
93 	writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
94 	while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
95 		;
96 
97 	/* Do nothing if flag already set */
98 	if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
99 		return;
100 
101 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
102 		;
103 
104 	setbits_le32(&rtc_regs->hw_rtc_persistent0,
105 			RTC_PERSISTENT0_AUTO_RESTART);
106 	writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
107 	writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
108 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
109 		;
110 	while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
111 		;
112 }
113 
114 /**
115  * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter
116  *
117  * This function configures the VDDIO, VDDA and VDDD linear regulators output
118  * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching
119  * converter. This is the recommended setting for the case where we use both
120  * linear regulators and DC-DC converter to power the VDDIO rail.
121  */
mxs_power_set_linreg(void)122 static void mxs_power_set_linreg(void)
123 {
124 	struct mxs_power_regs *power_regs =
125 		(struct mxs_power_regs *)MXS_POWER_BASE;
126 
127 	/* Set linear regulator 25mV below switching converter */
128 	debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
129 	clrsetbits_le32(&power_regs->hw_power_vdddctrl,
130 			POWER_VDDDCTRL_LINREG_OFFSET_MASK,
131 			POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
132 
133 	debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
134 	clrsetbits_le32(&power_regs->hw_power_vddactrl,
135 			POWER_VDDACTRL_LINREG_OFFSET_MASK,
136 			POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
137 
138 	debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
139 	clrsetbits_le32(&power_regs->hw_power_vddioctrl,
140 			POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
141 			POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
142 }
143 
144 /**
145  * mxs_get_batt_volt() - Measure battery input voltage
146  *
147  * This function retrieves the battery input voltage and returns it.
148  */
mxs_get_batt_volt(void)149 static int mxs_get_batt_volt(void)
150 {
151 	struct mxs_power_regs *power_regs =
152 		(struct mxs_power_regs *)MXS_POWER_BASE;
153 	uint32_t volt = readl(&power_regs->hw_power_battmonitor);
154 	volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
155 	volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
156 	volt *= 8;
157 
158 	debug("SPL: Battery Voltage = %dmV\n", volt);
159 	return volt;
160 }
161 
162 /**
163  * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot
164  *
165  * This function checks if the battery input voltage is higher than 3.6V and
166  * therefore allows the system to successfully boot using this power source.
167  */
mxs_is_batt_ready(void)168 static int mxs_is_batt_ready(void)
169 {
170 	return (mxs_get_batt_volt() >= 3600);
171 }
172 
173 /**
174  * mxs_is_batt_good() - Test if battery is operational at all
175  *
176  * This function starts recharging the battery and tests if the input current
177  * provided by the 5V input recharging the battery is also sufficient to power
178  * the DC-DC converter.
179  */
mxs_is_batt_good(void)180 static int mxs_is_batt_good(void)
181 {
182 	struct mxs_power_regs *power_regs =
183 		(struct mxs_power_regs *)MXS_POWER_BASE;
184 	uint32_t volt = mxs_get_batt_volt();
185 
186 	if ((volt >= 2400) && (volt <= 4300)) {
187 		debug("SPL: Battery is good\n");
188 		return 1;
189 	}
190 
191 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
192 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
193 		0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
194 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
195 		&power_regs->hw_power_5vctrl_clr);
196 
197 	clrsetbits_le32(&power_regs->hw_power_charge,
198 		POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
199 		POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
200 
201 	writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
202 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
203 		&power_regs->hw_power_5vctrl_clr);
204 
205 	early_delay(500000);
206 
207 	volt = mxs_get_batt_volt();
208 
209 	if (volt >= 3500) {
210 		debug("SPL: Battery Voltage too high\n");
211 		return 0;
212 	}
213 
214 	if (volt >= 2400) {
215 		debug("SPL: Battery is good\n");
216 		return 1;
217 	}
218 
219 	writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
220 		&power_regs->hw_power_charge_clr);
221 	writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
222 
223 	debug("SPL: Battery Voltage too low\n");
224 	return 0;
225 }
226 
227 /**
228  * mxs_power_setup_5v_detect() - Start the 5V input detection comparator
229  *
230  * This function enables the 5V detection comparator and sets the 5V valid
231  * threshold to 4.4V . We use 4.4V threshold here to make sure that even
232  * under high load, the voltage drop on the 5V input won't be so critical
233  * to cause undervolt on the 4P2 linear regulator supplying the DC-DC
234  * converter and thus making the system crash.
235  */
mxs_power_setup_5v_detect(void)236 static void mxs_power_setup_5v_detect(void)
237 {
238 	struct mxs_power_regs *power_regs =
239 		(struct mxs_power_regs *)MXS_POWER_BASE;
240 
241 	/* Start 5V detection */
242 	debug("SPL: Starting 5V input detection comparator\n");
243 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
244 			POWER_5VCTRL_VBUSVALID_TRSH_MASK,
245 			POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
246 			POWER_5VCTRL_PWRUP_VBUS_CMPS);
247 }
248 
249 /**
250  * mxs_power_switch_dcdc_clocksource() - Switch PLL clock for DC-DC converters
251  * @freqsel:	One of the POWER_MISC_FREQSEL_xxx defines to select the clock
252  *
253  * This function configures and then enables an alternative PLL clock source
254  * for the DC-DC converters.
255  */
mxs_power_switch_dcdc_clocksource(uint32_t freqsel)256 void mxs_power_switch_dcdc_clocksource(uint32_t freqsel)
257 {
258 	struct mxs_power_regs *power_regs =
259 		(struct mxs_power_regs *)MXS_POWER_BASE;
260 
261 	/* Select clocksource for DC-DC converters */
262 	clrsetbits_le32(&power_regs->hw_power_misc,
263 			POWER_MISC_FREQSEL_MASK,
264 			freqsel);
265 	setbits_le32(&power_regs->hw_power_misc,
266 			POWER_MISC_SEL_PLLCLK);
267 }
268 
269 /**
270  * mxs_power_setup_dcdc_clocksource() - Setup PLL clock source for DC-DC converters
271  *
272  * Normally, there is no need to switch DC-DC clocksource. This is the reason,
273  * why this function is a stub and does nothing. However, boards can implement
274  * this function when required and call mxs_power_switch_dcdc_clocksource() to
275  * switch to an alternative clock source.
276  */
mxs_power_setup_dcdc_clocksource(void)277 __weak void mxs_power_setup_dcdc_clocksource(void)
278 {
279 	debug("SPL: Using default DC-DC clocksource\n");
280 }
281 
282 /**
283  * mxs_src_power_init() - Preconfigure the power block
284  *
285  * This function configures reasonable values for the DC-DC control loop
286  * and battery monitor.
287  */
mxs_src_power_init(void)288 static void mxs_src_power_init(void)
289 {
290 	struct mxs_power_regs *power_regs =
291 		(struct mxs_power_regs *)MXS_POWER_BASE;
292 
293 	debug("SPL: Pre-Configuring power block\n");
294 
295 	/* Improve efficieny and reduce transient ripple */
296 	writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
297 		POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
298 
299 	clrsetbits_le32(&power_regs->hw_power_dclimits,
300 			POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
301 			0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
302 
303 	setbits_le32(&power_regs->hw_power_battmonitor,
304 			POWER_BATTMONITOR_EN_BATADJ);
305 
306 	/* Increase the RCSCALE level for quick DCDC response to dynamic load */
307 	clrsetbits_le32(&power_regs->hw_power_loopctrl,
308 			POWER_LOOPCTRL_EN_RCSCALE_MASK,
309 			POWER_LOOPCTRL_RCSCALE_THRESH |
310 			POWER_LOOPCTRL_EN_RCSCALE_8X);
311 
312 	clrsetbits_le32(&power_regs->hw_power_minpwr,
313 			POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
314 
315 	/* 5V to battery handoff ... FIXME */
316 	setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
317 	early_delay(30);
318 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
319 }
320 
321 /**
322  * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator
323  *
324  * This function configures the necessary parameters for the 4P2 linear
325  * regulator to supply the DC-DC converter from 5V input.
326  */
mxs_power_init_4p2_params(void)327 static void mxs_power_init_4p2_params(void)
328 {
329 	struct mxs_power_regs *power_regs =
330 		(struct mxs_power_regs *)MXS_POWER_BASE;
331 
332 	debug("SPL: Configuring common 4P2 regulator params\n");
333 
334 	/* Setup 4P2 parameters */
335 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
336 		POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
337 		POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
338 
339 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
340 		POWER_5VCTRL_HEADROOM_ADJ_MASK,
341 		0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
342 
343 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
344 		POWER_DCDC4P2_DROPOUT_CTRL_MASK,
345 		DCDC4P2_DROPOUT_CONFIG);
346 
347 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
348 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
349 		0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
350 }
351 
352 /**
353  * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2
354  * @xfer:	Select if the input shall be enabled or disabled
355  *
356  * This function enables or disables the 4P2 input into the DC-DC converter.
357  */
mxs_enable_4p2_dcdc_input(int xfer)358 static void mxs_enable_4p2_dcdc_input(int xfer)
359 {
360 	struct mxs_power_regs *power_regs =
361 		(struct mxs_power_regs *)MXS_POWER_BASE;
362 	uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
363 	uint32_t prev_5v_brnout, prev_5v_droop;
364 
365 	debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
366 
367 	if (xfer && (readl(&power_regs->hw_power_5vctrl) &
368 			POWER_5VCTRL_ENABLE_DCDC)) {
369 		return;
370 	}
371 
372 	prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
373 				POWER_5VCTRL_PWDN_5VBRNOUT;
374 	prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
375 				POWER_CTRL_ENIRQ_VDD5V_DROOP;
376 
377 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
378 	writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
379 		&power_regs->hw_power_reset);
380 
381 	clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
382 
383 	/*
384 	 * Recording orignal values that will be modified temporarlily
385 	 * to handle a chip bug. See chip errata for CQ ENGR00115837
386 	 */
387 	tmp = readl(&power_regs->hw_power_5vctrl);
388 	vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
389 	vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
390 
391 	pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
392 
393 	/*
394 	 * Disable mechanisms that get erroneously tripped by when setting
395 	 * the DCDC4P2 EN_DCDC
396 	 */
397 	clrbits_le32(&power_regs->hw_power_5vctrl,
398 		POWER_5VCTRL_VBUSVALID_5VDETECT |
399 		POWER_5VCTRL_VBUSVALID_TRSH_MASK);
400 
401 	writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
402 
403 	if (xfer) {
404 		setbits_le32(&power_regs->hw_power_5vctrl,
405 				POWER_5VCTRL_DCDC_XFER);
406 		early_delay(20);
407 		clrbits_le32(&power_regs->hw_power_5vctrl,
408 				POWER_5VCTRL_DCDC_XFER);
409 
410 		setbits_le32(&power_regs->hw_power_5vctrl,
411 				POWER_5VCTRL_ENABLE_DCDC);
412 	} else {
413 		setbits_le32(&power_regs->hw_power_dcdc4p2,
414 				POWER_DCDC4P2_ENABLE_DCDC);
415 	}
416 
417 	early_delay(25);
418 
419 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
420 			POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
421 
422 	if (vbus_5vdetect)
423 		writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
424 
425 	if (!pwd_bo)
426 		clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
427 
428 	while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
429 		writel(POWER_CTRL_VBUS_VALID_IRQ,
430 			&power_regs->hw_power_ctrl_clr);
431 
432 	if (prev_5v_brnout) {
433 		writel(POWER_5VCTRL_PWDN_5VBRNOUT,
434 			&power_regs->hw_power_5vctrl_set);
435 		writel(POWER_RESET_UNLOCK_KEY,
436 			&power_regs->hw_power_reset);
437 	} else {
438 		writel(POWER_5VCTRL_PWDN_5VBRNOUT,
439 			&power_regs->hw_power_5vctrl_clr);
440 		writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
441 			&power_regs->hw_power_reset);
442 	}
443 
444 	while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
445 		writel(POWER_CTRL_VDD5V_DROOP_IRQ,
446 			&power_regs->hw_power_ctrl_clr);
447 
448 	if (prev_5v_droop)
449 		clrbits_le32(&power_regs->hw_power_ctrl,
450 				POWER_CTRL_ENIRQ_VDD5V_DROOP);
451 	else
452 		setbits_le32(&power_regs->hw_power_ctrl,
453 				POWER_CTRL_ENIRQ_VDD5V_DROOP);
454 }
455 
456 /**
457  * mxs_power_init_4p2_regulator() - Start the 4P2 regulator
458  *
459  * This function enables the 4P2 regulator and switches the DC-DC converter
460  * to use the 4P2 input.
461  */
mxs_power_init_4p2_regulator(void)462 static void mxs_power_init_4p2_regulator(void)
463 {
464 	struct mxs_power_regs *power_regs =
465 		(struct mxs_power_regs *)MXS_POWER_BASE;
466 	uint32_t tmp, tmp2;
467 
468 	debug("SPL: Enabling 4P2 regulator\n");
469 
470 	setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
471 
472 	writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
473 
474 	writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
475 		&power_regs->hw_power_5vctrl_clr);
476 	clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
477 
478 	/* Power up the 4p2 rail and logic/control */
479 	writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
480 		&power_regs->hw_power_5vctrl_clr);
481 
482 	/*
483 	 * Start charging up the 4p2 capacitor. We ramp of this charge
484 	 * gradually to avoid large inrush current from the 5V cable which can
485 	 * cause transients/problems
486 	 */
487 	debug("SPL: Charging 4P2 capacitor\n");
488 	mxs_enable_4p2_dcdc_input(0);
489 
490 	if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
491 		/*
492 		 * If we arrived here, we were unable to recover from mx23 chip
493 		 * errata 5837. 4P2 is disabled and sufficient battery power is
494 		 * not present. Exiting to not enable DCDC power during 5V
495 		 * connected state.
496 		 */
497 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
498 			POWER_DCDC4P2_ENABLE_DCDC);
499 		writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
500 			&power_regs->hw_power_5vctrl_set);
501 
502 		debug("SPL: Unable to recover from mx23 errata 5837\n");
503 		hang();
504 	}
505 
506 	/*
507 	 * Here we set the 4p2 brownout level to something very close to 4.2V.
508 	 * We then check the brownout status. If the brownout status is false,
509 	 * the voltage is already close to the target voltage of 4.2V so we
510 	 * can go ahead and set the 4P2 current limit to our max target limit.
511 	 * If the brownout status is true, we need to ramp us the current limit
512 	 * so that we don't cause large inrush current issues. We step up the
513 	 * current limit until the brownout status is false or until we've
514 	 * reached our maximum defined 4p2 current limit.
515 	 */
516 	debug("SPL: Setting 4P2 brownout level\n");
517 	clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
518 			POWER_DCDC4P2_BO_MASK,
519 			22 << POWER_DCDC4P2_BO_OFFSET);	/* 4.15V */
520 
521 	if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
522 		setbits_le32(&power_regs->hw_power_5vctrl,
523 			0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
524 	} else {
525 		tmp = (readl(&power_regs->hw_power_5vctrl) &
526 			POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
527 			POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
528 		while (tmp < 0x3f) {
529 			if (!(readl(&power_regs->hw_power_sts) &
530 					POWER_STS_DCDC_4P2_BO)) {
531 				tmp = readl(&power_regs->hw_power_5vctrl);
532 				tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
533 				early_delay(100);
534 				writel(tmp, &power_regs->hw_power_5vctrl);
535 				break;
536 			} else {
537 				tmp++;
538 				tmp2 = readl(&power_regs->hw_power_5vctrl);
539 				tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
540 				tmp2 |= tmp <<
541 					POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
542 				writel(tmp2, &power_regs->hw_power_5vctrl);
543 				early_delay(100);
544 			}
545 		}
546 	}
547 
548 	clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
549 	writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
550 }
551 
552 /**
553  * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source
554  *
555  * This function configures the DC-DC converter to be supplied from the 4P2
556  * linear regulator.
557  */
mxs_power_init_dcdc_4p2_source(void)558 static void mxs_power_init_dcdc_4p2_source(void)
559 {
560 	struct mxs_power_regs *power_regs =
561 		(struct mxs_power_regs *)MXS_POWER_BASE;
562 
563 	debug("SPL: Switching DC-DC converters to 4P2\n");
564 
565 	if (!(readl(&power_regs->hw_power_dcdc4p2) &
566 		POWER_DCDC4P2_ENABLE_DCDC)) {
567 		debug("SPL: Already switched - aborting\n");
568 		hang();
569 	}
570 
571 	mxs_enable_4p2_dcdc_input(1);
572 
573 	if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
574 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
575 			POWER_DCDC4P2_ENABLE_DCDC);
576 		writel(POWER_5VCTRL_ENABLE_DCDC,
577 			&power_regs->hw_power_5vctrl_clr);
578 		writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
579 			&power_regs->hw_power_5vctrl_set);
580 	}
581 }
582 
583 /**
584  * mxs_power_enable_4p2() - Power up the 4P2 regulator
585  *
586  * This function drives the process of powering up the 4P2 linear regulator
587  * and switching the DC-DC converter input over to the 4P2 linear regulator.
588  */
mxs_power_enable_4p2(void)589 static void mxs_power_enable_4p2(void)
590 {
591 	struct mxs_power_regs *power_regs =
592 		(struct mxs_power_regs *)MXS_POWER_BASE;
593 	uint32_t vdddctrl, vddactrl, vddioctrl;
594 	uint32_t tmp;
595 
596 	debug("SPL: Powering up 4P2 regulator\n");
597 
598 	vdddctrl = readl(&power_regs->hw_power_vdddctrl);
599 	vddactrl = readl(&power_regs->hw_power_vddactrl);
600 	vddioctrl = readl(&power_regs->hw_power_vddioctrl);
601 
602 	setbits_le32(&power_regs->hw_power_vdddctrl,
603 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
604 		POWER_VDDDCTRL_PWDN_BRNOUT);
605 
606 	setbits_le32(&power_regs->hw_power_vddactrl,
607 		POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
608 		POWER_VDDACTRL_PWDN_BRNOUT);
609 
610 	setbits_le32(&power_regs->hw_power_vddioctrl,
611 		POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
612 
613 	mxs_power_init_4p2_params();
614 	mxs_power_init_4p2_regulator();
615 
616 	/* Shutdown battery (none present) */
617 	if (!mxs_is_batt_ready()) {
618 		clrbits_le32(&power_regs->hw_power_dcdc4p2,
619 				POWER_DCDC4P2_BO_MASK);
620 		writel(POWER_CTRL_DCDC4P2_BO_IRQ,
621 				&power_regs->hw_power_ctrl_clr);
622 		writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
623 				&power_regs->hw_power_ctrl_clr);
624 	}
625 
626 	mxs_power_init_dcdc_4p2_source();
627 
628 	writel(vdddctrl, &power_regs->hw_power_vdddctrl);
629 	early_delay(20);
630 	writel(vddactrl, &power_regs->hw_power_vddactrl);
631 	early_delay(20);
632 	writel(vddioctrl, &power_regs->hw_power_vddioctrl);
633 
634 	/*
635 	 * Check if FET is enabled on either powerout and if so,
636 	 * disable load.
637 	 */
638 	tmp = 0;
639 	tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
640 			POWER_VDDDCTRL_DISABLE_FET);
641 	tmp |= !(readl(&power_regs->hw_power_vddactrl) &
642 			POWER_VDDACTRL_DISABLE_FET);
643 	tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
644 			POWER_VDDIOCTRL_DISABLE_FET);
645 	if (tmp)
646 		writel(POWER_CHARGE_ENABLE_LOAD,
647 			&power_regs->hw_power_charge_clr);
648 
649 	debug("SPL: 4P2 regulator powered-up\n");
650 }
651 
652 /**
653  * mxs_boot_valid_5v() - Boot from 5V supply
654  *
655  * This function configures the power block to boot from valid 5V input.
656  * This is called only if the 5V is reliable and can properly supply the
657  * CPU. This function proceeds to configure the 4P2 converter to be supplied
658  * from the 5V input.
659  */
mxs_boot_valid_5v(void)660 static void mxs_boot_valid_5v(void)
661 {
662 	struct mxs_power_regs *power_regs =
663 		(struct mxs_power_regs *)MXS_POWER_BASE;
664 
665 	debug("SPL: Booting from 5V supply\n");
666 
667 	/*
668 	 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
669 	 * disconnect event. FIXME
670 	 */
671 	writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
672 		&power_regs->hw_power_5vctrl_set);
673 
674 	/* Configure polarity to check for 5V disconnection. */
675 	writel(POWER_CTRL_POLARITY_VBUSVALID |
676 		POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
677 		&power_regs->hw_power_ctrl_clr);
678 
679 	writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
680 		&power_regs->hw_power_ctrl_clr);
681 
682 	mxs_power_enable_4p2();
683 }
684 
685 /**
686  * mxs_powerdown() - Shut down the system
687  *
688  * This function powers down the CPU completely.
689  */
mxs_powerdown(void)690 static void mxs_powerdown(void)
691 {
692 	struct mxs_power_regs *power_regs =
693 		(struct mxs_power_regs *)MXS_POWER_BASE;
694 
695 	debug("Powering Down\n");
696 
697 	writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
698 	writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
699 		&power_regs->hw_power_reset);
700 }
701 
702 /**
703  * mxs_batt_boot() - Configure the power block to boot from battery input
704  *
705  * This function configures the power block to boot from the battery voltage
706  * supply.
707  */
mxs_batt_boot(void)708 static void mxs_batt_boot(void)
709 {
710 	struct mxs_power_regs *power_regs =
711 		(struct mxs_power_regs *)MXS_POWER_BASE;
712 
713 	debug("SPL: Configuring power block to boot from battery\n");
714 
715 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
716 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
717 
718 	clrbits_le32(&power_regs->hw_power_dcdc4p2,
719 			POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
720 	writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
721 
722 	/* 5V to battery handoff. */
723 	setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
724 	early_delay(30);
725 	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
726 
727 	writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
728 
729 	clrsetbits_le32(&power_regs->hw_power_minpwr,
730 			POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
731 
732 	mxs_power_set_linreg();
733 
734 	clrbits_le32(&power_regs->hw_power_vdddctrl,
735 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
736 
737 	clrbits_le32(&power_regs->hw_power_vddactrl,
738 		POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
739 
740 	clrbits_le32(&power_regs->hw_power_vddioctrl,
741 		POWER_VDDIOCTRL_DISABLE_FET);
742 
743 	setbits_le32(&power_regs->hw_power_5vctrl,
744 		POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
745 
746 	setbits_le32(&power_regs->hw_power_5vctrl,
747 		POWER_5VCTRL_ENABLE_DCDC);
748 
749 	clrsetbits_le32(&power_regs->hw_power_5vctrl,
750 		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
751 		0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
752 
753 	mxs_power_enable_4p2();
754 }
755 
756 /**
757  * mxs_handle_5v_conflict() - Test if the 5V input is reliable
758  *
759  * This function tests if the 5V input can reliably supply the system. If it
760  * can, then proceed to configuring the system to boot from 5V source, otherwise
761  * try booting from battery supply. If we can not boot from battery supply
762  * either, shut down the system.
763  */
mxs_handle_5v_conflict(void)764 static void mxs_handle_5v_conflict(void)
765 {
766 	struct mxs_power_regs *power_regs =
767 		(struct mxs_power_regs *)MXS_POWER_BASE;
768 	uint32_t tmp;
769 
770 	debug("SPL: Resolving 5V conflict\n");
771 
772 	setbits_le32(&power_regs->hw_power_vddioctrl,
773 			POWER_VDDIOCTRL_BO_OFFSET_MASK);
774 
775 	for (;;) {
776 		tmp = readl(&power_regs->hw_power_sts);
777 
778 		if (tmp & POWER_STS_VDDIO_BO) {
779 			/*
780 			 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
781 			 * unreliable
782 			 */
783 			debug("SPL: VDDIO has a brownout\n");
784 			mxs_powerdown();
785 			break;
786 		}
787 
788 		if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
789 			debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
790 			mxs_boot_valid_5v();
791 			break;
792 		} else {
793 			debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
794 			mxs_powerdown();
795 			break;
796 		}
797 
798 		/*
799 		 * TODO: I can't see this being reached. We'll either
800 		 * powerdown or boot from a stable 5V supply.
801 		 */
802 		if (tmp & POWER_STS_PSWITCH_MASK) {
803 			debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
804 			mxs_batt_boot();
805 			break;
806 		}
807 	}
808 }
809 
810 /**
811  * mxs_5v_boot() - Configure the power block to boot from 5V input
812  *
813  * This function handles configuration of the power block when supplied by
814  * a 5V input.
815  */
mxs_5v_boot(void)816 static void mxs_5v_boot(void)
817 {
818 	struct mxs_power_regs *power_regs =
819 		(struct mxs_power_regs *)MXS_POWER_BASE;
820 
821 	debug("SPL: Configuring power block to boot from 5V input\n");
822 
823 	/*
824 	 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
825 	 * but their implementation always returns 1 so we omit it here.
826 	 */
827 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
828 		debug("SPL: 5V VDD good\n");
829 		mxs_boot_valid_5v();
830 		return;
831 	}
832 
833 	early_delay(1000);
834 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
835 		debug("SPL: 5V VDD good (after delay)\n");
836 		mxs_boot_valid_5v();
837 		return;
838 	}
839 
840 	debug("SPL: 5V VDD not good\n");
841 	mxs_handle_5v_conflict();
842 }
843 
844 /**
845  * mxs_init_batt_bo() - Configure battery brownout threshold
846  *
847  * This function configures the battery input brownout threshold. The value
848  * at which the battery brownout happens is configured to 3.0V in the code.
849  */
mxs_init_batt_bo(void)850 static void mxs_init_batt_bo(void)
851 {
852 	struct mxs_power_regs *power_regs =
853 		(struct mxs_power_regs *)MXS_POWER_BASE;
854 
855 	debug("SPL: Initialising battery brown-out level to 3.0V\n");
856 
857 	/* Brownout at 3V */
858 	clrsetbits_le32(&power_regs->hw_power_battmonitor,
859 		POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
860 		15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
861 
862 	writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
863 	writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
864 }
865 
866 /**
867  * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter
868  *
869  * This function turns off the VDDD linear regulator and therefore makes
870  * the VDDD rail be supplied only by the DC-DC converter.
871  */
mxs_switch_vddd_to_dcdc_source(void)872 static void mxs_switch_vddd_to_dcdc_source(void)
873 {
874 	struct mxs_power_regs *power_regs =
875 		(struct mxs_power_regs *)MXS_POWER_BASE;
876 
877 	debug("SPL: Switching VDDD to DC-DC converters\n");
878 
879 	clrsetbits_le32(&power_regs->hw_power_vdddctrl,
880 		POWER_VDDDCTRL_LINREG_OFFSET_MASK,
881 		POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
882 
883 	clrbits_le32(&power_regs->hw_power_vdddctrl,
884 		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
885 		POWER_VDDDCTRL_DISABLE_STEPPING);
886 }
887 
888 /**
889  * mxs_power_configure_power_source() - Configure power block source
890  *
891  * This function is the core of the power configuration logic. The function
892  * selects the power block input source and configures the whole power block
893  * accordingly. After the configuration is complete and the system is stable
894  * again, the function switches the CPU clock source back to PLL. Finally,
895  * the function switches the voltage rails to DC-DC converter.
896  */
mxs_power_configure_power_source(void)897 static void mxs_power_configure_power_source(void)
898 {
899 	int batt_ready, batt_good;
900 	struct mxs_power_regs *power_regs =
901 		(struct mxs_power_regs *)MXS_POWER_BASE;
902 	struct mxs_lradc_regs *lradc_regs =
903 		(struct mxs_lradc_regs *)MXS_LRADC_BASE;
904 
905 	debug("SPL: Configuring power source\n");
906 
907 	mxs_power_setup_dcdc_clocksource();
908 	mxs_src_power_init();
909 
910 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
911 		batt_ready = mxs_is_batt_ready();
912 		if (batt_ready) {
913 			/* 5V source detected, good battery detected. */
914 			mxs_batt_boot();
915 		} else {
916 			batt_good = mxs_is_batt_good();
917 			if (!batt_good) {
918 				/* 5V source detected, bad battery detected. */
919 				writel(LRADC_CONVERSION_AUTOMATIC,
920 					&lradc_regs->hw_lradc_conversion_clr);
921 				clrbits_le32(&power_regs->hw_power_battmonitor,
922 					POWER_BATTMONITOR_BATT_VAL_MASK);
923 			}
924 			mxs_5v_boot();
925 		}
926 	} else {
927 		/* 5V not detected, booting from battery. */
928 		mxs_batt_boot();
929 	}
930 
931 	/*
932 	 * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced
933 	 * from USB VBUS
934 	 */
935 	mxs_power_clock2pll();
936 
937 	mxs_init_batt_bo();
938 
939 	mxs_switch_vddd_to_dcdc_source();
940 
941 #ifdef CONFIG_MX23
942 	/* Fire up the VDDMEM LinReg now that we're all set. */
943 	debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
944 	writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
945 		&power_regs->hw_power_vddmemctrl);
946 #endif
947 }
948 
949 /**
950  * mxs_enable_output_rail_protection() - Enable power rail protection
951  *
952  * This function enables overload protection on the power rails. This is
953  * triggered if the power rails' voltage drops rapidly due to overload and
954  * in such case, the supply to the powerrail is cut-off, protecting the
955  * CPU from damage. Note that under such condition, the system will likely
956  * crash or misbehave.
957  */
mxs_enable_output_rail_protection(void)958 static void mxs_enable_output_rail_protection(void)
959 {
960 	struct mxs_power_regs *power_regs =
961 		(struct mxs_power_regs *)MXS_POWER_BASE;
962 
963 	debug("SPL: Enabling output rail protection\n");
964 
965 	writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
966 		POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
967 
968 	setbits_le32(&power_regs->hw_power_vdddctrl,
969 			POWER_VDDDCTRL_PWDN_BRNOUT);
970 
971 	setbits_le32(&power_regs->hw_power_vddactrl,
972 			POWER_VDDACTRL_PWDN_BRNOUT);
973 
974 	setbits_le32(&power_regs->hw_power_vddioctrl,
975 			POWER_VDDIOCTRL_PWDN_BRNOUT);
976 }
977 
978 /**
979  * mxs_get_vddio_power_source_off() - Get VDDIO rail power source
980  *
981  * This function tests if the VDDIO rail is supplied by linear regulator
982  * or by the DC-DC converter. Returns 1 if powered by linear regulator,
983  * returns 0 if powered by the DC-DC converter.
984  */
mxs_get_vddio_power_source_off(void)985 static int mxs_get_vddio_power_source_off(void)
986 {
987 	struct mxs_power_regs *power_regs =
988 		(struct mxs_power_regs *)MXS_POWER_BASE;
989 	uint32_t tmp;
990 
991 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
992 		tmp = readl(&power_regs->hw_power_vddioctrl);
993 		if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
994 			if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
995 				POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
996 				return 1;
997 			}
998 		}
999 
1000 		if (!(readl(&power_regs->hw_power_5vctrl) &
1001 			POWER_5VCTRL_ENABLE_DCDC)) {
1002 			if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
1003 				POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
1004 				return 1;
1005 			}
1006 		}
1007 	}
1008 
1009 	return 0;
1010 
1011 }
1012 
1013 /**
1014  * mxs_get_vddd_power_source_off() - Get VDDD rail power source
1015  *
1016  * This function tests if the VDDD rail is supplied by linear regulator
1017  * or by the DC-DC converter. Returns 1 if powered by linear regulator,
1018  * returns 0 if powered by the DC-DC converter.
1019  */
mxs_get_vddd_power_source_off(void)1020 static int mxs_get_vddd_power_source_off(void)
1021 {
1022 	struct mxs_power_regs *power_regs =
1023 		(struct mxs_power_regs *)MXS_POWER_BASE;
1024 	uint32_t tmp;
1025 
1026 	tmp = readl(&power_regs->hw_power_vdddctrl);
1027 	if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
1028 		if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
1029 			POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
1030 			return 1;
1031 		}
1032 	}
1033 
1034 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
1035 		if (!(readl(&power_regs->hw_power_5vctrl) &
1036 			POWER_5VCTRL_ENABLE_DCDC)) {
1037 			return 1;
1038 		}
1039 	}
1040 
1041 	if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
1042 		if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
1043 			POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
1044 			return 1;
1045 		}
1046 	}
1047 
1048 	return 0;
1049 }
1050 
1051 struct mxs_vddx_cfg {
1052 	uint32_t		*reg;
1053 	uint8_t			step_mV;
1054 	uint16_t		lowest_mV;
1055 	int			(*powered_by_linreg)(void);
1056 	uint32_t		trg_mask;
1057 	uint32_t		bo_irq;
1058 	uint32_t		bo_enirq;
1059 	uint32_t		bo_offset_mask;
1060 	uint32_t		bo_offset_offset;
1061 };
1062 
1063 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
1064 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1065 					hw_power_vddioctrl),
1066 #if defined(CONFIG_MX23)
1067 	.step_mV		= 25,
1068 #else
1069 	.step_mV		= 50,
1070 #endif
1071 	.lowest_mV		= 2800,
1072 	.powered_by_linreg	= mxs_get_vddio_power_source_off,
1073 	.trg_mask		= POWER_VDDIOCTRL_TRG_MASK,
1074 	.bo_irq			= POWER_CTRL_VDDIO_BO_IRQ,
1075 	.bo_enirq		= POWER_CTRL_ENIRQ_VDDIO_BO,
1076 	.bo_offset_mask		= POWER_VDDIOCTRL_BO_OFFSET_MASK,
1077 	.bo_offset_offset	= POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
1078 };
1079 
1080 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
1081 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1082 					hw_power_vdddctrl),
1083 	.step_mV		= 25,
1084 	.lowest_mV		= 800,
1085 	.powered_by_linreg	= mxs_get_vddd_power_source_off,
1086 	.trg_mask		= POWER_VDDDCTRL_TRG_MASK,
1087 	.bo_irq			= POWER_CTRL_VDDD_BO_IRQ,
1088 	.bo_enirq		= POWER_CTRL_ENIRQ_VDDD_BO,
1089 	.bo_offset_mask		= POWER_VDDDCTRL_BO_OFFSET_MASK,
1090 	.bo_offset_offset	= POWER_VDDDCTRL_BO_OFFSET_OFFSET,
1091 };
1092 
1093 #ifdef CONFIG_MX23
1094 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
1095 	.reg			= &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1096 					hw_power_vddmemctrl),
1097 	.step_mV		= 50,
1098 	.lowest_mV		= 1700,
1099 	.powered_by_linreg	= NULL,
1100 	.trg_mask		= POWER_VDDMEMCTRL_TRG_MASK,
1101 	.bo_irq			= 0,
1102 	.bo_enirq		= 0,
1103 	.bo_offset_mask		= 0,
1104 	.bo_offset_offset	= 0,
1105 };
1106 #endif
1107 
1108 /**
1109  * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail
1110  * @cfg:		Configuration data of the DC-DC converter rail
1111  * @new_target:		New target voltage of the DC-DC converter rail
1112  * @new_brownout:	New brownout trigger voltage
1113  *
1114  * This function configures the output voltage on the DC-DC converter rail.
1115  * The rail is selected by the @cfg argument. The new voltage target is
1116  * selected by the @new_target and the voltage is specified in mV. The
1117  * new brownout value is selected by the @new_brownout argument and the
1118  * value is also in mV.
1119  */
mxs_power_set_vddx(const struct mxs_vddx_cfg * cfg,uint32_t new_target,uint32_t new_brownout)1120 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
1121 				uint32_t new_target, uint32_t new_brownout)
1122 {
1123 	struct mxs_power_regs *power_regs =
1124 		(struct mxs_power_regs *)MXS_POWER_BASE;
1125 	uint32_t cur_target, diff, bo_int = 0;
1126 	uint32_t powered_by_linreg = 0;
1127 	int adjust_up, tmp;
1128 
1129 	new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
1130 					 cfg->step_mV);
1131 
1132 	cur_target = readl(cfg->reg);
1133 	cur_target &= cfg->trg_mask;
1134 	cur_target *= cfg->step_mV;
1135 	cur_target += cfg->lowest_mV;
1136 
1137 	adjust_up = new_target > cur_target;
1138 	if (cfg->powered_by_linreg)
1139 		powered_by_linreg = cfg->powered_by_linreg();
1140 
1141 	if (adjust_up && cfg->bo_irq) {
1142 		if (powered_by_linreg) {
1143 			bo_int = readl(cfg->reg);
1144 			clrbits_le32(cfg->reg, cfg->bo_enirq);
1145 		}
1146 		setbits_le32(cfg->reg, cfg->bo_offset_mask);
1147 	}
1148 
1149 	do {
1150 		if (abs(new_target - cur_target) > 100) {
1151 			if (adjust_up)
1152 				diff = cur_target + 100;
1153 			else
1154 				diff = cur_target - 100;
1155 		} else {
1156 			diff = new_target;
1157 		}
1158 
1159 		diff -= cfg->lowest_mV;
1160 		diff /= cfg->step_mV;
1161 
1162 		clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
1163 
1164 		if (powered_by_linreg ||
1165 			(readl(&power_regs->hw_power_sts) &
1166 				POWER_STS_VDD5V_GT_VDDIO))
1167 			early_delay(500);
1168 		else {
1169 			for (;;) {
1170 				tmp = readl(&power_regs->hw_power_sts);
1171 				if (tmp & POWER_STS_DC_OK)
1172 					break;
1173 			}
1174 		}
1175 
1176 		cur_target = readl(cfg->reg);
1177 		cur_target &= cfg->trg_mask;
1178 		cur_target *= cfg->step_mV;
1179 		cur_target += cfg->lowest_mV;
1180 	} while (new_target > cur_target);
1181 
1182 	if (cfg->bo_irq) {
1183 		if (adjust_up && powered_by_linreg) {
1184 			writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
1185 			if (bo_int & cfg->bo_enirq)
1186 				setbits_le32(cfg->reg, cfg->bo_enirq);
1187 		}
1188 
1189 		clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
1190 				new_brownout << cfg->bo_offset_offset);
1191 	}
1192 }
1193 
1194 /**
1195  * mxs_setup_batt_detect() - Start the battery voltage measurement logic
1196  *
1197  * This function starts and configures the LRADC block. This allows the
1198  * power initialization code to measure battery voltage and based on this
1199  * knowledge, decide whether to boot at all, boot from battery or boot
1200  * from 5V input.
1201  */
mxs_setup_batt_detect(void)1202 static void mxs_setup_batt_detect(void)
1203 {
1204 	debug("SPL: Starting battery voltage measurement logic\n");
1205 
1206 	mxs_lradc_init();
1207 	mxs_lradc_enable_batt_measurement();
1208 	early_delay(10);
1209 }
1210 
1211 /**
1212  * mxs_ungate_power() - Ungate the POWER block
1213  *
1214  * This function ungates clock to the power block. In case the power block
1215  * was still gated at this point, it will not be possible to configure the
1216  * block and therefore the power initialization would fail. This function
1217  * is only needed on i.MX233, on i.MX28 the power block is always ungated.
1218  */
mxs_ungate_power(void)1219 static void mxs_ungate_power(void)
1220 {
1221 #ifdef CONFIG_MX23
1222 	struct mxs_power_regs *power_regs =
1223 		(struct mxs_power_regs *)MXS_POWER_BASE;
1224 
1225 	writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
1226 #endif
1227 }
1228 
1229 /**
1230  * mxs_power_init() - The power block init main function
1231  *
1232  * This function calls all the power block initialization functions in
1233  * proper sequence to start the power block.
1234  */
mxs_power_init(void)1235 void mxs_power_init(void)
1236 {
1237 	struct mxs_power_regs *power_regs =
1238 		(struct mxs_power_regs *)MXS_POWER_BASE;
1239 
1240 	debug("SPL: Initialising Power Block\n");
1241 
1242 	mxs_ungate_power();
1243 
1244 	mxs_power_clock2xtal();
1245 	mxs_power_set_auto_restart();
1246 	mxs_power_set_linreg();
1247 	mxs_power_setup_5v_detect();
1248 
1249 	mxs_setup_batt_detect();
1250 
1251 	mxs_power_configure_power_source();
1252 	mxs_enable_output_rail_protection();
1253 
1254 	debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n");
1255 	mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
1256 
1257 	debug("SPL: Setting VDDD to 1V5 (brownout @ 1v315)\n");
1258 	mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1315);
1259 #ifdef CONFIG_MX23
1260 	debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n");
1261 	mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
1262 #endif
1263 	writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1264 		POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1265 		POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1266 		POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1267 
1268 	writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
1269 
1270 	early_delay(1000);
1271 }
1272 
1273 #ifdef	CONFIG_SPL_MXS_PSWITCH_WAIT
1274 /**
1275  * mxs_power_wait_pswitch() - Wait for power switch to be pressed
1276  *
1277  * This function waits until the power-switch was pressed to start booting
1278  * the board.
1279  */
mxs_power_wait_pswitch(void)1280 void mxs_power_wait_pswitch(void)
1281 {
1282 	struct mxs_power_regs *power_regs =
1283 		(struct mxs_power_regs *)MXS_POWER_BASE;
1284 
1285 	debug("SPL: Waiting for power switch input\n");
1286 	while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
1287 		;
1288 }
1289 #endif
1290