2 * Freescale i.MX28 Boot PMIC init
4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5 * on behalf of DENX Software Engineering GmbH
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/arch/imx-regs.h>
17 #ifdef CONFIG_SYS_MXS_VDD5V_ONLY
18 #define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
19 POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
21 #define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
22 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
25 * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
27 * This function switches the CPU core clock from PLL to 24MHz XTAL
28 * oscilator. This is necessary if the PLL is being reconfigured to
29 * prevent crash of the CPU core.
31 static void mxs_power_clock2xtal(void)
33 struct mxs_clkctrl_regs *clkctrl_regs =
34 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
36 debug("SPL: Switching CPU clock to 24MHz XTAL\n");
38 /* Set XTAL as CPU reference clock */
39 writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
40 &clkctrl_regs->hw_clkctrl_clkseq_set);
44 * mxs_power_clock2pll() - Switch CPU core clock source to PLL
46 * This function switches the CPU core clock from 24MHz XTAL oscilator
47 * to PLL. This can only be called once the PLL has re-locked and once
48 * the PLL is stable after reconfiguration.
50 static void mxs_power_clock2pll(void)
52 struct mxs_clkctrl_regs *clkctrl_regs =
53 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
55 debug("SPL: Switching CPU core clock source to PLL\n");
58 * TODO: Are we really? It looks like we turn on PLL0, but we then
59 * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already
60 * set by mxs_power_clock2xtal()). Clearing this bit here seems to
61 * introduce some instability (causing the CPU core to hang). Maybe
62 * we aren't giving PLL0 enough time to stabilise?
64 setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
65 CLKCTRL_PLL0CTRL0_POWER);
69 * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a
70 * wait on the PLL0 LOCK bit?
72 setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
73 CLKCTRL_CLKSEQ_BYPASS_CPU);
77 * mxs_power_set_auto_restart() - Set the auto-restart bit
79 * This function ungates the RTC block and sets the AUTO_RESTART
80 * bit to work around a design bug on MX28EVK Rev. A .
83 static void mxs_power_set_auto_restart(void)
85 struct mxs_rtc_regs *rtc_regs =
86 (struct mxs_rtc_regs *)MXS_RTC_BASE;
88 debug("SPL: Setting auto-restart bit\n");
90 writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
91 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
94 writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
95 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
98 /* Do nothing if flag already set */
99 if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
102 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
105 setbits_le32(&rtc_regs->hw_rtc_persistent0,
106 RTC_PERSISTENT0_AUTO_RESTART);
107 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
108 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
109 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
111 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
116 * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter
118 * This function configures the VDDIO, VDDA and VDDD linear regulators output
119 * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching
120 * converter. This is the recommended setting for the case where we use both
121 * linear regulators and DC-DC converter to power the VDDIO rail.
123 static void mxs_power_set_linreg(void)
125 struct mxs_power_regs *power_regs =
126 (struct mxs_power_regs *)MXS_POWER_BASE;
128 /* Set linear regulator 25mV below switching converter */
129 debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
130 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
131 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
132 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
134 debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
135 clrsetbits_le32(&power_regs->hw_power_vddactrl,
136 POWER_VDDACTRL_LINREG_OFFSET_MASK,
137 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
139 debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
140 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
141 POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
142 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
146 * mxs_get_batt_volt() - Measure battery input voltage
148 * This function retrieves the battery input voltage and returns it.
150 static int mxs_get_batt_volt(void)
152 struct mxs_power_regs *power_regs =
153 (struct mxs_power_regs *)MXS_POWER_BASE;
154 uint32_t volt = readl(&power_regs->hw_power_battmonitor);
155 volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
156 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
159 debug("SPL: Battery Voltage = %dmV\n", volt);
164 * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot
166 * This function checks if the battery input voltage is higher than 3.6V and
167 * therefore allows the system to successfully boot using this power source.
169 static int mxs_is_batt_ready(void)
171 return (mxs_get_batt_volt() >= 3600);
175 * mxs_is_batt_good() - Test if battery is operational at all
177 * This function starts recharging the battery and tests if the input current
178 * provided by the 5V input recharging the battery is also sufficient to power
179 * the DC-DC converter.
181 static int mxs_is_batt_good(void)
183 struct mxs_power_regs *power_regs =
184 (struct mxs_power_regs *)MXS_POWER_BASE;
185 uint32_t volt = mxs_get_batt_volt();
187 if ((volt >= 2400) && (volt <= 4300)) {
188 debug("SPL: Battery is good\n");
192 clrsetbits_le32(&power_regs->hw_power_5vctrl,
193 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
194 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
195 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
196 &power_regs->hw_power_5vctrl_clr);
198 clrsetbits_le32(&power_regs->hw_power_charge,
199 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
200 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
202 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
203 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
204 &power_regs->hw_power_5vctrl_clr);
208 volt = mxs_get_batt_volt();
211 debug("SPL: Battery Voltage too high\n");
216 debug("SPL: Battery is good\n");
220 writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
221 &power_regs->hw_power_charge_clr);
222 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
224 debug("SPL: Battery Voltage too low\n");
229 * mxs_power_setup_5v_detect() - Start the 5V input detection comparator
231 * This function enables the 5V detection comparator and sets the 5V valid
232 * threshold to 4.4V . We use 4.4V threshold here to make sure that even
233 * under high load, the voltage drop on the 5V input won't be so critical
234 * to cause undervolt on the 4P2 linear regulator supplying the DC-DC
235 * converter and thus making the system crash.
237 static void mxs_power_setup_5v_detect(void)
239 struct mxs_power_regs *power_regs =
240 (struct mxs_power_regs *)MXS_POWER_BASE;
242 /* Start 5V detection */
243 debug("SPL: Starting 5V input detection comparator\n");
244 clrsetbits_le32(&power_regs->hw_power_5vctrl,
245 POWER_5VCTRL_VBUSVALID_TRSH_MASK,
246 POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
247 POWER_5VCTRL_PWRUP_VBUS_CMPS);
251 * mxs_src_power_init() - Preconfigure the power block
253 * This function configures reasonable values for the DC-DC control loop
254 * and battery monitor.
256 static void mxs_src_power_init(void)
258 struct mxs_power_regs *power_regs =
259 (struct mxs_power_regs *)MXS_POWER_BASE;
261 debug("SPL: Pre-Configuring power block\n");
263 /* Improve efficieny and reduce transient ripple */
264 writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
265 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
267 clrsetbits_le32(&power_regs->hw_power_dclimits,
268 POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
269 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
271 setbits_le32(&power_regs->hw_power_battmonitor,
272 POWER_BATTMONITOR_EN_BATADJ);
274 /* Increase the RCSCALE level for quick DCDC response to dynamic load */
275 clrsetbits_le32(&power_regs->hw_power_loopctrl,
276 POWER_LOOPCTRL_EN_RCSCALE_MASK,
277 POWER_LOOPCTRL_RCSCALE_THRESH |
278 POWER_LOOPCTRL_EN_RCSCALE_8X);
280 clrsetbits_le32(&power_regs->hw_power_minpwr,
281 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
283 /* 5V to battery handoff ... FIXME */
284 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
286 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
290 * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator
292 * This function configures the necessary parameters for the 4P2 linear
293 * regulator to supply the DC-DC converter from 5V input.
295 static void mxs_power_init_4p2_params(void)
297 struct mxs_power_regs *power_regs =
298 (struct mxs_power_regs *)MXS_POWER_BASE;
300 debug("SPL: Configuring common 4P2 regulator params\n");
302 /* Setup 4P2 parameters */
303 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
304 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
305 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
307 clrsetbits_le32(&power_regs->hw_power_5vctrl,
308 POWER_5VCTRL_HEADROOM_ADJ_MASK,
309 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
311 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
312 POWER_DCDC4P2_DROPOUT_CTRL_MASK,
313 DCDC4P2_DROPOUT_CONFIG);
315 clrsetbits_le32(&power_regs->hw_power_5vctrl,
316 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
317 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
321 * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2
322 * @xfer: Select if the input shall be enabled or disabled
324 * This function enables or disables the 4P2 input into the DC-DC converter.
326 static void mxs_enable_4p2_dcdc_input(int xfer)
328 struct mxs_power_regs *power_regs =
329 (struct mxs_power_regs *)MXS_POWER_BASE;
330 uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
331 uint32_t prev_5v_brnout, prev_5v_droop;
333 debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
335 if (xfer && (readl(&power_regs->hw_power_5vctrl) &
336 POWER_5VCTRL_ENABLE_DCDC)) {
340 prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
341 POWER_5VCTRL_PWDN_5VBRNOUT;
342 prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
343 POWER_CTRL_ENIRQ_VDD5V_DROOP;
345 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
346 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
347 &power_regs->hw_power_reset);
349 clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
352 * Recording orignal values that will be modified temporarlily
353 * to handle a chip bug. See chip errata for CQ ENGR00115837
355 tmp = readl(&power_regs->hw_power_5vctrl);
356 vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
357 vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
359 pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
362 * Disable mechanisms that get erroneously tripped by when setting
363 * the DCDC4P2 EN_DCDC
365 clrbits_le32(&power_regs->hw_power_5vctrl,
366 POWER_5VCTRL_VBUSVALID_5VDETECT |
367 POWER_5VCTRL_VBUSVALID_TRSH_MASK);
369 writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
372 setbits_le32(&power_regs->hw_power_5vctrl,
373 POWER_5VCTRL_DCDC_XFER);
375 clrbits_le32(&power_regs->hw_power_5vctrl,
376 POWER_5VCTRL_DCDC_XFER);
378 setbits_le32(&power_regs->hw_power_5vctrl,
379 POWER_5VCTRL_ENABLE_DCDC);
381 setbits_le32(&power_regs->hw_power_dcdc4p2,
382 POWER_DCDC4P2_ENABLE_DCDC);
387 clrsetbits_le32(&power_regs->hw_power_5vctrl,
388 POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
391 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
394 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
396 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
397 writel(POWER_CTRL_VBUS_VALID_IRQ,
398 &power_regs->hw_power_ctrl_clr);
400 if (prev_5v_brnout) {
401 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
402 &power_regs->hw_power_5vctrl_set);
403 writel(POWER_RESET_UNLOCK_KEY,
404 &power_regs->hw_power_reset);
406 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
407 &power_regs->hw_power_5vctrl_clr);
408 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
409 &power_regs->hw_power_reset);
412 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
413 writel(POWER_CTRL_VDD5V_DROOP_IRQ,
414 &power_regs->hw_power_ctrl_clr);
417 clrbits_le32(&power_regs->hw_power_ctrl,
418 POWER_CTRL_ENIRQ_VDD5V_DROOP);
420 setbits_le32(&power_regs->hw_power_ctrl,
421 POWER_CTRL_ENIRQ_VDD5V_DROOP);
425 * mxs_power_init_4p2_regulator() - Start the 4P2 regulator
427 * This function enables the 4P2 regulator and switches the DC-DC converter
428 * to use the 4P2 input.
430 static void mxs_power_init_4p2_regulator(void)
432 struct mxs_power_regs *power_regs =
433 (struct mxs_power_regs *)MXS_POWER_BASE;
436 debug("SPL: Enabling 4P2 regulator\n");
438 setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
440 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
442 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
443 &power_regs->hw_power_5vctrl_clr);
444 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
446 /* Power up the 4p2 rail and logic/control */
447 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
448 &power_regs->hw_power_5vctrl_clr);
451 * Start charging up the 4p2 capacitor. We ramp of this charge
452 * gradually to avoid large inrush current from the 5V cable which can
453 * cause transients/problems
455 debug("SPL: Charging 4P2 capacitor\n");
456 mxs_enable_4p2_dcdc_input(0);
458 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
460 * If we arrived here, we were unable to recover from mx23 chip
461 * errata 5837. 4P2 is disabled and sufficient battery power is
462 * not present. Exiting to not enable DCDC power during 5V
465 clrbits_le32(&power_regs->hw_power_dcdc4p2,
466 POWER_DCDC4P2_ENABLE_DCDC);
467 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
468 &power_regs->hw_power_5vctrl_set);
470 debug("SPL: Unable to recover from mx23 errata 5837\n");
475 * Here we set the 4p2 brownout level to something very close to 4.2V.
476 * We then check the brownout status. If the brownout status is false,
477 * the voltage is already close to the target voltage of 4.2V so we
478 * can go ahead and set the 4P2 current limit to our max target limit.
479 * If the brownout status is true, we need to ramp us the current limit
480 * so that we don't cause large inrush current issues. We step up the
481 * current limit until the brownout status is false or until we've
482 * reached our maximum defined 4p2 current limit.
484 debug("SPL: Setting 4P2 brownout level\n");
485 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
486 POWER_DCDC4P2_BO_MASK,
487 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
489 if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
490 setbits_le32(&power_regs->hw_power_5vctrl,
491 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
493 tmp = (readl(&power_regs->hw_power_5vctrl) &
494 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
495 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
497 if (!(readl(&power_regs->hw_power_sts) &
498 POWER_STS_DCDC_4P2_BO)) {
499 tmp = readl(&power_regs->hw_power_5vctrl);
500 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
502 writel(tmp, &power_regs->hw_power_5vctrl);
506 tmp2 = readl(&power_regs->hw_power_5vctrl);
507 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
509 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
510 writel(tmp2, &power_regs->hw_power_5vctrl);
516 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
517 writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
521 * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source
523 * This function configures the DC-DC converter to be supplied from the 4P2
526 static void mxs_power_init_dcdc_4p2_source(void)
528 struct mxs_power_regs *power_regs =
529 (struct mxs_power_regs *)MXS_POWER_BASE;
531 debug("SPL: Switching DC-DC converters to 4P2\n");
533 if (!(readl(&power_regs->hw_power_dcdc4p2) &
534 POWER_DCDC4P2_ENABLE_DCDC)) {
535 debug("SPL: Already switched - aborting\n");
539 mxs_enable_4p2_dcdc_input(1);
541 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
542 clrbits_le32(&power_regs->hw_power_dcdc4p2,
543 POWER_DCDC4P2_ENABLE_DCDC);
544 writel(POWER_5VCTRL_ENABLE_DCDC,
545 &power_regs->hw_power_5vctrl_clr);
546 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
547 &power_regs->hw_power_5vctrl_set);
552 * mxs_power_enable_4p2() - Power up the 4P2 regulator
554 * This function drives the process of powering up the 4P2 linear regulator
555 * and switching the DC-DC converter input over to the 4P2 linear regulator.
557 static void mxs_power_enable_4p2(void)
559 struct mxs_power_regs *power_regs =
560 (struct mxs_power_regs *)MXS_POWER_BASE;
561 uint32_t vdddctrl, vddactrl, vddioctrl;
564 debug("SPL: Powering up 4P2 regulator\n");
566 vdddctrl = readl(&power_regs->hw_power_vdddctrl);
567 vddactrl = readl(&power_regs->hw_power_vddactrl);
568 vddioctrl = readl(&power_regs->hw_power_vddioctrl);
570 setbits_le32(&power_regs->hw_power_vdddctrl,
571 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
572 POWER_VDDDCTRL_PWDN_BRNOUT);
574 setbits_le32(&power_regs->hw_power_vddactrl,
575 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
576 POWER_VDDACTRL_PWDN_BRNOUT);
578 setbits_le32(&power_regs->hw_power_vddioctrl,
579 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
581 mxs_power_init_4p2_params();
582 mxs_power_init_4p2_regulator();
584 /* Shutdown battery (none present) */
585 if (!mxs_is_batt_ready()) {
586 clrbits_le32(&power_regs->hw_power_dcdc4p2,
587 POWER_DCDC4P2_BO_MASK);
588 writel(POWER_CTRL_DCDC4P2_BO_IRQ,
589 &power_regs->hw_power_ctrl_clr);
590 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
591 &power_regs->hw_power_ctrl_clr);
594 mxs_power_init_dcdc_4p2_source();
596 writel(vdddctrl, &power_regs->hw_power_vdddctrl);
598 writel(vddactrl, &power_regs->hw_power_vddactrl);
600 writel(vddioctrl, &power_regs->hw_power_vddioctrl);
603 * Check if FET is enabled on either powerout and if so,
607 tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
608 POWER_VDDDCTRL_DISABLE_FET);
609 tmp |= !(readl(&power_regs->hw_power_vddactrl) &
610 POWER_VDDACTRL_DISABLE_FET);
611 tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
612 POWER_VDDIOCTRL_DISABLE_FET);
614 writel(POWER_CHARGE_ENABLE_LOAD,
615 &power_regs->hw_power_charge_clr);
617 debug("SPL: 4P2 regulator powered-up\n");
621 * mxs_boot_valid_5v() - Boot from 5V supply
623 * This function configures the power block to boot from valid 5V input.
624 * This is called only if the 5V is reliable and can properly supply the
625 * CPU. This function proceeds to configure the 4P2 converter to be supplied
628 static void mxs_boot_valid_5v(void)
630 struct mxs_power_regs *power_regs =
631 (struct mxs_power_regs *)MXS_POWER_BASE;
633 debug("SPL: Booting from 5V supply\n");
636 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
637 * disconnect event. FIXME
639 writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
640 &power_regs->hw_power_5vctrl_set);
642 /* Configure polarity to check for 5V disconnection. */
643 writel(POWER_CTRL_POLARITY_VBUSVALID |
644 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
645 &power_regs->hw_power_ctrl_clr);
647 writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
648 &power_regs->hw_power_ctrl_clr);
650 mxs_power_enable_4p2();
654 * mxs_powerdown() - Shut down the system
656 * This function powers down the CPU completely.
658 static void mxs_powerdown(void)
660 struct mxs_power_regs *power_regs =
661 (struct mxs_power_regs *)MXS_POWER_BASE;
663 debug("Powering Down\n");
665 writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
666 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
667 &power_regs->hw_power_reset);
671 * mxs_batt_boot() - Configure the power block to boot from battery input
673 * This function configures the power block to boot from the battery voltage
676 static void mxs_batt_boot(void)
678 struct mxs_power_regs *power_regs =
679 (struct mxs_power_regs *)MXS_POWER_BASE;
681 debug("SPL: Configuring power block to boot from battery\n");
683 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
684 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
686 clrbits_le32(&power_regs->hw_power_dcdc4p2,
687 POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
688 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
690 /* 5V to battery handoff. */
691 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
693 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
695 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
697 clrsetbits_le32(&power_regs->hw_power_minpwr,
698 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
700 mxs_power_set_linreg();
702 clrbits_le32(&power_regs->hw_power_vdddctrl,
703 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
705 clrbits_le32(&power_regs->hw_power_vddactrl,
706 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
708 clrbits_le32(&power_regs->hw_power_vddioctrl,
709 POWER_VDDIOCTRL_DISABLE_FET);
711 setbits_le32(&power_regs->hw_power_5vctrl,
712 POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
714 setbits_le32(&power_regs->hw_power_5vctrl,
715 POWER_5VCTRL_ENABLE_DCDC);
717 clrsetbits_le32(&power_regs->hw_power_5vctrl,
718 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
719 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
721 mxs_power_enable_4p2();
725 * mxs_handle_5v_conflict() - Test if the 5V input is reliable
727 * This function tests if the 5V input can reliably supply the system. If it
728 * can, then proceed to configuring the system to boot from 5V source, otherwise
729 * try booting from battery supply. If we can not boot from battery supply
730 * either, shut down the system.
732 static void mxs_handle_5v_conflict(void)
734 struct mxs_power_regs *power_regs =
735 (struct mxs_power_regs *)MXS_POWER_BASE;
738 debug("SPL: Resolving 5V conflict\n");
740 setbits_le32(&power_regs->hw_power_vddioctrl,
741 POWER_VDDIOCTRL_BO_OFFSET_MASK);
744 tmp = readl(&power_regs->hw_power_sts);
746 if (tmp & POWER_STS_VDDIO_BO) {
748 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
751 debug("SPL: VDDIO has a brownout\n");
756 if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
757 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
761 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
767 * TODO: I can't see this being reached. We'll either
768 * powerdown or boot from a stable 5V supply.
770 if (tmp & POWER_STS_PSWITCH_MASK) {
771 debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
779 * mxs_5v_boot() - Configure the power block to boot from 5V input
781 * This function handles configuration of the power block when supplied by
784 static void mxs_5v_boot(void)
786 struct mxs_power_regs *power_regs =
787 (struct mxs_power_regs *)MXS_POWER_BASE;
789 debug("SPL: Configuring power block to boot from 5V input\n");
792 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
793 * but their implementation always returns 1 so we omit it here.
795 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
796 debug("SPL: 5V VDD good\n");
802 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
803 debug("SPL: 5V VDD good (after delay)\n");
808 debug("SPL: 5V VDD not good\n");
809 mxs_handle_5v_conflict();
813 * mxs_init_batt_bo() - Configure battery brownout threshold
815 * This function configures the battery input brownout threshold. The value
816 * at which the battery brownout happens is configured to 3.0V in the code.
818 static void mxs_init_batt_bo(void)
820 struct mxs_power_regs *power_regs =
821 (struct mxs_power_regs *)MXS_POWER_BASE;
823 debug("SPL: Initialising battery brown-out level to 3.0V\n");
826 clrsetbits_le32(&power_regs->hw_power_battmonitor,
827 POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
828 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
830 writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
831 writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
835 * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter
837 * This function turns off the VDDD linear regulator and therefore makes
838 * the VDDD rail be supplied only by the DC-DC converter.
840 static void mxs_switch_vddd_to_dcdc_source(void)
842 struct mxs_power_regs *power_regs =
843 (struct mxs_power_regs *)MXS_POWER_BASE;
845 debug("SPL: Switching VDDD to DC-DC converters\n");
847 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
848 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
849 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
851 clrbits_le32(&power_regs->hw_power_vdddctrl,
852 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
853 POWER_VDDDCTRL_DISABLE_STEPPING);
857 * mxs_power_configure_power_source() - Configure power block source
859 * This function is the core of the power configuration logic. The function
860 * selects the power block input source and configures the whole power block
861 * accordingly. After the configuration is complete and the system is stable
862 * again, the function switches the CPU clock source back to PLL. Finally,
863 * the function switches the voltage rails to DC-DC converter.
865 static void mxs_power_configure_power_source(void)
867 int batt_ready, batt_good;
868 struct mxs_power_regs *power_regs =
869 (struct mxs_power_regs *)MXS_POWER_BASE;
870 struct mxs_lradc_regs *lradc_regs =
871 (struct mxs_lradc_regs *)MXS_LRADC_BASE;
873 debug("SPL: Configuring power source\n");
875 mxs_src_power_init();
877 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
878 batt_ready = mxs_is_batt_ready();
880 /* 5V source detected, good battery detected. */
883 batt_good = mxs_is_batt_good();
885 /* 5V source detected, bad battery detected. */
886 writel(LRADC_CONVERSION_AUTOMATIC,
887 &lradc_regs->hw_lradc_conversion_clr);
888 clrbits_le32(&power_regs->hw_power_battmonitor,
889 POWER_BATTMONITOR_BATT_VAL_MASK);
894 /* 5V not detected, booting from battery. */
899 * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced
902 mxs_power_clock2pll();
906 mxs_switch_vddd_to_dcdc_source();
909 /* Fire up the VDDMEM LinReg now that we're all set. */
910 debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
911 writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
912 &power_regs->hw_power_vddmemctrl);
917 * mxs_enable_output_rail_protection() - Enable power rail protection
919 * This function enables overload protection on the power rails. This is
920 * triggered if the power rails' voltage drops rapidly due to overload and
921 * in such case, the supply to the powerrail is cut-off, protecting the
922 * CPU from damage. Note that under such condition, the system will likely
923 * crash or misbehave.
925 static void mxs_enable_output_rail_protection(void)
927 struct mxs_power_regs *power_regs =
928 (struct mxs_power_regs *)MXS_POWER_BASE;
930 debug("SPL: Enabling output rail protection\n");
932 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
933 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
935 setbits_le32(&power_regs->hw_power_vdddctrl,
936 POWER_VDDDCTRL_PWDN_BRNOUT);
938 setbits_le32(&power_regs->hw_power_vddactrl,
939 POWER_VDDACTRL_PWDN_BRNOUT);
941 setbits_le32(&power_regs->hw_power_vddioctrl,
942 POWER_VDDIOCTRL_PWDN_BRNOUT);
946 * mxs_get_vddio_power_source_off() - Get VDDIO rail power source
948 * This function tests if the VDDIO rail is supplied by linear regulator
949 * or by the DC-DC converter. Returns 1 if powered by linear regulator,
950 * returns 0 if powered by the DC-DC converter.
952 static int mxs_get_vddio_power_source_off(void)
954 struct mxs_power_regs *power_regs =
955 (struct mxs_power_regs *)MXS_POWER_BASE;
958 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
959 tmp = readl(&power_regs->hw_power_vddioctrl);
960 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
961 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
962 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
967 if (!(readl(&power_regs->hw_power_5vctrl) &
968 POWER_5VCTRL_ENABLE_DCDC)) {
969 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
970 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
981 * mxs_get_vddd_power_source_off() - Get VDDD rail power source
983 * This function tests if the VDDD rail is supplied by linear regulator
984 * or by the DC-DC converter. Returns 1 if powered by linear regulator,
985 * returns 0 if powered by the DC-DC converter.
987 static int mxs_get_vddd_power_source_off(void)
989 struct mxs_power_regs *power_regs =
990 (struct mxs_power_regs *)MXS_POWER_BASE;
993 tmp = readl(&power_regs->hw_power_vdddctrl);
994 if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
995 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
996 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
1001 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
1002 if (!(readl(&power_regs->hw_power_5vctrl) &
1003 POWER_5VCTRL_ENABLE_DCDC)) {
1008 if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
1009 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
1010 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
1018 struct mxs_vddx_cfg {
1022 int (*powered_by_linreg)(void);
1026 uint32_t bo_offset_mask;
1027 uint32_t bo_offset_offset;
1030 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
1031 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1032 hw_power_vddioctrl),
1033 #if defined(CONFIG_MX23)
1039 .powered_by_linreg = mxs_get_vddio_power_source_off,
1040 .trg_mask = POWER_VDDIOCTRL_TRG_MASK,
1041 .bo_irq = POWER_CTRL_VDDIO_BO_IRQ,
1042 .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO,
1043 .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK,
1044 .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
1047 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
1048 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1052 .powered_by_linreg = mxs_get_vddd_power_source_off,
1053 .trg_mask = POWER_VDDDCTRL_TRG_MASK,
1054 .bo_irq = POWER_CTRL_VDDD_BO_IRQ,
1055 .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO,
1056 .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK,
1057 .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
1061 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
1062 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1063 hw_power_vddmemctrl),
1066 .powered_by_linreg = NULL,
1067 .trg_mask = POWER_VDDMEMCTRL_TRG_MASK,
1070 .bo_offset_mask = 0,
1071 .bo_offset_offset = 0,
1076 * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail
1077 * @cfg: Configuration data of the DC-DC converter rail
1078 * @new_target: New target voltage of the DC-DC converter rail
1079 * @new_brownout: New brownout trigger voltage
1081 * This function configures the output voltage on the DC-DC converter rail.
1082 * The rail is selected by the @cfg argument. The new voltage target is
1083 * selected by the @new_target and the voltage is specified in mV. The
1084 * new brownout value is selected by the @new_brownout argument and the
1085 * value is also in mV.
1087 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
1088 uint32_t new_target, uint32_t new_brownout)
1090 struct mxs_power_regs *power_regs =
1091 (struct mxs_power_regs *)MXS_POWER_BASE;
1092 uint32_t cur_target, diff, bo_int = 0;
1093 uint32_t powered_by_linreg = 0;
1096 new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
1099 cur_target = readl(cfg->reg);
1100 cur_target &= cfg->trg_mask;
1101 cur_target *= cfg->step_mV;
1102 cur_target += cfg->lowest_mV;
1104 adjust_up = new_target > cur_target;
1105 if (cfg->powered_by_linreg)
1106 powered_by_linreg = cfg->powered_by_linreg();
1108 if (adjust_up && cfg->bo_irq) {
1109 if (powered_by_linreg) {
1110 bo_int = readl(cfg->reg);
1111 clrbits_le32(cfg->reg, cfg->bo_enirq);
1113 setbits_le32(cfg->reg, cfg->bo_offset_mask);
1117 if (abs(new_target - cur_target) > 100) {
1119 diff = cur_target + 100;
1121 diff = cur_target - 100;
1126 diff -= cfg->lowest_mV;
1127 diff /= cfg->step_mV;
1129 clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
1131 if (powered_by_linreg ||
1132 (readl(&power_regs->hw_power_sts) &
1133 POWER_STS_VDD5V_GT_VDDIO))
1137 tmp = readl(&power_regs->hw_power_sts);
1138 if (tmp & POWER_STS_DC_OK)
1143 cur_target = readl(cfg->reg);
1144 cur_target &= cfg->trg_mask;
1145 cur_target *= cfg->step_mV;
1146 cur_target += cfg->lowest_mV;
1147 } while (new_target > cur_target);
1150 if (adjust_up && powered_by_linreg) {
1151 writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
1152 if (bo_int & cfg->bo_enirq)
1153 setbits_le32(cfg->reg, cfg->bo_enirq);
1156 clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
1157 new_brownout << cfg->bo_offset_offset);
1162 * mxs_setup_batt_detect() - Start the battery voltage measurement logic
1164 * This function starts and configures the LRADC block. This allows the
1165 * power initialization code to measure battery voltage and based on this
1166 * knowledge, decide whether to boot at all, boot from battery or boot
1169 static void mxs_setup_batt_detect(void)
1171 debug("SPL: Starting battery voltage measurement logic\n");
1174 mxs_lradc_enable_batt_measurement();
1179 * mxs_ungate_power() - Ungate the POWER block
1181 * This function ungates clock to the power block. In case the power block
1182 * was still gated at this point, it will not be possible to configure the
1183 * block and therefore the power initialization would fail. This function
1184 * is only needed on i.MX233, on i.MX28 the power block is always ungated.
1186 static void mxs_ungate_power(void)
1189 struct mxs_power_regs *power_regs =
1190 (struct mxs_power_regs *)MXS_POWER_BASE;
1192 writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
1197 * mxs_power_init() - The power block init main function
1199 * This function calls all the power block initialization functions in
1200 * proper sequence to start the power block.
1202 void mxs_power_init(void)
1204 struct mxs_power_regs *power_regs =
1205 (struct mxs_power_regs *)MXS_POWER_BASE;
1207 debug("SPL: Initialising Power Block\n");
1211 mxs_power_clock2xtal();
1212 mxs_power_set_auto_restart();
1213 mxs_power_set_linreg();
1214 mxs_power_setup_5v_detect();
1216 mxs_setup_batt_detect();
1218 mxs_power_configure_power_source();
1219 mxs_enable_output_rail_protection();
1221 debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n");
1222 mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
1224 debug("SPL: Setting VDDD to 1V5 (brownout @ 1v315)\n");
1225 mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1315);
1227 debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n");
1228 mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
1230 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1231 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1232 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1233 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1235 writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
1240 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
1242 * mxs_power_wait_pswitch() - Wait for power switch to be pressed
1244 * This function waits until the power-switch was pressed to start booting
1247 void mxs_power_wait_pswitch(void)
1249 struct mxs_power_regs *power_regs =
1250 (struct mxs_power_regs *)MXS_POWER_BASE;
1252 debug("SPL: Waiting for power switch input\n");
1253 while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))