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 * See file CREDITS for list of people who contributed to this
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <asm/arch/imx-regs.h>
33 static void mxs_power_clock2xtal(void)
35 struct mxs_clkctrl_regs
*clkctrl_regs
=
36 (struct mxs_clkctrl_regs
*)MXS_CLKCTRL_BASE
;
38 /* Set XTAL as CPU reference clock */
39 writel(CLKCTRL_CLKSEQ_BYPASS_CPU
,
40 &clkctrl_regs
->hw_clkctrl_clkseq_set
);
43 static void mxs_power_clock2pll(void)
45 struct mxs_clkctrl_regs
*clkctrl_regs
=
46 (struct mxs_clkctrl_regs
*)MXS_CLKCTRL_BASE
;
48 setbits_le32(&clkctrl_regs
->hw_clkctrl_pll0ctrl0
,
49 CLKCTRL_PLL0CTRL0_POWER
);
51 setbits_le32(&clkctrl_regs
->hw_clkctrl_clkseq
,
52 CLKCTRL_CLKSEQ_BYPASS_CPU
);
55 static void mxs_power_clear_auto_restart(void)
57 struct mxs_rtc_regs
*rtc_regs
=
58 (struct mxs_rtc_regs
*)MXS_RTC_BASE
;
60 writel(RTC_CTRL_SFTRST
, &rtc_regs
->hw_rtc_ctrl_clr
);
61 while (readl(&rtc_regs
->hw_rtc_ctrl
) & RTC_CTRL_SFTRST
)
64 writel(RTC_CTRL_CLKGATE
, &rtc_regs
->hw_rtc_ctrl_clr
);
65 while (readl(&rtc_regs
->hw_rtc_ctrl
) & RTC_CTRL_CLKGATE
)
69 * Due to the hardware design bug of mx28 EVK-A
70 * we need to set the AUTO_RESTART bit.
72 if (readl(&rtc_regs
->hw_rtc_persistent0
) & RTC_PERSISTENT0_AUTO_RESTART
)
75 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_NEW_REGS_MASK
)
78 setbits_le32(&rtc_regs
->hw_rtc_persistent0
,
79 RTC_PERSISTENT0_AUTO_RESTART
);
80 writel(RTC_CTRL_FORCE_UPDATE
, &rtc_regs
->hw_rtc_ctrl_set
);
81 writel(RTC_CTRL_FORCE_UPDATE
, &rtc_regs
->hw_rtc_ctrl_clr
);
82 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_NEW_REGS_MASK
)
84 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_STALE_REGS_MASK
)
88 static void mxs_power_set_linreg(void)
90 struct mxs_power_regs
*power_regs
=
91 (struct mxs_power_regs
*)MXS_POWER_BASE
;
93 /* Set linear regulator 25mV below switching converter */
94 clrsetbits_le32(&power_regs
->hw_power_vdddctrl
,
95 POWER_VDDDCTRL_LINREG_OFFSET_MASK
,
96 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
);
98 clrsetbits_le32(&power_regs
->hw_power_vddactrl
,
99 POWER_VDDACTRL_LINREG_OFFSET_MASK
,
100 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW
);
102 clrsetbits_le32(&power_regs
->hw_power_vddioctrl
,
103 POWER_VDDIOCTRL_LINREG_OFFSET_MASK
,
104 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW
);
107 static int mxs_get_batt_volt(void)
109 struct mxs_power_regs
*power_regs
=
110 (struct mxs_power_regs
*)MXS_POWER_BASE
;
111 uint32_t volt
= readl(&power_regs
->hw_power_battmonitor
);
112 volt
&= POWER_BATTMONITOR_BATT_VAL_MASK
;
113 volt
>>= POWER_BATTMONITOR_BATT_VAL_OFFSET
;
118 static int mxs_is_batt_ready(void)
120 return (mxs_get_batt_volt() >= 3600);
123 static int mxs_is_batt_good(void)
125 struct mxs_power_regs
*power_regs
=
126 (struct mxs_power_regs
*)MXS_POWER_BASE
;
127 uint32_t volt
= mxs_get_batt_volt();
129 if ((volt
>= 2400) && (volt
<= 4300))
132 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
133 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
134 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
135 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
136 &power_regs
->hw_power_5vctrl_clr
);
138 clrsetbits_le32(&power_regs
->hw_power_charge
,
139 POWER_CHARGE_STOP_ILIMIT_MASK
| POWER_CHARGE_BATTCHRG_I_MASK
,
140 POWER_CHARGE_STOP_ILIMIT_10MA
| 0x3);
142 writel(POWER_CHARGE_PWD_BATTCHRG
, &power_regs
->hw_power_charge_clr
);
143 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
144 &power_regs
->hw_power_5vctrl_clr
);
148 volt
= mxs_get_batt_volt();
156 writel(POWER_CHARGE_STOP_ILIMIT_MASK
| POWER_CHARGE_BATTCHRG_I_MASK
,
157 &power_regs
->hw_power_charge_clr
);
158 writel(POWER_CHARGE_PWD_BATTCHRG
, &power_regs
->hw_power_charge_set
);
163 static void mxs_power_setup_5v_detect(void)
165 struct mxs_power_regs
*power_regs
=
166 (struct mxs_power_regs
*)MXS_POWER_BASE
;
168 /* Start 5V detection */
169 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
170 POWER_5VCTRL_VBUSVALID_TRSH_MASK
,
171 POWER_5VCTRL_VBUSVALID_TRSH_4V4
|
172 POWER_5VCTRL_PWRUP_VBUS_CMPS
);
175 static void mxs_src_power_init(void)
177 struct mxs_power_regs
*power_regs
=
178 (struct mxs_power_regs
*)MXS_POWER_BASE
;
180 /* Improve efficieny and reduce transient ripple */
181 writel(POWER_LOOPCTRL_TOGGLE_DIF
| POWER_LOOPCTRL_EN_CM_HYST
|
182 POWER_LOOPCTRL_EN_DF_HYST
, &power_regs
->hw_power_loopctrl_set
);
184 clrsetbits_le32(&power_regs
->hw_power_dclimits
,
185 POWER_DCLIMITS_POSLIMIT_BUCK_MASK
,
186 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET
);
188 setbits_le32(&power_regs
->hw_power_battmonitor
,
189 POWER_BATTMONITOR_EN_BATADJ
);
191 /* Increase the RCSCALE level for quick DCDC response to dynamic load */
192 clrsetbits_le32(&power_regs
->hw_power_loopctrl
,
193 POWER_LOOPCTRL_EN_RCSCALE_MASK
,
194 POWER_LOOPCTRL_RCSCALE_THRESH
|
195 POWER_LOOPCTRL_EN_RCSCALE_8X
);
197 clrsetbits_le32(&power_regs
->hw_power_minpwr
,
198 POWER_MINPWR_HALFFETS
, POWER_MINPWR_DOUBLE_FETS
);
200 /* 5V to battery handoff ... FIXME */
201 setbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
203 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
206 static void mxs_power_init_4p2_params(void)
208 struct mxs_power_regs
*power_regs
=
209 (struct mxs_power_regs
*)MXS_POWER_BASE
;
211 /* Setup 4P2 parameters */
212 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
213 POWER_DCDC4P2_CMPTRIP_MASK
| POWER_DCDC4P2_TRG_MASK
,
214 POWER_DCDC4P2_TRG_4V2
| (31 << POWER_DCDC4P2_CMPTRIP_OFFSET
));
216 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
217 POWER_5VCTRL_HEADROOM_ADJ_MASK
,
218 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET
);
220 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
221 POWER_DCDC4P2_DROPOUT_CTRL_MASK
,
222 POWER_DCDC4P2_DROPOUT_CTRL_100MV
|
223 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
);
225 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
226 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
227 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
230 static void mxs_enable_4p2_dcdc_input(int xfer
)
232 struct mxs_power_regs
*power_regs
=
233 (struct mxs_power_regs
*)MXS_POWER_BASE
;
234 uint32_t tmp
, vbus_thresh
, vbus_5vdetect
, pwd_bo
;
235 uint32_t prev_5v_brnout
, prev_5v_droop
;
237 prev_5v_brnout
= readl(&power_regs
->hw_power_5vctrl
) &
238 POWER_5VCTRL_PWDN_5VBRNOUT
;
239 prev_5v_droop
= readl(&power_regs
->hw_power_ctrl
) &
240 POWER_CTRL_ENIRQ_VDD5V_DROOP
;
242 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_PWDN_5VBRNOUT
);
243 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
244 &power_regs
->hw_power_reset
);
246 clrbits_le32(&power_regs
->hw_power_ctrl
, POWER_CTRL_ENIRQ_VDD5V_DROOP
);
248 if (xfer
&& (readl(&power_regs
->hw_power_5vctrl
) &
249 POWER_5VCTRL_ENABLE_DCDC
)) {
254 * Recording orignal values that will be modified temporarlily
255 * to handle a chip bug. See chip errata for CQ ENGR00115837
257 tmp
= readl(&power_regs
->hw_power_5vctrl
);
258 vbus_thresh
= tmp
& POWER_5VCTRL_VBUSVALID_TRSH_MASK
;
259 vbus_5vdetect
= tmp
& POWER_5VCTRL_VBUSVALID_5VDETECT
;
261 pwd_bo
= readl(&power_regs
->hw_power_minpwr
) & POWER_MINPWR_PWD_BO
;
264 * Disable mechanisms that get erroneously tripped by when setting
265 * the DCDC4P2 EN_DCDC
267 clrbits_le32(&power_regs
->hw_power_5vctrl
,
268 POWER_5VCTRL_VBUSVALID_5VDETECT
|
269 POWER_5VCTRL_VBUSVALID_TRSH_MASK
);
271 writel(POWER_MINPWR_PWD_BO
, &power_regs
->hw_power_minpwr_set
);
274 setbits_le32(&power_regs
->hw_power_5vctrl
,
275 POWER_5VCTRL_DCDC_XFER
);
277 clrbits_le32(&power_regs
->hw_power_5vctrl
,
278 POWER_5VCTRL_DCDC_XFER
);
280 setbits_le32(&power_regs
->hw_power_5vctrl
,
281 POWER_5VCTRL_ENABLE_DCDC
);
283 setbits_le32(&power_regs
->hw_power_dcdc4p2
,
284 POWER_DCDC4P2_ENABLE_DCDC
);
289 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
290 POWER_5VCTRL_VBUSVALID_TRSH_MASK
, vbus_thresh
);
293 writel(vbus_5vdetect
, &power_regs
->hw_power_5vctrl_set
);
296 clrbits_le32(&power_regs
->hw_power_minpwr
, POWER_MINPWR_PWD_BO
);
298 while (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
)
299 writel(POWER_CTRL_VBUS_VALID_IRQ
,
300 &power_regs
->hw_power_ctrl_clr
);
302 if (prev_5v_brnout
) {
303 writel(POWER_5VCTRL_PWDN_5VBRNOUT
,
304 &power_regs
->hw_power_5vctrl_set
);
305 writel(POWER_RESET_UNLOCK_KEY
,
306 &power_regs
->hw_power_reset
);
308 writel(POWER_5VCTRL_PWDN_5VBRNOUT
,
309 &power_regs
->hw_power_5vctrl_clr
);
310 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
311 &power_regs
->hw_power_reset
);
314 while (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VDD5V_DROOP_IRQ
)
315 writel(POWER_CTRL_VDD5V_DROOP_IRQ
,
316 &power_regs
->hw_power_ctrl_clr
);
319 clrbits_le32(&power_regs
->hw_power_ctrl
,
320 POWER_CTRL_ENIRQ_VDD5V_DROOP
);
322 setbits_le32(&power_regs
->hw_power_ctrl
,
323 POWER_CTRL_ENIRQ_VDD5V_DROOP
);
326 static void mxs_power_init_4p2_regulator(void)
328 struct mxs_power_regs
*power_regs
=
329 (struct mxs_power_regs
*)MXS_POWER_BASE
;
332 setbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_ENABLE_4P2
);
334 writel(POWER_CHARGE_ENABLE_LOAD
, &power_regs
->hw_power_charge_set
);
336 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
337 &power_regs
->hw_power_5vctrl_clr
);
338 clrbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_TRG_MASK
);
340 /* Power up the 4p2 rail and logic/control */
341 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
342 &power_regs
->hw_power_5vctrl_clr
);
345 * Start charging up the 4p2 capacitor. We ramp of this charge
346 * gradually to avoid large inrush current from the 5V cable which can
347 * cause transients/problems
349 mxs_enable_4p2_dcdc_input(0);
351 if (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
) {
353 * If we arrived here, we were unable to recover from mx23 chip
354 * errata 5837. 4P2 is disabled and sufficient battery power is
355 * not present. Exiting to not enable DCDC power during 5V
358 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
359 POWER_DCDC4P2_ENABLE_DCDC
);
360 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
361 &power_regs
->hw_power_5vctrl_set
);
366 * Here we set the 4p2 brownout level to something very close to 4.2V.
367 * We then check the brownout status. If the brownout status is false,
368 * the voltage is already close to the target voltage of 4.2V so we
369 * can go ahead and set the 4P2 current limit to our max target limit.
370 * If the brownout status is true, we need to ramp us the current limit
371 * so that we don't cause large inrush current issues. We step up the
372 * current limit until the brownout status is false or until we've
373 * reached our maximum defined 4p2 current limit.
375 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
376 POWER_DCDC4P2_BO_MASK
,
377 22 << POWER_DCDC4P2_BO_OFFSET
); /* 4.15V */
379 if (!(readl(&power_regs
->hw_power_sts
) & POWER_STS_DCDC_4P2_BO
)) {
380 setbits_le32(&power_regs
->hw_power_5vctrl
,
381 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
383 tmp
= (readl(&power_regs
->hw_power_5vctrl
) &
384 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
) >>
385 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
;
387 if (!(readl(&power_regs
->hw_power_sts
) &
388 POWER_STS_DCDC_4P2_BO
)) {
389 tmp
= readl(&power_regs
->hw_power_5vctrl
);
390 tmp
|= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
;
392 writel(tmp
, &power_regs
->hw_power_5vctrl
);
396 tmp2
= readl(&power_regs
->hw_power_5vctrl
);
397 tmp2
&= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
;
399 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
;
400 writel(tmp2
, &power_regs
->hw_power_5vctrl
);
406 clrbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_BO_MASK
);
407 writel(POWER_CTRL_DCDC4P2_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
410 static void mxs_power_init_dcdc_4p2_source(void)
412 struct mxs_power_regs
*power_regs
=
413 (struct mxs_power_regs
*)MXS_POWER_BASE
;
415 if (!(readl(&power_regs
->hw_power_dcdc4p2
) &
416 POWER_DCDC4P2_ENABLE_DCDC
)) {
420 mxs_enable_4p2_dcdc_input(1);
422 if (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
) {
423 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
424 POWER_DCDC4P2_ENABLE_DCDC
);
425 writel(POWER_5VCTRL_ENABLE_DCDC
,
426 &power_regs
->hw_power_5vctrl_clr
);
427 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
428 &power_regs
->hw_power_5vctrl_set
);
432 static void mxs_power_enable_4p2(void)
434 struct mxs_power_regs
*power_regs
=
435 (struct mxs_power_regs
*)MXS_POWER_BASE
;
436 uint32_t vdddctrl
, vddactrl
, vddioctrl
;
439 vdddctrl
= readl(&power_regs
->hw_power_vdddctrl
);
440 vddactrl
= readl(&power_regs
->hw_power_vddactrl
);
441 vddioctrl
= readl(&power_regs
->hw_power_vddioctrl
);
443 setbits_le32(&power_regs
->hw_power_vdddctrl
,
444 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
|
445 POWER_VDDDCTRL_PWDN_BRNOUT
);
447 setbits_le32(&power_regs
->hw_power_vddactrl
,
448 POWER_VDDACTRL_DISABLE_FET
| POWER_VDDACTRL_ENABLE_LINREG
|
449 POWER_VDDACTRL_PWDN_BRNOUT
);
451 setbits_le32(&power_regs
->hw_power_vddioctrl
,
452 POWER_VDDIOCTRL_DISABLE_FET
| POWER_VDDIOCTRL_PWDN_BRNOUT
);
454 mxs_power_init_4p2_params();
455 mxs_power_init_4p2_regulator();
457 /* Shutdown battery (none present) */
458 if (!mxs_is_batt_ready()) {
459 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
460 POWER_DCDC4P2_BO_MASK
);
461 writel(POWER_CTRL_DCDC4P2_BO_IRQ
,
462 &power_regs
->hw_power_ctrl_clr
);
463 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO
,
464 &power_regs
->hw_power_ctrl_clr
);
467 mxs_power_init_dcdc_4p2_source();
469 writel(vdddctrl
, &power_regs
->hw_power_vdddctrl
);
471 writel(vddactrl
, &power_regs
->hw_power_vddactrl
);
473 writel(vddioctrl
, &power_regs
->hw_power_vddioctrl
);
476 * Check if FET is enabled on either powerout and if so,
480 tmp
|= !(readl(&power_regs
->hw_power_vdddctrl
) &
481 POWER_VDDDCTRL_DISABLE_FET
);
482 tmp
|= !(readl(&power_regs
->hw_power_vddactrl
) &
483 POWER_VDDACTRL_DISABLE_FET
);
484 tmp
|= !(readl(&power_regs
->hw_power_vddioctrl
) &
485 POWER_VDDIOCTRL_DISABLE_FET
);
487 writel(POWER_CHARGE_ENABLE_LOAD
,
488 &power_regs
->hw_power_charge_clr
);
491 static void mxs_boot_valid_5v(void)
493 struct mxs_power_regs
*power_regs
=
494 (struct mxs_power_regs
*)MXS_POWER_BASE
;
497 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
498 * disconnect event. FIXME
500 writel(POWER_5VCTRL_VBUSVALID_5VDETECT
,
501 &power_regs
->hw_power_5vctrl_set
);
503 /* Configure polarity to check for 5V disconnection. */
504 writel(POWER_CTRL_POLARITY_VBUSVALID
|
505 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO
,
506 &power_regs
->hw_power_ctrl_clr
);
508 writel(POWER_CTRL_VBUS_VALID_IRQ
| POWER_CTRL_VDD5V_GT_VDDIO_IRQ
,
509 &power_regs
->hw_power_ctrl_clr
);
511 mxs_power_enable_4p2();
514 static void mxs_powerdown(void)
516 struct mxs_power_regs
*power_regs
=
517 (struct mxs_power_regs
*)MXS_POWER_BASE
;
518 writel(POWER_RESET_UNLOCK_KEY
, &power_regs
->hw_power_reset
);
519 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
520 &power_regs
->hw_power_reset
);
523 static void mxs_batt_boot(void)
525 struct mxs_power_regs
*power_regs
=
526 (struct mxs_power_regs
*)MXS_POWER_BASE
;
528 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_PWDN_5VBRNOUT
);
529 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_ENABLE_DCDC
);
531 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
532 POWER_DCDC4P2_ENABLE_DCDC
| POWER_DCDC4P2_ENABLE_4P2
);
533 writel(POWER_CHARGE_ENABLE_LOAD
, &power_regs
->hw_power_charge_clr
);
535 /* 5V to battery handoff. */
536 setbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
538 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
540 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO
, &power_regs
->hw_power_ctrl_clr
);
542 clrsetbits_le32(&power_regs
->hw_power_minpwr
,
543 POWER_MINPWR_HALFFETS
, POWER_MINPWR_DOUBLE_FETS
);
545 mxs_power_set_linreg();
547 clrbits_le32(&power_regs
->hw_power_vdddctrl
,
548 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
);
550 clrbits_le32(&power_regs
->hw_power_vddactrl
,
551 POWER_VDDACTRL_DISABLE_FET
| POWER_VDDACTRL_ENABLE_LINREG
);
553 clrbits_le32(&power_regs
->hw_power_vddioctrl
,
554 POWER_VDDIOCTRL_DISABLE_FET
);
556 setbits_le32(&power_regs
->hw_power_5vctrl
,
557 POWER_5VCTRL_PWD_CHARGE_4P2_MASK
);
559 setbits_le32(&power_regs
->hw_power_5vctrl
,
560 POWER_5VCTRL_ENABLE_DCDC
);
562 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
563 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
564 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
567 static void mxs_handle_5v_conflict(void)
569 struct mxs_power_regs
*power_regs
=
570 (struct mxs_power_regs
*)MXS_POWER_BASE
;
573 setbits_le32(&power_regs
->hw_power_vddioctrl
,
574 POWER_VDDIOCTRL_BO_OFFSET_MASK
);
577 tmp
= readl(&power_regs
->hw_power_sts
);
579 if (tmp
& POWER_STS_VDDIO_BO
) {
581 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
588 if (tmp
& POWER_STS_VDD5V_GT_VDDIO
) {
596 if (tmp
& POWER_STS_PSWITCH_MASK
) {
603 static void mxs_5v_boot(void)
605 struct mxs_power_regs
*power_regs
=
606 (struct mxs_power_regs
*)MXS_POWER_BASE
;
609 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
610 * but their implementation always returns 1 so we omit it here.
612 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
618 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
623 mxs_handle_5v_conflict();
626 static void mxs_init_batt_bo(void)
628 struct mxs_power_regs
*power_regs
=
629 (struct mxs_power_regs
*)MXS_POWER_BASE
;
632 clrsetbits_le32(&power_regs
->hw_power_battmonitor
,
633 POWER_BATTMONITOR_BRWNOUT_LVL_MASK
,
634 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET
);
636 writel(POWER_CTRL_BATT_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
637 writel(POWER_CTRL_ENIRQ_BATT_BO
, &power_regs
->hw_power_ctrl_clr
);
640 static void mxs_switch_vddd_to_dcdc_source(void)
642 struct mxs_power_regs
*power_regs
=
643 (struct mxs_power_regs
*)MXS_POWER_BASE
;
645 clrsetbits_le32(&power_regs
->hw_power_vdddctrl
,
646 POWER_VDDDCTRL_LINREG_OFFSET_MASK
,
647 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
);
649 clrbits_le32(&power_regs
->hw_power_vdddctrl
,
650 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
|
651 POWER_VDDDCTRL_DISABLE_STEPPING
);
654 static void mxs_power_configure_power_source(void)
656 int batt_ready
, batt_good
;
657 struct mxs_power_regs
*power_regs
=
658 (struct mxs_power_regs
*)MXS_POWER_BASE
;
659 struct mxs_lradc_regs
*lradc_regs
=
660 (struct mxs_lradc_regs
*)MXS_LRADC_BASE
;
662 mxs_src_power_init();
664 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
665 batt_ready
= mxs_is_batt_ready();
667 /* 5V source detected, good battery detected. */
670 batt_good
= mxs_is_batt_good();
672 /* 5V source detected, bad battery detected. */
673 writel(LRADC_CONVERSION_AUTOMATIC
,
674 &lradc_regs
->hw_lradc_conversion_clr
);
675 clrbits_le32(&power_regs
->hw_power_battmonitor
,
676 POWER_BATTMONITOR_BATT_VAL_MASK
);
681 /* 5V not detected, booting from battery. */
685 mxs_power_clock2pll();
689 mxs_switch_vddd_to_dcdc_source();
692 static void mxs_enable_output_rail_protection(void)
694 struct mxs_power_regs
*power_regs
=
695 (struct mxs_power_regs
*)MXS_POWER_BASE
;
697 writel(POWER_CTRL_VDDD_BO_IRQ
| POWER_CTRL_VDDA_BO_IRQ
|
698 POWER_CTRL_VDDIO_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
700 setbits_le32(&power_regs
->hw_power_vdddctrl
,
701 POWER_VDDDCTRL_PWDN_BRNOUT
);
703 setbits_le32(&power_regs
->hw_power_vddactrl
,
704 POWER_VDDACTRL_PWDN_BRNOUT
);
706 setbits_le32(&power_regs
->hw_power_vddioctrl
,
707 POWER_VDDIOCTRL_PWDN_BRNOUT
);
710 static int mxs_get_vddio_power_source_off(void)
712 struct mxs_power_regs
*power_regs
=
713 (struct mxs_power_regs
*)MXS_POWER_BASE
;
716 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
717 tmp
= readl(&power_regs
->hw_power_vddioctrl
);
718 if (tmp
& POWER_VDDIOCTRL_DISABLE_FET
) {
719 if ((tmp
& POWER_VDDIOCTRL_LINREG_OFFSET_MASK
) ==
720 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS
) {
725 if (!(readl(&power_regs
->hw_power_5vctrl
) &
726 POWER_5VCTRL_ENABLE_DCDC
)) {
727 if ((tmp
& POWER_VDDIOCTRL_LINREG_OFFSET_MASK
) ==
728 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS
) {
738 static int mxs_get_vddd_power_source_off(void)
740 struct mxs_power_regs
*power_regs
=
741 (struct mxs_power_regs
*)MXS_POWER_BASE
;
744 tmp
= readl(&power_regs
->hw_power_vdddctrl
);
745 if (tmp
& POWER_VDDDCTRL_DISABLE_FET
) {
746 if ((tmp
& POWER_VDDDCTRL_LINREG_OFFSET_MASK
) ==
747 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS
) {
752 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
753 if (!(readl(&power_regs
->hw_power_5vctrl
) &
754 POWER_5VCTRL_ENABLE_DCDC
)) {
759 if (!(tmp
& POWER_VDDDCTRL_ENABLE_LINREG
)) {
760 if ((tmp
& POWER_VDDDCTRL_LINREG_OFFSET_MASK
) ==
761 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
) {
769 struct mxs_vddx_cfg
{
773 int (*powered_by_linreg
)(void);
777 uint32_t bo_offset_mask
;
778 uint32_t bo_offset_offset
;
781 static const struct mxs_vddx_cfg mxs_vddio_cfg
= {
782 .reg
= &(((struct mxs_power_regs
*)MXS_POWER_BASE
)->
786 .powered_by_linreg
= mxs_get_vddio_power_source_off
,
787 .trg_mask
= POWER_VDDIOCTRL_TRG_MASK
,
788 .bo_irq
= POWER_CTRL_VDDIO_BO_IRQ
,
789 .bo_enirq
= POWER_CTRL_ENIRQ_VDDIO_BO
,
790 .bo_offset_mask
= POWER_VDDIOCTRL_BO_OFFSET_MASK
,
791 .bo_offset_offset
= POWER_VDDIOCTRL_BO_OFFSET_OFFSET
,
794 static const struct mxs_vddx_cfg mxs_vddd_cfg
= {
795 .reg
= &(((struct mxs_power_regs
*)MXS_POWER_BASE
)->
799 .powered_by_linreg
= mxs_get_vddd_power_source_off
,
800 .trg_mask
= POWER_VDDDCTRL_TRG_MASK
,
801 .bo_irq
= POWER_CTRL_VDDD_BO_IRQ
,
802 .bo_enirq
= POWER_CTRL_ENIRQ_VDDD_BO
,
803 .bo_offset_mask
= POWER_VDDDCTRL_BO_OFFSET_MASK
,
804 .bo_offset_offset
= POWER_VDDDCTRL_BO_OFFSET_OFFSET
,
807 static void mxs_power_set_vddx(const struct mxs_vddx_cfg
*cfg
,
808 uint32_t new_target
, uint32_t new_brownout
)
810 struct mxs_power_regs
*power_regs
=
811 (struct mxs_power_regs
*)MXS_POWER_BASE
;
812 uint32_t cur_target
, diff
, bo_int
= 0;
813 uint32_t powered_by_linreg
= 0;
816 new_brownout
= DIV_ROUND(new_target
- new_brownout
, cfg
->step_mV
);
818 cur_target
= readl(cfg
->reg
);
819 cur_target
&= cfg
->trg_mask
;
820 cur_target
*= cfg
->step_mV
;
821 cur_target
+= cfg
->lowest_mV
;
823 adjust_up
= new_target
> cur_target
;
824 powered_by_linreg
= cfg
->powered_by_linreg();
827 if (powered_by_linreg
) {
828 bo_int
= readl(cfg
->reg
);
829 clrbits_le32(cfg
->reg
, cfg
->bo_enirq
);
831 setbits_le32(cfg
->reg
, cfg
->bo_offset_mask
);
835 if (abs(new_target
- cur_target
) > 100) {
837 diff
= cur_target
+ 100;
839 diff
= cur_target
- 100;
844 diff
-= cfg
->lowest_mV
;
845 diff
/= cfg
->step_mV
;
847 clrsetbits_le32(cfg
->reg
, cfg
->trg_mask
, diff
);
849 if (powered_by_linreg
||
850 (readl(&power_regs
->hw_power_sts
) &
851 POWER_STS_VDD5V_GT_VDDIO
))
855 tmp
= readl(&power_regs
->hw_power_sts
);
856 if (tmp
& POWER_STS_DC_OK
)
861 cur_target
= readl(cfg
->reg
);
862 cur_target
&= cfg
->trg_mask
;
863 cur_target
*= cfg
->step_mV
;
864 cur_target
+= cfg
->lowest_mV
;
865 } while (new_target
> cur_target
);
867 if (adjust_up
&& powered_by_linreg
) {
868 writel(cfg
->bo_irq
, &power_regs
->hw_power_ctrl_clr
);
869 if (bo_int
& cfg
->bo_enirq
)
870 setbits_le32(cfg
->reg
, cfg
->bo_enirq
);
873 clrsetbits_le32(cfg
->reg
, cfg
->bo_offset_mask
,
874 new_brownout
<< cfg
->bo_offset_offset
);
877 static void mxs_setup_batt_detect(void)
880 mxs_lradc_enable_batt_measurement();
884 static void mxs_ungate_power(void)
887 struct mxs_power_regs
*power_regs
=
888 (struct mxs_power_regs
*)MXS_POWER_BASE
;
890 writel(POWER_CTRL_CLKGATE
, &power_regs
->hw_power_ctrl_clr
);
894 void mxs_power_init(void)
896 struct mxs_power_regs
*power_regs
=
897 (struct mxs_power_regs
*)MXS_POWER_BASE
;
901 mxs_power_clock2xtal();
902 mxs_power_clear_auto_restart();
903 mxs_power_set_linreg();
904 mxs_power_setup_5v_detect();
906 mxs_setup_batt_detect();
908 mxs_power_configure_power_source();
909 mxs_enable_output_rail_protection();
911 mxs_power_set_vddx(&mxs_vddio_cfg
, 3300, 3150);
912 mxs_power_set_vddx(&mxs_vddd_cfg
, 1500, 1000);
914 writel(POWER_CTRL_VDDD_BO_IRQ
| POWER_CTRL_VDDA_BO_IRQ
|
915 POWER_CTRL_VDDIO_BO_IRQ
| POWER_CTRL_VDD5V_DROOP_IRQ
|
916 POWER_CTRL_VBUS_VALID_IRQ
| POWER_CTRL_BATT_BO_IRQ
|
917 POWER_CTRL_DCDC4P2_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
919 writel(POWER_5VCTRL_PWDN_5VBRNOUT
, &power_regs
->hw_power_5vctrl_set
);
924 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
925 void mxs_power_wait_pswitch(void)
927 struct mxs_power_regs
*power_regs
=
928 (struct mxs_power_regs
*)MXS_POWER_BASE
;
930 while (!(readl(&power_regs
->hw_power_sts
) & POWER_STS_PSWITCH_MASK
))