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 static void mxs_power_clock2xtal(void)
19 struct mxs_clkctrl_regs
*clkctrl_regs
=
20 (struct mxs_clkctrl_regs
*)MXS_CLKCTRL_BASE
;
22 /* Set XTAL as CPU reference clock */
23 writel(CLKCTRL_CLKSEQ_BYPASS_CPU
,
24 &clkctrl_regs
->hw_clkctrl_clkseq_set
);
27 static void mxs_power_clock2pll(void)
29 struct mxs_clkctrl_regs
*clkctrl_regs
=
30 (struct mxs_clkctrl_regs
*)MXS_CLKCTRL_BASE
;
32 setbits_le32(&clkctrl_regs
->hw_clkctrl_pll0ctrl0
,
33 CLKCTRL_PLL0CTRL0_POWER
);
35 setbits_le32(&clkctrl_regs
->hw_clkctrl_clkseq
,
36 CLKCTRL_CLKSEQ_BYPASS_CPU
);
39 static void mxs_power_clear_auto_restart(void)
41 struct mxs_rtc_regs
*rtc_regs
=
42 (struct mxs_rtc_regs
*)MXS_RTC_BASE
;
44 writel(RTC_CTRL_SFTRST
, &rtc_regs
->hw_rtc_ctrl_clr
);
45 while (readl(&rtc_regs
->hw_rtc_ctrl
) & RTC_CTRL_SFTRST
)
48 writel(RTC_CTRL_CLKGATE
, &rtc_regs
->hw_rtc_ctrl_clr
);
49 while (readl(&rtc_regs
->hw_rtc_ctrl
) & RTC_CTRL_CLKGATE
)
53 * Due to the hardware design bug of mx28 EVK-A
54 * we need to set the AUTO_RESTART bit.
56 if (readl(&rtc_regs
->hw_rtc_persistent0
) & RTC_PERSISTENT0_AUTO_RESTART
)
59 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_NEW_REGS_MASK
)
62 setbits_le32(&rtc_regs
->hw_rtc_persistent0
,
63 RTC_PERSISTENT0_AUTO_RESTART
);
64 writel(RTC_CTRL_FORCE_UPDATE
, &rtc_regs
->hw_rtc_ctrl_set
);
65 writel(RTC_CTRL_FORCE_UPDATE
, &rtc_regs
->hw_rtc_ctrl_clr
);
66 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_NEW_REGS_MASK
)
68 while (readl(&rtc_regs
->hw_rtc_stat
) & RTC_STAT_STALE_REGS_MASK
)
72 static void mxs_power_set_linreg(void)
74 struct mxs_power_regs
*power_regs
=
75 (struct mxs_power_regs
*)MXS_POWER_BASE
;
77 /* Set linear regulator 25mV below switching converter */
78 clrsetbits_le32(&power_regs
->hw_power_vdddctrl
,
79 POWER_VDDDCTRL_LINREG_OFFSET_MASK
,
80 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
);
82 clrsetbits_le32(&power_regs
->hw_power_vddactrl
,
83 POWER_VDDACTRL_LINREG_OFFSET_MASK
,
84 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW
);
86 clrsetbits_le32(&power_regs
->hw_power_vddioctrl
,
87 POWER_VDDIOCTRL_LINREG_OFFSET_MASK
,
88 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW
);
91 static int mxs_get_batt_volt(void)
93 struct mxs_power_regs
*power_regs
=
94 (struct mxs_power_regs
*)MXS_POWER_BASE
;
95 uint32_t volt
= readl(&power_regs
->hw_power_battmonitor
);
96 volt
&= POWER_BATTMONITOR_BATT_VAL_MASK
;
97 volt
>>= POWER_BATTMONITOR_BATT_VAL_OFFSET
;
102 static int mxs_is_batt_ready(void)
104 return (mxs_get_batt_volt() >= 3600);
107 static int mxs_is_batt_good(void)
109 struct mxs_power_regs
*power_regs
=
110 (struct mxs_power_regs
*)MXS_POWER_BASE
;
111 uint32_t volt
= mxs_get_batt_volt();
113 if ((volt
>= 2400) && (volt
<= 4300))
116 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
117 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
118 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
119 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
120 &power_regs
->hw_power_5vctrl_clr
);
122 clrsetbits_le32(&power_regs
->hw_power_charge
,
123 POWER_CHARGE_STOP_ILIMIT_MASK
| POWER_CHARGE_BATTCHRG_I_MASK
,
124 POWER_CHARGE_STOP_ILIMIT_10MA
| 0x3);
126 writel(POWER_CHARGE_PWD_BATTCHRG
, &power_regs
->hw_power_charge_clr
);
127 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
128 &power_regs
->hw_power_5vctrl_clr
);
132 volt
= mxs_get_batt_volt();
140 writel(POWER_CHARGE_STOP_ILIMIT_MASK
| POWER_CHARGE_BATTCHRG_I_MASK
,
141 &power_regs
->hw_power_charge_clr
);
142 writel(POWER_CHARGE_PWD_BATTCHRG
, &power_regs
->hw_power_charge_set
);
147 static void mxs_power_setup_5v_detect(void)
149 struct mxs_power_regs
*power_regs
=
150 (struct mxs_power_regs
*)MXS_POWER_BASE
;
152 /* Start 5V detection */
153 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
154 POWER_5VCTRL_VBUSVALID_TRSH_MASK
,
155 POWER_5VCTRL_VBUSVALID_TRSH_4V4
|
156 POWER_5VCTRL_PWRUP_VBUS_CMPS
);
159 static void mxs_src_power_init(void)
161 struct mxs_power_regs
*power_regs
=
162 (struct mxs_power_regs
*)MXS_POWER_BASE
;
164 /* Improve efficieny and reduce transient ripple */
165 writel(POWER_LOOPCTRL_TOGGLE_DIF
| POWER_LOOPCTRL_EN_CM_HYST
|
166 POWER_LOOPCTRL_EN_DF_HYST
, &power_regs
->hw_power_loopctrl_set
);
168 clrsetbits_le32(&power_regs
->hw_power_dclimits
,
169 POWER_DCLIMITS_POSLIMIT_BUCK_MASK
,
170 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET
);
172 setbits_le32(&power_regs
->hw_power_battmonitor
,
173 POWER_BATTMONITOR_EN_BATADJ
);
175 /* Increase the RCSCALE level for quick DCDC response to dynamic load */
176 clrsetbits_le32(&power_regs
->hw_power_loopctrl
,
177 POWER_LOOPCTRL_EN_RCSCALE_MASK
,
178 POWER_LOOPCTRL_RCSCALE_THRESH
|
179 POWER_LOOPCTRL_EN_RCSCALE_8X
);
181 clrsetbits_le32(&power_regs
->hw_power_minpwr
,
182 POWER_MINPWR_HALFFETS
, POWER_MINPWR_DOUBLE_FETS
);
184 /* 5V to battery handoff ... FIXME */
185 setbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
187 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
190 static void mxs_power_init_4p2_params(void)
192 struct mxs_power_regs
*power_regs
=
193 (struct mxs_power_regs
*)MXS_POWER_BASE
;
195 /* Setup 4P2 parameters */
196 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
197 POWER_DCDC4P2_CMPTRIP_MASK
| POWER_DCDC4P2_TRG_MASK
,
198 POWER_DCDC4P2_TRG_4V2
| (31 << POWER_DCDC4P2_CMPTRIP_OFFSET
));
200 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
201 POWER_5VCTRL_HEADROOM_ADJ_MASK
,
202 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET
);
204 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
205 POWER_DCDC4P2_DROPOUT_CTRL_MASK
,
206 POWER_DCDC4P2_DROPOUT_CTRL_100MV
|
207 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
);
209 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
210 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
211 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
214 static void mxs_enable_4p2_dcdc_input(int xfer
)
216 struct mxs_power_regs
*power_regs
=
217 (struct mxs_power_regs
*)MXS_POWER_BASE
;
218 uint32_t tmp
, vbus_thresh
, vbus_5vdetect
, pwd_bo
;
219 uint32_t prev_5v_brnout
, prev_5v_droop
;
221 prev_5v_brnout
= readl(&power_regs
->hw_power_5vctrl
) &
222 POWER_5VCTRL_PWDN_5VBRNOUT
;
223 prev_5v_droop
= readl(&power_regs
->hw_power_ctrl
) &
224 POWER_CTRL_ENIRQ_VDD5V_DROOP
;
226 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_PWDN_5VBRNOUT
);
227 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
228 &power_regs
->hw_power_reset
);
230 clrbits_le32(&power_regs
->hw_power_ctrl
, POWER_CTRL_ENIRQ_VDD5V_DROOP
);
232 if (xfer
&& (readl(&power_regs
->hw_power_5vctrl
) &
233 POWER_5VCTRL_ENABLE_DCDC
)) {
238 * Recording orignal values that will be modified temporarlily
239 * to handle a chip bug. See chip errata for CQ ENGR00115837
241 tmp
= readl(&power_regs
->hw_power_5vctrl
);
242 vbus_thresh
= tmp
& POWER_5VCTRL_VBUSVALID_TRSH_MASK
;
243 vbus_5vdetect
= tmp
& POWER_5VCTRL_VBUSVALID_5VDETECT
;
245 pwd_bo
= readl(&power_regs
->hw_power_minpwr
) & POWER_MINPWR_PWD_BO
;
248 * Disable mechanisms that get erroneously tripped by when setting
249 * the DCDC4P2 EN_DCDC
251 clrbits_le32(&power_regs
->hw_power_5vctrl
,
252 POWER_5VCTRL_VBUSVALID_5VDETECT
|
253 POWER_5VCTRL_VBUSVALID_TRSH_MASK
);
255 writel(POWER_MINPWR_PWD_BO
, &power_regs
->hw_power_minpwr_set
);
258 setbits_le32(&power_regs
->hw_power_5vctrl
,
259 POWER_5VCTRL_DCDC_XFER
);
261 clrbits_le32(&power_regs
->hw_power_5vctrl
,
262 POWER_5VCTRL_DCDC_XFER
);
264 setbits_le32(&power_regs
->hw_power_5vctrl
,
265 POWER_5VCTRL_ENABLE_DCDC
);
267 setbits_le32(&power_regs
->hw_power_dcdc4p2
,
268 POWER_DCDC4P2_ENABLE_DCDC
);
273 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
274 POWER_5VCTRL_VBUSVALID_TRSH_MASK
, vbus_thresh
);
277 writel(vbus_5vdetect
, &power_regs
->hw_power_5vctrl_set
);
280 clrbits_le32(&power_regs
->hw_power_minpwr
, POWER_MINPWR_PWD_BO
);
282 while (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
)
283 writel(POWER_CTRL_VBUS_VALID_IRQ
,
284 &power_regs
->hw_power_ctrl_clr
);
286 if (prev_5v_brnout
) {
287 writel(POWER_5VCTRL_PWDN_5VBRNOUT
,
288 &power_regs
->hw_power_5vctrl_set
);
289 writel(POWER_RESET_UNLOCK_KEY
,
290 &power_regs
->hw_power_reset
);
292 writel(POWER_5VCTRL_PWDN_5VBRNOUT
,
293 &power_regs
->hw_power_5vctrl_clr
);
294 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
295 &power_regs
->hw_power_reset
);
298 while (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VDD5V_DROOP_IRQ
)
299 writel(POWER_CTRL_VDD5V_DROOP_IRQ
,
300 &power_regs
->hw_power_ctrl_clr
);
303 clrbits_le32(&power_regs
->hw_power_ctrl
,
304 POWER_CTRL_ENIRQ_VDD5V_DROOP
);
306 setbits_le32(&power_regs
->hw_power_ctrl
,
307 POWER_CTRL_ENIRQ_VDD5V_DROOP
);
310 static void mxs_power_init_4p2_regulator(void)
312 struct mxs_power_regs
*power_regs
=
313 (struct mxs_power_regs
*)MXS_POWER_BASE
;
316 setbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_ENABLE_4P2
);
318 writel(POWER_CHARGE_ENABLE_LOAD
, &power_regs
->hw_power_charge_set
);
320 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
321 &power_regs
->hw_power_5vctrl_clr
);
322 clrbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_TRG_MASK
);
324 /* Power up the 4p2 rail and logic/control */
325 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
326 &power_regs
->hw_power_5vctrl_clr
);
329 * Start charging up the 4p2 capacitor. We ramp of this charge
330 * gradually to avoid large inrush current from the 5V cable which can
331 * cause transients/problems
333 mxs_enable_4p2_dcdc_input(0);
335 if (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
) {
337 * If we arrived here, we were unable to recover from mx23 chip
338 * errata 5837. 4P2 is disabled and sufficient battery power is
339 * not present. Exiting to not enable DCDC power during 5V
342 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
343 POWER_DCDC4P2_ENABLE_DCDC
);
344 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
345 &power_regs
->hw_power_5vctrl_set
);
350 * Here we set the 4p2 brownout level to something very close to 4.2V.
351 * We then check the brownout status. If the brownout status is false,
352 * the voltage is already close to the target voltage of 4.2V so we
353 * can go ahead and set the 4P2 current limit to our max target limit.
354 * If the brownout status is true, we need to ramp us the current limit
355 * so that we don't cause large inrush current issues. We step up the
356 * current limit until the brownout status is false or until we've
357 * reached our maximum defined 4p2 current limit.
359 clrsetbits_le32(&power_regs
->hw_power_dcdc4p2
,
360 POWER_DCDC4P2_BO_MASK
,
361 22 << POWER_DCDC4P2_BO_OFFSET
); /* 4.15V */
363 if (!(readl(&power_regs
->hw_power_sts
) & POWER_STS_DCDC_4P2_BO
)) {
364 setbits_le32(&power_regs
->hw_power_5vctrl
,
365 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
367 tmp
= (readl(&power_regs
->hw_power_5vctrl
) &
368 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
) >>
369 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
;
371 if (!(readl(&power_regs
->hw_power_sts
) &
372 POWER_STS_DCDC_4P2_BO
)) {
373 tmp
= readl(&power_regs
->hw_power_5vctrl
);
374 tmp
|= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
;
376 writel(tmp
, &power_regs
->hw_power_5vctrl
);
380 tmp2
= readl(&power_regs
->hw_power_5vctrl
);
381 tmp2
&= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
;
383 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
;
384 writel(tmp2
, &power_regs
->hw_power_5vctrl
);
390 clrbits_le32(&power_regs
->hw_power_dcdc4p2
, POWER_DCDC4P2_BO_MASK
);
391 writel(POWER_CTRL_DCDC4P2_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
394 static void mxs_power_init_dcdc_4p2_source(void)
396 struct mxs_power_regs
*power_regs
=
397 (struct mxs_power_regs
*)MXS_POWER_BASE
;
399 if (!(readl(&power_regs
->hw_power_dcdc4p2
) &
400 POWER_DCDC4P2_ENABLE_DCDC
)) {
404 mxs_enable_4p2_dcdc_input(1);
406 if (readl(&power_regs
->hw_power_ctrl
) & POWER_CTRL_VBUS_VALID_IRQ
) {
407 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
408 POWER_DCDC4P2_ENABLE_DCDC
);
409 writel(POWER_5VCTRL_ENABLE_DCDC
,
410 &power_regs
->hw_power_5vctrl_clr
);
411 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK
,
412 &power_regs
->hw_power_5vctrl_set
);
416 static void mxs_power_enable_4p2(void)
418 struct mxs_power_regs
*power_regs
=
419 (struct mxs_power_regs
*)MXS_POWER_BASE
;
420 uint32_t vdddctrl
, vddactrl
, vddioctrl
;
423 vdddctrl
= readl(&power_regs
->hw_power_vdddctrl
);
424 vddactrl
= readl(&power_regs
->hw_power_vddactrl
);
425 vddioctrl
= readl(&power_regs
->hw_power_vddioctrl
);
427 setbits_le32(&power_regs
->hw_power_vdddctrl
,
428 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
|
429 POWER_VDDDCTRL_PWDN_BRNOUT
);
431 setbits_le32(&power_regs
->hw_power_vddactrl
,
432 POWER_VDDACTRL_DISABLE_FET
| POWER_VDDACTRL_ENABLE_LINREG
|
433 POWER_VDDACTRL_PWDN_BRNOUT
);
435 setbits_le32(&power_regs
->hw_power_vddioctrl
,
436 POWER_VDDIOCTRL_DISABLE_FET
| POWER_VDDIOCTRL_PWDN_BRNOUT
);
438 mxs_power_init_4p2_params();
439 mxs_power_init_4p2_regulator();
441 /* Shutdown battery (none present) */
442 if (!mxs_is_batt_ready()) {
443 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
444 POWER_DCDC4P2_BO_MASK
);
445 writel(POWER_CTRL_DCDC4P2_BO_IRQ
,
446 &power_regs
->hw_power_ctrl_clr
);
447 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO
,
448 &power_regs
->hw_power_ctrl_clr
);
451 mxs_power_init_dcdc_4p2_source();
453 writel(vdddctrl
, &power_regs
->hw_power_vdddctrl
);
455 writel(vddactrl
, &power_regs
->hw_power_vddactrl
);
457 writel(vddioctrl
, &power_regs
->hw_power_vddioctrl
);
460 * Check if FET is enabled on either powerout and if so,
464 tmp
|= !(readl(&power_regs
->hw_power_vdddctrl
) &
465 POWER_VDDDCTRL_DISABLE_FET
);
466 tmp
|= !(readl(&power_regs
->hw_power_vddactrl
) &
467 POWER_VDDACTRL_DISABLE_FET
);
468 tmp
|= !(readl(&power_regs
->hw_power_vddioctrl
) &
469 POWER_VDDIOCTRL_DISABLE_FET
);
471 writel(POWER_CHARGE_ENABLE_LOAD
,
472 &power_regs
->hw_power_charge_clr
);
475 static void mxs_boot_valid_5v(void)
477 struct mxs_power_regs
*power_regs
=
478 (struct mxs_power_regs
*)MXS_POWER_BASE
;
481 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
482 * disconnect event. FIXME
484 writel(POWER_5VCTRL_VBUSVALID_5VDETECT
,
485 &power_regs
->hw_power_5vctrl_set
);
487 /* Configure polarity to check for 5V disconnection. */
488 writel(POWER_CTRL_POLARITY_VBUSVALID
|
489 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO
,
490 &power_regs
->hw_power_ctrl_clr
);
492 writel(POWER_CTRL_VBUS_VALID_IRQ
| POWER_CTRL_VDD5V_GT_VDDIO_IRQ
,
493 &power_regs
->hw_power_ctrl_clr
);
495 mxs_power_enable_4p2();
498 static void mxs_powerdown(void)
500 struct mxs_power_regs
*power_regs
=
501 (struct mxs_power_regs
*)MXS_POWER_BASE
;
502 writel(POWER_RESET_UNLOCK_KEY
, &power_regs
->hw_power_reset
);
503 writel(POWER_RESET_UNLOCK_KEY
| POWER_RESET_PWD_OFF
,
504 &power_regs
->hw_power_reset
);
507 static void mxs_batt_boot(void)
509 struct mxs_power_regs
*power_regs
=
510 (struct mxs_power_regs
*)MXS_POWER_BASE
;
512 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_PWDN_5VBRNOUT
);
513 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_ENABLE_DCDC
);
515 clrbits_le32(&power_regs
->hw_power_dcdc4p2
,
516 POWER_DCDC4P2_ENABLE_DCDC
| POWER_DCDC4P2_ENABLE_4P2
);
517 writel(POWER_CHARGE_ENABLE_LOAD
, &power_regs
->hw_power_charge_clr
);
519 /* 5V to battery handoff. */
520 setbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
522 clrbits_le32(&power_regs
->hw_power_5vctrl
, POWER_5VCTRL_DCDC_XFER
);
524 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO
, &power_regs
->hw_power_ctrl_clr
);
526 clrsetbits_le32(&power_regs
->hw_power_minpwr
,
527 POWER_MINPWR_HALFFETS
, POWER_MINPWR_DOUBLE_FETS
);
529 mxs_power_set_linreg();
531 clrbits_le32(&power_regs
->hw_power_vdddctrl
,
532 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
);
534 clrbits_le32(&power_regs
->hw_power_vddactrl
,
535 POWER_VDDACTRL_DISABLE_FET
| POWER_VDDACTRL_ENABLE_LINREG
);
537 clrbits_le32(&power_regs
->hw_power_vddioctrl
,
538 POWER_VDDIOCTRL_DISABLE_FET
);
540 setbits_le32(&power_regs
->hw_power_5vctrl
,
541 POWER_5VCTRL_PWD_CHARGE_4P2_MASK
);
543 setbits_le32(&power_regs
->hw_power_5vctrl
,
544 POWER_5VCTRL_ENABLE_DCDC
);
546 clrsetbits_le32(&power_regs
->hw_power_5vctrl
,
547 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK
,
548 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET
);
551 static void mxs_handle_5v_conflict(void)
553 struct mxs_power_regs
*power_regs
=
554 (struct mxs_power_regs
*)MXS_POWER_BASE
;
557 setbits_le32(&power_regs
->hw_power_vddioctrl
,
558 POWER_VDDIOCTRL_BO_OFFSET_MASK
);
561 tmp
= readl(&power_regs
->hw_power_sts
);
563 if (tmp
& POWER_STS_VDDIO_BO
) {
565 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
572 if (tmp
& POWER_STS_VDD5V_GT_VDDIO
) {
580 if (tmp
& POWER_STS_PSWITCH_MASK
) {
587 static void mxs_5v_boot(void)
589 struct mxs_power_regs
*power_regs
=
590 (struct mxs_power_regs
*)MXS_POWER_BASE
;
593 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
594 * but their implementation always returns 1 so we omit it here.
596 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
602 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
607 mxs_handle_5v_conflict();
610 static void mxs_init_batt_bo(void)
612 struct mxs_power_regs
*power_regs
=
613 (struct mxs_power_regs
*)MXS_POWER_BASE
;
616 clrsetbits_le32(&power_regs
->hw_power_battmonitor
,
617 POWER_BATTMONITOR_BRWNOUT_LVL_MASK
,
618 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET
);
620 writel(POWER_CTRL_BATT_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
621 writel(POWER_CTRL_ENIRQ_BATT_BO
, &power_regs
->hw_power_ctrl_clr
);
624 static void mxs_switch_vddd_to_dcdc_source(void)
626 struct mxs_power_regs
*power_regs
=
627 (struct mxs_power_regs
*)MXS_POWER_BASE
;
629 clrsetbits_le32(&power_regs
->hw_power_vdddctrl
,
630 POWER_VDDDCTRL_LINREG_OFFSET_MASK
,
631 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
);
633 clrbits_le32(&power_regs
->hw_power_vdddctrl
,
634 POWER_VDDDCTRL_DISABLE_FET
| POWER_VDDDCTRL_ENABLE_LINREG
|
635 POWER_VDDDCTRL_DISABLE_STEPPING
);
638 static void mxs_power_configure_power_source(void)
640 int batt_ready
, batt_good
;
641 struct mxs_power_regs
*power_regs
=
642 (struct mxs_power_regs
*)MXS_POWER_BASE
;
643 struct mxs_lradc_regs
*lradc_regs
=
644 (struct mxs_lradc_regs
*)MXS_LRADC_BASE
;
646 mxs_src_power_init();
648 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
649 batt_ready
= mxs_is_batt_ready();
651 /* 5V source detected, good battery detected. */
654 batt_good
= mxs_is_batt_good();
656 /* 5V source detected, bad battery detected. */
657 writel(LRADC_CONVERSION_AUTOMATIC
,
658 &lradc_regs
->hw_lradc_conversion_clr
);
659 clrbits_le32(&power_regs
->hw_power_battmonitor
,
660 POWER_BATTMONITOR_BATT_VAL_MASK
);
665 /* 5V not detected, booting from battery. */
669 mxs_power_clock2pll();
673 mxs_switch_vddd_to_dcdc_source();
676 /* Fire up the VDDMEM LinReg now that we're all set. */
677 writel(POWER_VDDMEMCTRL_ENABLE_LINREG
| POWER_VDDMEMCTRL_ENABLE_ILIMIT
,
678 &power_regs
->hw_power_vddmemctrl
);
682 static void mxs_enable_output_rail_protection(void)
684 struct mxs_power_regs
*power_regs
=
685 (struct mxs_power_regs
*)MXS_POWER_BASE
;
687 writel(POWER_CTRL_VDDD_BO_IRQ
| POWER_CTRL_VDDA_BO_IRQ
|
688 POWER_CTRL_VDDIO_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
690 setbits_le32(&power_regs
->hw_power_vdddctrl
,
691 POWER_VDDDCTRL_PWDN_BRNOUT
);
693 setbits_le32(&power_regs
->hw_power_vddactrl
,
694 POWER_VDDACTRL_PWDN_BRNOUT
);
696 setbits_le32(&power_regs
->hw_power_vddioctrl
,
697 POWER_VDDIOCTRL_PWDN_BRNOUT
);
700 static int mxs_get_vddio_power_source_off(void)
702 struct mxs_power_regs
*power_regs
=
703 (struct mxs_power_regs
*)MXS_POWER_BASE
;
706 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
707 tmp
= readl(&power_regs
->hw_power_vddioctrl
);
708 if (tmp
& POWER_VDDIOCTRL_DISABLE_FET
) {
709 if ((tmp
& POWER_VDDIOCTRL_LINREG_OFFSET_MASK
) ==
710 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS
) {
715 if (!(readl(&power_regs
->hw_power_5vctrl
) &
716 POWER_5VCTRL_ENABLE_DCDC
)) {
717 if ((tmp
& POWER_VDDIOCTRL_LINREG_OFFSET_MASK
) ==
718 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS
) {
728 static int mxs_get_vddd_power_source_off(void)
730 struct mxs_power_regs
*power_regs
=
731 (struct mxs_power_regs
*)MXS_POWER_BASE
;
734 tmp
= readl(&power_regs
->hw_power_vdddctrl
);
735 if (tmp
& POWER_VDDDCTRL_DISABLE_FET
) {
736 if ((tmp
& POWER_VDDDCTRL_LINREG_OFFSET_MASK
) ==
737 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS
) {
742 if (readl(&power_regs
->hw_power_sts
) & POWER_STS_VDD5V_GT_VDDIO
) {
743 if (!(readl(&power_regs
->hw_power_5vctrl
) &
744 POWER_5VCTRL_ENABLE_DCDC
)) {
749 if (!(tmp
& POWER_VDDDCTRL_ENABLE_LINREG
)) {
750 if ((tmp
& POWER_VDDDCTRL_LINREG_OFFSET_MASK
) ==
751 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW
) {
759 struct mxs_vddx_cfg
{
763 int (*powered_by_linreg
)(void);
767 uint32_t bo_offset_mask
;
768 uint32_t bo_offset_offset
;
771 static const struct mxs_vddx_cfg mxs_vddio_cfg
= {
772 .reg
= &(((struct mxs_power_regs
*)MXS_POWER_BASE
)->
774 #if defined(CONFIG_MX23)
780 .powered_by_linreg
= mxs_get_vddio_power_source_off
,
781 .trg_mask
= POWER_VDDIOCTRL_TRG_MASK
,
782 .bo_irq
= POWER_CTRL_VDDIO_BO_IRQ
,
783 .bo_enirq
= POWER_CTRL_ENIRQ_VDDIO_BO
,
784 .bo_offset_mask
= POWER_VDDIOCTRL_BO_OFFSET_MASK
,
785 .bo_offset_offset
= POWER_VDDIOCTRL_BO_OFFSET_OFFSET
,
788 static const struct mxs_vddx_cfg mxs_vddd_cfg
= {
789 .reg
= &(((struct mxs_power_regs
*)MXS_POWER_BASE
)->
793 .powered_by_linreg
= mxs_get_vddd_power_source_off
,
794 .trg_mask
= POWER_VDDDCTRL_TRG_MASK
,
795 .bo_irq
= POWER_CTRL_VDDD_BO_IRQ
,
796 .bo_enirq
= POWER_CTRL_ENIRQ_VDDD_BO
,
797 .bo_offset_mask
= POWER_VDDDCTRL_BO_OFFSET_MASK
,
798 .bo_offset_offset
= POWER_VDDDCTRL_BO_OFFSET_OFFSET
,
802 static const struct mxs_vddx_cfg mxs_vddmem_cfg
= {
803 .reg
= &(((struct mxs_power_regs
*)MXS_POWER_BASE
)->
804 hw_power_vddmemctrl
),
807 .powered_by_linreg
= NULL
,
808 .trg_mask
= POWER_VDDMEMCTRL_TRG_MASK
,
812 .bo_offset_offset
= 0,
816 static void mxs_power_set_vddx(const struct mxs_vddx_cfg
*cfg
,
817 uint32_t new_target
, uint32_t new_brownout
)
819 struct mxs_power_regs
*power_regs
=
820 (struct mxs_power_regs
*)MXS_POWER_BASE
;
821 uint32_t cur_target
, diff
, bo_int
= 0;
822 uint32_t powered_by_linreg
= 0;
825 new_brownout
= DIV_ROUND(new_target
- new_brownout
, cfg
->step_mV
);
827 cur_target
= readl(cfg
->reg
);
828 cur_target
&= cfg
->trg_mask
;
829 cur_target
*= cfg
->step_mV
;
830 cur_target
+= cfg
->lowest_mV
;
832 adjust_up
= new_target
> cur_target
;
833 if (cfg
->powered_by_linreg
)
834 powered_by_linreg
= cfg
->powered_by_linreg();
836 if (adjust_up
&& cfg
->bo_irq
) {
837 if (powered_by_linreg
) {
838 bo_int
= readl(cfg
->reg
);
839 clrbits_le32(cfg
->reg
, cfg
->bo_enirq
);
841 setbits_le32(cfg
->reg
, cfg
->bo_offset_mask
);
845 if (abs(new_target
- cur_target
) > 100) {
847 diff
= cur_target
+ 100;
849 diff
= cur_target
- 100;
854 diff
-= cfg
->lowest_mV
;
855 diff
/= cfg
->step_mV
;
857 clrsetbits_le32(cfg
->reg
, cfg
->trg_mask
, diff
);
859 if (powered_by_linreg
||
860 (readl(&power_regs
->hw_power_sts
) &
861 POWER_STS_VDD5V_GT_VDDIO
))
865 tmp
= readl(&power_regs
->hw_power_sts
);
866 if (tmp
& POWER_STS_DC_OK
)
871 cur_target
= readl(cfg
->reg
);
872 cur_target
&= cfg
->trg_mask
;
873 cur_target
*= cfg
->step_mV
;
874 cur_target
+= cfg
->lowest_mV
;
875 } while (new_target
> cur_target
);
878 if (adjust_up
&& powered_by_linreg
) {
879 writel(cfg
->bo_irq
, &power_regs
->hw_power_ctrl_clr
);
880 if (bo_int
& cfg
->bo_enirq
)
881 setbits_le32(cfg
->reg
, cfg
->bo_enirq
);
884 clrsetbits_le32(cfg
->reg
, cfg
->bo_offset_mask
,
885 new_brownout
<< cfg
->bo_offset_offset
);
889 static void mxs_setup_batt_detect(void)
892 mxs_lradc_enable_batt_measurement();
896 static void mxs_ungate_power(void)
899 struct mxs_power_regs
*power_regs
=
900 (struct mxs_power_regs
*)MXS_POWER_BASE
;
902 writel(POWER_CTRL_CLKGATE
, &power_regs
->hw_power_ctrl_clr
);
906 void mxs_power_init(void)
908 struct mxs_power_regs
*power_regs
=
909 (struct mxs_power_regs
*)MXS_POWER_BASE
;
913 mxs_power_clock2xtal();
914 mxs_power_clear_auto_restart();
915 mxs_power_set_linreg();
916 mxs_power_setup_5v_detect();
918 mxs_setup_batt_detect();
920 mxs_power_configure_power_source();
921 mxs_enable_output_rail_protection();
923 mxs_power_set_vddx(&mxs_vddio_cfg
, 3300, 3150);
924 mxs_power_set_vddx(&mxs_vddd_cfg
, 1500, 1000);
926 mxs_power_set_vddx(&mxs_vddmem_cfg
, 2500, 1700);
928 writel(POWER_CTRL_VDDD_BO_IRQ
| POWER_CTRL_VDDA_BO_IRQ
|
929 POWER_CTRL_VDDIO_BO_IRQ
| POWER_CTRL_VDD5V_DROOP_IRQ
|
930 POWER_CTRL_VBUS_VALID_IRQ
| POWER_CTRL_BATT_BO_IRQ
|
931 POWER_CTRL_DCDC4P2_BO_IRQ
, &power_regs
->hw_power_ctrl_clr
);
933 writel(POWER_5VCTRL_PWDN_5VBRNOUT
, &power_regs
->hw_power_5vctrl_set
);
938 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
939 void mxs_power_wait_pswitch(void)
941 struct mxs_power_regs
*power_regs
=
942 (struct mxs_power_regs
*)MXS_POWER_BASE
;
944 while (!(readl(&power_regs
->hw_power_sts
) & POWER_STS_PSWITCH_MASK
))