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))