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>
31 #include "mx28_init.h"
33 extern void dprintf(const char *fmt, ...);
38 #define __arch_getl(a) arch_getl(a, __func__, __LINE__)
39 static inline unsigned int arch_getl(volatile void *addr,
40 const char *fn, unsigned int ln)
42 volatile unsigned int *a = addr;
43 unsigned int val = *a;
44 dprintf("%s@%d: Read %x from %p\n", fn, ln, val, addr);
48 #define __arch_putl(v, a) arch_putl(v, a, __func__, __LINE__)
49 static inline void arch_putl(unsigned int val, volatile void *addr,
50 const char *fn, unsigned int ln)
52 volatile unsigned int *a = addr;
54 dprintf("%s@%d: Writing %x to %p\n", fn, ln, val, addr);
60 __static int mx28_power_vdd5v_gt_vddio(void)
62 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
63 struct mx28_power_regs *power_regs =
64 (struct mx28_power_regs *)MXS_POWER_BASE;
65 int power_sts = readl(&power_regs->hw_power_sts);
67 dprintf("%s@%d: 0\n", __func__, __LINE__,
68 !!(power_sts & POWER_STS_VDD5V_GT_VDDIO));
69 return power_sts & POWER_STS_VDD5V_GT_VDDIO;
71 dprintf("%s@%d: 0\n", __func__, __LINE__);
76 __static int mx28_power_vbus_valid(void)
78 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
79 struct mx28_power_regs *power_regs =
80 (struct mx28_power_regs *)MXS_POWER_BASE;
81 int power_5vctrl = readl(&power_regs->hw_power_5vctrl);
83 dprintf("%s@%d: 0\n", __func__, __LINE__,
84 !!(power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT));
85 return power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT;
87 dprintf("%s@%d: 0\n", __func__, __LINE__);
92 static void memdump(unsigned long addr, unsigned long len)
95 uint32_t *ptr = (void *)addr;
97 for (i = 0; i < len; i++) {
99 dprintf("\n%p:", &ptr[i]);
100 dprintf(" %x", ptr[i]);
105 //#undef CONFIG_SPL_FIXED_BATT_SUPPLY
107 __static void mx28_power_clock2xtal(void)
109 struct mx28_clkctrl_regs *clkctrl_regs =
110 (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
112 dprintf("%s@%d: \n", __func__, __LINE__);
113 /* Set XTAL as CPU reference clock */
114 writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
115 &clkctrl_regs->hw_clkctrl_clkseq_set);
118 __static void mx28_power_clock2pll(void)
120 struct mx28_clkctrl_regs *clkctrl_regs =
121 (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
123 dprintf("%s@%d: \n", __func__, __LINE__);
124 writel(CLKCTRL_PLL0CTRL0_POWER,
125 &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
127 writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
128 &clkctrl_regs->hw_clkctrl_clkseq_clr);
131 __static void mx28_power_clear_auto_restart(void)
133 struct mx28_rtc_regs *rtc_regs =
134 (struct mx28_rtc_regs *)MXS_RTC_BASE;
136 dprintf("%s@%d: \n", __func__, __LINE__);
137 writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
138 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
141 writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
142 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
144 #ifdef CONFIG_MACH_MX28EVK
146 * Due to the hardware design bug of mx28 EVK-A
147 * we need to set the AUTO_RESTART bit.
149 if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
152 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
155 setbits_le32(&rtc_regs->hw_rtc_persistent0,
156 RTC_PERSISTENT0_AUTO_RESTART);
157 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
158 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
159 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
161 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
166 __static void mx28_power_set_linreg(void)
168 struct mx28_power_regs *power_regs =
169 (struct mx28_power_regs *)MXS_POWER_BASE;
171 dprintf("%s@%d: \n", __func__, __LINE__);
172 /* Set linear regulator 25mV below switching converter */
173 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
174 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
175 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_ABOVE);
177 clrsetbits_le32(&power_regs->hw_power_vddactrl,
178 POWER_VDDACTRL_LINREG_OFFSET_MASK,
179 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
181 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
182 POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
183 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
184 dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
187 __static void mx28_power_setup_5v_detect(void)
189 struct mx28_power_regs *power_regs =
190 (struct mx28_power_regs *)MXS_POWER_BASE;
192 dprintf("%s@%d: \n", __func__, __LINE__);
193 /* Start 5V detection */
194 clrsetbits_le32(&power_regs->hw_power_5vctrl,
195 POWER_5VCTRL_VBUSVALID_TRSH_MASK,
196 POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
197 POWER_5VCTRL_PWRUP_VBUS_CMPS);
200 __static void mx28_src_power_init(void)
202 struct mx28_power_regs *power_regs =
203 (struct mx28_power_regs *)MXS_POWER_BASE;
205 dprintf("%s@%d: \n", __func__, __LINE__);
206 /* Improve efficieny and reduce transient ripple */
207 writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
208 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
210 clrsetbits_le32(&power_regs->hw_power_dclimits,
211 POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
212 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
214 setbits_le32(&power_regs->hw_power_battmonitor,
215 POWER_BATTMONITOR_EN_BATADJ);
217 /* Increase the RCSCALE level for quick DCDC response to dynamic load */
218 clrsetbits_le32(&power_regs->hw_power_loopctrl,
219 POWER_LOOPCTRL_EN_RCSCALE_MASK,
220 POWER_LOOPCTRL_RCSCALE_THRESH |
221 POWER_LOOPCTRL_EN_RCSCALE_8X);
223 clrsetbits_le32(&power_regs->hw_power_minpwr,
224 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
225 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
226 /* 5V to battery handoff ... FIXME */
227 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
229 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
233 __static void mx28_power_init_4p2_params(void)
235 struct mx28_power_regs *power_regs =
236 (struct mx28_power_regs *)MXS_POWER_BASE;
238 dprintf("%s@%d: \n", __func__, __LINE__);
239 /* Setup 4P2 parameters */
240 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
241 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
242 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
244 clrsetbits_le32(&power_regs->hw_power_5vctrl,
245 POWER_5VCTRL_HEADROOM_ADJ_MASK,
246 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
248 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
249 POWER_DCDC4P2_DROPOUT_CTRL_MASK,
250 POWER_DCDC4P2_DROPOUT_CTRL_100MV |
251 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
253 clrsetbits_le32(&power_regs->hw_power_5vctrl,
254 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
255 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
256 dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
257 dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
260 __static void mx28_enable_4p2_dcdc_input(int xfer)
262 struct mx28_power_regs *power_regs =
263 (struct mx28_power_regs *)MXS_POWER_BASE;
264 uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
265 uint32_t prev_5v_brnout, prev_5v_droop;
267 dprintf("%s@%d: %d\n", __func__, __LINE__, xfer);
268 prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
269 POWER_5VCTRL_PWDN_5VBRNOUT;
270 prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
271 POWER_CTRL_ENIRQ_VDD5V_DROOP;
273 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
274 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
275 &power_regs->hw_power_reset);
277 clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
279 if (xfer && (readl(&power_regs->hw_power_5vctrl) &
280 POWER_5VCTRL_ENABLE_DCDC)) {
285 * Recording orignal values that will be modified temporarlily
286 * to handle a chip bug. See chip errata for CQ ENGR00115837
288 tmp = readl(&power_regs->hw_power_5vctrl);
289 vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
290 vbus_5vdetect = mx28_power_vbus_valid();
292 pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
295 * Disable mechanisms that get erroneously tripped by when setting
296 * the DCDC4P2 EN_DCDC
298 clrbits_le32(&power_regs->hw_power_5vctrl,
299 POWER_5VCTRL_VBUSVALID_5VDETECT |
300 POWER_5VCTRL_VBUSVALID_TRSH_MASK);
302 writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
305 setbits_le32(&power_regs->hw_power_5vctrl,
306 POWER_5VCTRL_DCDC_XFER);
308 clrbits_le32(&power_regs->hw_power_5vctrl,
309 POWER_5VCTRL_DCDC_XFER);
311 setbits_le32(&power_regs->hw_power_5vctrl,
312 POWER_5VCTRL_ENABLE_DCDC);
314 setbits_le32(&power_regs->hw_power_dcdc4p2,
315 POWER_DCDC4P2_ENABLE_DCDC);
320 clrsetbits_le32(&power_regs->hw_power_5vctrl,
321 POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
324 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
327 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
329 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
330 writel(POWER_CTRL_VBUS_VALID_IRQ,
331 &power_regs->hw_power_ctrl_clr);
333 if (prev_5v_brnout) {
334 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
335 &power_regs->hw_power_5vctrl_set);
336 writel(POWER_RESET_UNLOCK_KEY,
337 &power_regs->hw_power_reset);
339 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
340 &power_regs->hw_power_5vctrl_clr);
341 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
342 &power_regs->hw_power_reset);
345 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
346 writel(POWER_CTRL_VDD5V_DROOP_IRQ,
347 &power_regs->hw_power_ctrl_clr);
350 setbits_le32(&power_regs->hw_power_ctrl,
351 POWER_CTRL_ENIRQ_VDD5V_DROOP);
353 clrbits_le32(&power_regs->hw_power_ctrl,
354 POWER_CTRL_ENIRQ_VDD5V_DROOP);
357 __static void mx28_power_init_4p2_regulator(void)
359 struct mx28_power_regs *power_regs =
360 (struct mx28_power_regs *)MXS_POWER_BASE;
363 dprintf("%s@%d: \n", __func__, __LINE__);
364 setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
366 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
368 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
369 &power_regs->hw_power_5vctrl_clr);
370 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
372 /* Power up the 4p2 rail and logic/control */
373 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
374 &power_regs->hw_power_5vctrl_clr);
377 * Start charging up the 4p2 capacitor. We ramp of this charge
378 * gradually to avoid large inrush current from the 5V cable which can
379 * cause transients/problems
381 mx28_enable_4p2_dcdc_input(0);
383 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
385 * If we arrived here, we were unable to recover from mx23 chip
386 * errata 5837. 4P2 is disabled and sufficient battery power is
387 * not present. Exiting to not enable DCDC power during 5V
390 clrbits_le32(&power_regs->hw_power_dcdc4p2,
391 POWER_DCDC4P2_ENABLE_DCDC);
392 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
393 &power_regs->hw_power_5vctrl_set);
398 * Here we set the 4p2 brownout level to something very close to 4.2V.
399 * We then check the brownout status. If the brownout status is false,
400 * the voltage is already close to the target voltage of 4.2V so we
401 * can go ahead and set the 4P2 current limit to our max target limit.
402 * If the brownout status is true, we need to ramp us the current limit
403 * so that we don't cause large inrush current issues. We step up the
404 * current limit until the brownout status is false or until we've
405 * reached our maximum defined 4p2 current limit.
407 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
408 POWER_DCDC4P2_BO_MASK,
409 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
411 if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
412 setbits_le32(&power_regs->hw_power_5vctrl,
413 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
415 tmp = (readl(&power_regs->hw_power_5vctrl) &
416 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
417 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
419 if (!(readl(&power_regs->hw_power_sts) &
420 POWER_STS_DCDC_4P2_BO)) {
421 tmp = readl(&power_regs->hw_power_5vctrl);
422 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
424 writel(tmp, &power_regs->hw_power_5vctrl);
428 tmp2 = readl(&power_regs->hw_power_5vctrl);
429 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
431 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
432 writel(tmp2, &power_regs->hw_power_5vctrl);
438 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
439 writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
442 __static void mx28_power_init_dcdc_4p2_source(void)
444 struct mx28_power_regs *power_regs =
445 (struct mx28_power_regs *)MXS_POWER_BASE;
447 dprintf("%s@%d: \n", __func__, __LINE__);
448 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
449 if (!(readl(&power_regs->hw_power_dcdc4p2) &
450 POWER_DCDC4P2_ENABLE_DCDC)) {
454 mx28_enable_4p2_dcdc_input(1);
456 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
457 clrbits_le32(&power_regs->hw_power_dcdc4p2,
458 POWER_DCDC4P2_ENABLE_DCDC);
459 writel(POWER_5VCTRL_ENABLE_DCDC,
460 &power_regs->hw_power_5vctrl_clr);
461 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
462 &power_regs->hw_power_5vctrl_set);
465 clrbits_le32(&power_regs->hw_power_dcdc4p2,
466 POWER_DCDC4P2_ENABLE_4P2 | POWER_DCDC4P2_ENABLE_DCDC);
470 __static void mx28_power_enable_4p2(void)
472 struct mx28_power_regs *power_regs =
473 (struct mx28_power_regs *)MXS_POWER_BASE;
474 uint32_t vdddctrl, vddactrl, vddioctrl;
477 dprintf("%s@%d: \n", __func__, __LINE__);
478 vdddctrl = readl(&power_regs->hw_power_vdddctrl);
479 vddactrl = readl(&power_regs->hw_power_vddactrl);
480 vddioctrl = readl(&power_regs->hw_power_vddioctrl);
482 setbits_le32(&power_regs->hw_power_vdddctrl,
483 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
484 POWER_VDDDCTRL_PWDN_BRNOUT);
486 setbits_le32(&power_regs->hw_power_vddactrl,
487 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
488 POWER_VDDACTRL_PWDN_BRNOUT);
490 setbits_le32(&power_regs->hw_power_vddioctrl,
491 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
493 mx28_power_init_4p2_params();
494 mx28_power_init_4p2_regulator();
496 /* Shutdown battery (none present) */
497 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
498 writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
499 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
501 mx28_power_init_dcdc_4p2_source();
503 readl(&power_regs->hw_power_vdddctrl);
504 readl(&power_regs->hw_power_vddactrl);
505 readl(&power_regs->hw_power_vddioctrl);
506 writel(vdddctrl, &power_regs->hw_power_vdddctrl);
508 memdump(0x80044000, 0x60);
509 writel(vddactrl, &power_regs->hw_power_vddactrl);
511 writel(vddioctrl, &power_regs->hw_power_vddioctrl);
514 * Check if FET is enabled on either powerout and if so,
518 tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
519 POWER_VDDDCTRL_DISABLE_FET);
520 tmp |= !(readl(&power_regs->hw_power_vddactrl) &
521 POWER_VDDACTRL_DISABLE_FET);
522 tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
523 POWER_VDDIOCTRL_DISABLE_FET);
525 writel(POWER_CHARGE_ENABLE_LOAD,
526 &power_regs->hw_power_charge_clr);
529 __static void mx28_boot_valid_5v(void)
531 struct mx28_power_regs *power_regs =
532 (struct mx28_power_regs *)MXS_POWER_BASE;
534 dprintf("%s@%d: \n", __func__, __LINE__);
536 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
537 * disconnect event. FIXME
539 writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
540 &power_regs->hw_power_5vctrl_set);
542 /* Configure polarity to check for 5V disconnection. */
543 writel(POWER_CTRL_POLARITY_VBUSVALID |
544 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
545 &power_regs->hw_power_ctrl_clr);
547 writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
548 &power_regs->hw_power_ctrl_clr);
550 mx28_power_enable_4p2();
553 void mx28_powerdown(void)
555 struct mx28_power_regs *power_regs =
556 (struct mx28_power_regs *)MXS_POWER_BASE;
558 dprintf("%s@%d: \n", __func__, __LINE__);
559 writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
560 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
561 &power_regs->hw_power_reset);
564 __static inline void mx28_handle_5v_conflict(void)
566 struct mx28_power_regs *power_regs =
567 (struct mx28_power_regs *)MXS_POWER_BASE;
570 dprintf("%s@%d: \n", __func__, __LINE__);
571 setbits_le32(&power_regs->hw_power_vddioctrl,
572 POWER_VDDIOCTRL_BO_OFFSET_MASK);
575 tmp = readl(&power_regs->hw_power_sts);
577 if (tmp & POWER_STS_VDDIO_BO) {
582 if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
583 mx28_boot_valid_5v();
592 __static int mx28_get_batt_volt(void)
594 struct mx28_power_regs *power_regs =
595 (struct mx28_power_regs *)MXS_POWER_BASE;
596 uint32_t volt = readl(&power_regs->hw_power_battmonitor);
598 dprintf("%s@%d: \n", __func__, __LINE__);
599 volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
600 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
605 #define __maybe_unused __attribute__((unused))
607 __static int __maybe_unused mx28_is_batt_ready(void)
609 dprintf("%s@%d: \n", __func__, __LINE__);
610 return (mx28_get_batt_volt() >= 3600);
613 __static void mx28_5v_boot(void)
615 struct mx28_power_regs *power_regs =
616 (struct mx28_power_regs *)MXS_POWER_BASE;
618 dprintf("%s@%d: \n", __func__, __LINE__);
619 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
621 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
622 * but their implementation always returns 1 so we omit it here.
624 if (mx28_power_vdd5v_gt_vddio()) {
625 mx28_boot_valid_5v();
630 if (mx28_power_vdd5v_gt_vddio()) {
631 mx28_boot_valid_5v();
635 mx28_handle_5v_conflict();
637 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
638 writel(1 << POWER_5VCTRL_PWD_CHARGE_4P2_OFFSET, &power_regs->hw_power_5vctrl_set);
640 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
641 POWER_VDDDCTRL_DISABLE_FET,
642 POWER_VDDDCTRL_ENABLE_LINREG |
643 POWER_VDDDCTRL_DISABLE_STEPPING);
647 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
648 #define BATT_BO_VALUE 15
650 /* Brownout at 3.08V */
651 #define BATT_BO_VALUE 17
654 __static void mx28_init_batt_bo(void)
656 struct mx28_power_regs *power_regs =
657 (struct mx28_power_regs *)MXS_POWER_BASE;
659 dprintf("%s@%d: \n", __func__, __LINE__);
660 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
662 clrsetbits_le32(&power_regs->hw_power_battmonitor,
663 POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
664 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
666 writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
667 writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
669 clrbits_le32(&power_regs->hw_power_battmonitor,
670 POWER_BATTMONITOR_PWDN_BATTBRNOUT);
671 writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
675 __static void mx28_switch_vddd_to_dcdc_source(void)
677 struct mx28_power_regs *power_regs =
678 (struct mx28_power_regs *)MXS_POWER_BASE;
680 dprintf("%s@%d: \n", __func__, __LINE__);
681 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
682 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
683 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
685 clrbits_le32(&power_regs->hw_power_vdddctrl,
686 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
687 POWER_VDDDCTRL_DISABLE_STEPPING);
690 __static int __maybe_unused mx28_is_batt_good(void)
692 struct mx28_power_regs *power_regs =
693 (struct mx28_power_regs *)MXS_POWER_BASE;
696 dprintf("%s@%d: \n", __func__, __LINE__);
697 volt = readl(&power_regs->hw_power_battmonitor);
698 volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
699 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
702 if ((volt >= 2400) && (volt <= 4300))
705 clrsetbits_le32(&power_regs->hw_power_5vctrl,
706 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
707 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
708 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
709 &power_regs->hw_power_5vctrl_clr);
711 clrsetbits_le32(&power_regs->hw_power_charge,
712 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
713 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
715 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
716 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
717 &power_regs->hw_power_5vctrl_clr);
721 volt = readl(&power_regs->hw_power_battmonitor);
722 volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
723 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
732 writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
733 &power_regs->hw_power_charge_clr);
734 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
739 __static void mx28_power_configure_power_source(void)
741 dprintf("%s@%d: \n", __func__, __LINE__);
743 mx28_src_power_init();
746 mx28_power_clock2pll();
750 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
751 mx28_switch_vddd_to_dcdc_source();
755 __static void mx28_enable_output_rail_protection(void)
757 struct mx28_power_regs *power_regs =
758 (struct mx28_power_regs *)MXS_POWER_BASE;
760 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
761 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
763 setbits_le32(&power_regs->hw_power_vdddctrl,
764 POWER_VDDDCTRL_PWDN_BRNOUT);
766 setbits_le32(&power_regs->hw_power_vddactrl,
767 POWER_VDDACTRL_PWDN_BRNOUT);
769 setbits_le32(&power_regs->hw_power_vddioctrl,
770 POWER_VDDIOCTRL_PWDN_BRNOUT);
773 __static int mx28_get_vddio_power_source_off(void)
775 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
776 struct mx28_power_regs *power_regs =
777 (struct mx28_power_regs *)MXS_POWER_BASE;
780 dprintf("%s@%d: \n", __func__, __LINE__);
781 if (mx28_power_vdd5v_gt_vddio()) {
782 tmp = readl(&power_regs->hw_power_vddioctrl);
783 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
784 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
785 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
786 dprintf("%s@%d: 1\n", __func__, __LINE__);
791 if (!(readl(&power_regs->hw_power_5vctrl) &
792 POWER_5VCTRL_ENABLE_DCDC)) {
793 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
794 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
795 dprintf("%s@%d: 1\n", __func__, __LINE__);
800 dprintf("%s@%d: 0\n", __func__, __LINE__);
803 dprintf("%s@%d: 1\n", __func__, __LINE__);
808 __static int mx28_get_vddd_power_source_off(void)
810 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
811 struct mx28_power_regs *power_regs =
812 (struct mx28_power_regs *)MXS_POWER_BASE;
815 dprintf("%s@%d: \n", __func__, __LINE__);
816 tmp = readl(&power_regs->hw_power_vdddctrl);
817 if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
818 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
819 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
820 dprintf("%s@%d: 1\n", __func__, __LINE__);
825 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
826 if (!(readl(&power_regs->hw_power_5vctrl) &
827 POWER_5VCTRL_ENABLE_DCDC)) {
828 dprintf("%s@%d: 1\n", __func__, __LINE__);
833 if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
834 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
835 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
836 dprintf("%s@%d: 1\n", __func__, __LINE__);
840 dprintf("%s@%d: 0\n", __func__, __LINE__);
843 dprintf("%s@%d: 1\n", __func__, __LINE__);
848 __static void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
850 struct mx28_power_regs *power_regs =
851 (struct mx28_power_regs *)MXS_POWER_BASE;
852 uint32_t cur_target, diff, bo_int = 0;
853 uint32_t powered_by_linreg;
855 dprintf("%s@%d: \n", __func__, __LINE__);
856 new_brownout = (new_target - new_brownout) / 25;
857 if (new_brownout > 7) {
858 dprintf("Bad VDDD brownout offset\n");
862 cur_target = readl(&power_regs->hw_power_vddioctrl);
863 cur_target &= POWER_VDDIOCTRL_TRG_MASK;
864 cur_target *= 50; /* 50 mV step*/
865 cur_target += 2800; /* 2800 mV lowest */
867 powered_by_linreg = mx28_get_vddio_power_source_off();
868 if (new_target != cur_target)
869 dprintf("%s@%d: stepping VDDIO from %u to %u\n", __func__, __LINE__,
870 cur_target, new_target);
872 dprintf("%s@%d: VDDIO is at %u\n", __func__, __LINE__,
873 cur_target, new_target);
874 if (new_target > cur_target) {
876 if (powered_by_linreg) {
877 bo_int = readl(&power_regs->hw_power_vddioctrl);
878 clrbits_le32(&power_regs->hw_power_vddioctrl,
879 POWER_CTRL_ENIRQ_VDDIO_BO);
882 setbits_le32(&power_regs->hw_power_vddioctrl,
883 POWER_VDDIOCTRL_BO_OFFSET_MASK);
885 if (new_target - cur_target > 100)
886 diff = cur_target + 100;
893 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
894 POWER_VDDIOCTRL_TRG_MASK, diff);
895 dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
897 if (powered_by_linreg)
900 while (!(readl(&power_regs->hw_power_sts) &
906 cur_target = readl(&power_regs->hw_power_vddioctrl);
907 cur_target &= POWER_VDDIOCTRL_TRG_MASK;
908 cur_target *= 50; /* 50 mV step*/
909 cur_target += 2800; /* 2800 mV lowest */
910 } while (new_target > cur_target);
912 if (powered_by_linreg) {
913 writel(POWER_CTRL_VDDIO_BO_IRQ,
914 &power_regs->hw_power_ctrl_clr);
915 if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
916 setbits_le32(&power_regs->hw_power_vddioctrl,
917 POWER_CTRL_ENIRQ_VDDIO_BO);
918 dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
920 dprintf("%s@%d: Done\n", __func__, __LINE__);
923 if (cur_target - new_target > 100)
924 diff = cur_target - 100;
931 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
932 POWER_VDDIOCTRL_TRG_MASK, diff);
934 if (powered_by_linreg)
937 while (!(readl(&power_regs->hw_power_sts) &
943 cur_target = readl(&power_regs->hw_power_vddioctrl);
944 cur_target &= POWER_VDDIOCTRL_TRG_MASK;
945 cur_target *= 50; /* 50 mV step*/
946 cur_target += 2800; /* 2800 mV lowest */
947 } while (new_target < cur_target);
948 dprintf("%s@%d: Done\n", __func__, __LINE__);
951 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
952 POWER_VDDDCTRL_BO_OFFSET_MASK,
953 new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
954 dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
957 __static void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
959 struct mx28_power_regs *power_regs =
960 (struct mx28_power_regs *)MXS_POWER_BASE;
961 uint32_t cur_target, diff, bo_int = 0;
962 uint32_t powered_by_linreg;
964 dprintf("%s@%d: \n", __func__, __LINE__);
965 new_brownout = (new_target - new_brownout) / 25;
966 if (new_brownout > 7) {
967 dprintf("Bad VDDD brownout offset\n");
970 cur_target = readl(&power_regs->hw_power_vdddctrl);
971 cur_target &= POWER_VDDDCTRL_TRG_MASK;
972 cur_target *= 25; /* 25 mV step*/
973 cur_target += 800; /* 800 mV lowest */
975 powered_by_linreg = mx28_get_vddd_power_source_off();
976 if (new_target != cur_target)
977 dprintf("%s@%d: stepping VDDD from %u to %u\n", __func__, __LINE__,
978 cur_target, new_target);
980 dprintf("%s@%d: VDDD is at %u\n", __func__, __LINE__,
981 cur_target, new_target);
982 if (new_target > cur_target) {
983 if (powered_by_linreg) {
984 bo_int = readl(&power_regs->hw_power_vdddctrl);
985 clrbits_le32(&power_regs->hw_power_vdddctrl,
986 POWER_CTRL_ENIRQ_VDDD_BO);
989 setbits_le32(&power_regs->hw_power_vdddctrl,
990 POWER_VDDDCTRL_BO_OFFSET_MASK);
993 if (new_target - cur_target > 100)
994 diff = cur_target + 100;
1001 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1002 POWER_VDDDCTRL_TRG_MASK, diff);
1004 if (powered_by_linreg)
1007 while (!(readl(&power_regs->hw_power_sts) &
1013 cur_target = readl(&power_regs->hw_power_vdddctrl);
1014 cur_target &= POWER_VDDDCTRL_TRG_MASK;
1015 cur_target *= 25; /* 25 mV step*/
1016 cur_target += 800; /* 800 mV lowest */
1017 } while (new_target > cur_target);
1019 if (powered_by_linreg) {
1020 writel(POWER_CTRL_VDDD_BO_IRQ,
1021 &power_regs->hw_power_ctrl_clr);
1022 if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
1023 setbits_le32(&power_regs->hw_power_vdddctrl,
1024 POWER_CTRL_ENIRQ_VDDD_BO);
1026 dprintf("%s@%d: Done\n", __func__, __LINE__);
1029 if (cur_target - new_target > 100)
1030 diff = cur_target - 100;
1037 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1038 POWER_VDDDCTRL_TRG_MASK, diff);
1040 if (powered_by_linreg)
1043 while (!(readl(&power_regs->hw_power_sts) &
1049 cur_target = readl(&power_regs->hw_power_vdddctrl);
1050 cur_target &= POWER_VDDDCTRL_TRG_MASK;
1051 cur_target *= 25; /* 25 mV step*/
1052 cur_target += 800; /* 800 mV lowest */
1053 } while (new_target < cur_target);
1054 dprintf("%s@%d: Done\n", __func__, __LINE__);
1057 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1058 POWER_VDDDCTRL_BO_OFFSET_MASK,
1059 new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
1062 void mx28_power_init(void)
1064 struct mx28_power_regs *power_regs =
1065 (struct mx28_power_regs *)MXS_POWER_BASE;
1067 dprintf("%s: %s %s\n", __func__, __DATE__, __TIME__);
1068 dprintf("ctrl=%x\n", readl(&power_regs->hw_power_ctrl));
1069 dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
1070 #ifdef CONFIG_SPL_FIXED_BATT_SUPPLY_
1071 writel(0x00018024, &power_regs->hw_power_ctrl);
1072 writel(0x20100592, &power_regs->hw_power_5vctrl);
1073 writel(0x00000018, &power_regs->hw_power_dcdc4p2);
1074 writel(0x0061071c, &power_regs->hw_power_vdddctrl);
1075 writel(0x0000270c, &power_regs->hw_power_vddactrl);
1076 writel(0x0004260a, &power_regs->hw_power_vddioctrl);
1078 dprintf("%s@%d\n", __func__, __LINE__);
1079 mx28_power_clock2xtal();
1080 dprintf("%s@%d\n", __func__, __LINE__);
1081 mx28_power_clear_auto_restart();
1082 dprintf("%s@%d\n", __func__, __LINE__);
1083 mx28_power_set_linreg();
1084 dprintf("%s@%d\n", __func__, __LINE__);
1085 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
1086 mx28_power_setup_5v_detect();
1087 dprintf("%s@%d\n", __func__, __LINE__);
1088 mx28_power_configure_power_source();
1089 // dprintf("%s@%d\n", __func__, __LINE__);
1090 // mx28_enable_output_rail_protection();
1091 dprintf("%s@%d\n", __func__, __LINE__);
1093 mx28_power_set_vddio(3300, 3150);
1094 dprintf("%s@%d\n", __func__, __LINE__);
1096 mx28_power_set_vddd(1500, 1325);
1097 dprintf("%s@%d\n", __func__, __LINE__);
1099 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1100 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1101 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1102 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1104 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
1105 writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
1109 dprintf("%s@%d\n", __func__, __LINE__);
1110 mx28_src_power_init();
1111 dprintf("%s@%d\n", __func__, __LINE__);
1113 dprintf("%s@%d\n", __func__, __LINE__);
1114 mx28_power_clock2pll();
1115 dprintf("%s@%d\n", __func__, __LINE__);
1116 mx28_init_batt_bo();
1117 dprintf("%s@%d\n", __func__, __LINE__);
1118 mx28_switch_vddd_to_dcdc_source();
1120 dprintf("%s@%d\n", __func__, __LINE__);
1121 mx28_power_set_vddio(3300, 3150);
1123 dprintf("%s@%d\n", __func__, __LINE__);
1124 mx28_power_set_vddd(1500, 1325);
1125 dprintf("%s@%d\n", __func__, __LINE__);
1127 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1128 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1129 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1130 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1133 dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
1134 dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
1135 dprintf("vdddctrl=%x\n", readl(&power_regs->hw_power_vdddctrl));
1136 dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
1137 dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
1138 dprintf("%s@%d: Finished\n", __func__, __LINE__);
1139 memdump(0x80044000, 0x60);
1142 #ifdef CONFIG_SPL_MX28_PSWITCH_WAIT
1143 void mx28_power_wait_pswitch(void)
1145 struct mx28_power_regs *power_regs =
1146 (struct mx28_power_regs *)MXS_POWER_BASE;
1148 dprintf("%s@%d: \n", __func__, __LINE__);
1149 while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))