]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
FIXED_BATT_SUPPLY working!?
authorLothar Waßmann <LW@KARO-electronics.de>
Wed, 14 Mar 2012 18:27:47 +0000 (19:27 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Thu, 15 Mar 2012 09:01:18 +0000 (10:01 +0100)
arch/arm/cpu/arm926ejs/mx28/Makefile
arch/arm/cpu/arm926ejs/mx28/debug.c [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mx28/debug.h [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c

index a2e3f771c26aa9835d4455c4975cf72e191b81a8..cb671837e47bb58f3976a62d3d401ae12e575eef 100644 (file)
@@ -28,7 +28,7 @@ LIB   = $(obj)lib$(SOC).o
 COBJS  = clock.o mx28.o iomux.o timer.o
 
 ifdef  CONFIG_SPL_BUILD
-COBJS  += spl_boot.o spl_mem_init.o spl_power_init.o
+COBJS  += spl_boot.o spl_mem_init.o spl_power_init.o debug.o
 endif
 
 SRCS   := $(START:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/arm926ejs/mx28/debug.c b/arch/arm/cpu/arm926ejs/mx28/debug.c
new file mode 100644 (file)
index 0000000..a88f1af
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Boot Prep common file
+ *
+ * Copyright 2008-2009 Freescale Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <stdarg.h>
+//#include <stdlib.h>
+
+#include <common.h>
+
+void printhex(int data)
+{
+       int i;
+       char c;
+
+       for (i = sizeof(int) * 2 - 1; i >= 0; i--) {
+               c = data >> (i * 4);
+               c &= 0xf;
+               if (c > 9)
+                       serial_putc(c - 10 + 'A');
+               else
+                       serial_putc(c + '0');
+       }
+}
+
+void printdec(int data)
+{
+       unsigned int m;
+       char str[10] = { 0, };
+       int i;
+
+       if (data == 0) {
+               serial_putc('0');
+               return;
+       } else if (data < 0) {
+               serial_putc('-');
+               data = -data;
+       }
+       m = data;
+       for (i = 0; m > 0; i++) {
+               str[i] = m % 10 + '0';
+               m /= 10;
+       }
+       for (i--; i >= 0; i--) {
+               serial_putc(str[i]);
+       }
+}
+
+void dprintf(const char *fmt, ...)
+{
+       va_list args;
+       const char *fp = fmt;
+
+       if (!fmt)
+               return;
+
+       va_start(args, fmt);
+       while (*fp) {
+               if (*fp == '%') {
+                       fp++;
+                       switch (*fp) {
+                       case 'c':
+                               serial_putc(va_arg(args, int));
+                               break;
+
+                       case 's':
+                               serial_puts(va_arg(args, const char *));
+                               break;
+
+                       case 'd':
+                       case 'u':
+                       case 'i':
+                               printdec(va_arg(args, int));
+                               break;
+
+                       case 'p':
+                               serial_puts("0x");
+                       case 'x':
+                       case 'X':
+                               printhex(va_arg(args, int));
+                               break;
+
+                       case '%':
+                               serial_putc('%');
+                               break;
+
+                       default:
+                               dprintf("\nUnsupported format string token '%c'(%x) in '%s'\n",
+                                       *fp, *fp, fmt);
+                       }
+               } else {
+                       if (*fp == '\n')
+                               serial_putc('\r');
+                       serial_putc(*fp);
+               }
+               fp++;
+       }
+       va_end(args);
+}
diff --git a/arch/arm/cpu/arm926ejs/mx28/debug.h b/arch/arm/cpu/arm926ejs/mx28/debug.h
new file mode 100644 (file)
index 0000000..8299142
--- /dev/null
@@ -0,0 +1,3 @@
+extern void printhex(int data);
+extern void printdec(int data);
+extern void dprintf(const char *fmt, ...);
index 380b120dc9c6d1e623f1cf9fa310ad4bfd951448..95a79a749b95e8291930850f5b6ac58038f89f70 100644 (file)
 
 #include "mx28_init.h"
 
-void mx28_power_clock2xtal(void)
+extern void dprintf(const char *fmt, ...);
+
+#undef __arch_getl
+#undef __arch_putl
+
+#define __arch_getl(a) arch_getl(a, __func__, __LINE__)
+static inline unsigned int arch_getl(volatile void *addr,
+                       const char *fn, unsigned int ln)
+{
+       volatile unsigned int *a = addr;
+       unsigned int val = *a;
+       dprintf("%s@%d: Read %x from %p\n", fn, ln, val, addr);
+       return val;
+}
+
+#define __arch_putl(v, a)      arch_putl(v, a, __func__, __LINE__)
+static inline void arch_putl(unsigned int val, volatile void *addr,
+                       const char *fn, unsigned int ln)
+{
+       volatile unsigned int *a = addr;
+
+       dprintf("%s@%d: Writing %x to %p\n", fn, ln, val, addr);
+       *a = val;
+}
+
+#define __static
+
+__static int mx28_power_vdd5v_gt_vddio(void)
+{
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
+       struct mx28_power_regs *power_regs =
+               (struct mx28_power_regs *)MXS_POWER_BASE;
+       int power_sts = readl(&power_regs->hw_power_sts);
+
+       dprintf("%s@%d: 0\n", __func__, __LINE__,
+               !!(power_sts & POWER_STS_VDD5V_GT_VDDIO));
+       return power_sts & POWER_STS_VDD5V_GT_VDDIO;
+#else
+       dprintf("%s@%d: 0\n", __func__, __LINE__);
+       return 0;
+#endif
+}
+
+__static int mx28_power_vbus_valid(void)
+{
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
+       struct mx28_power_regs *power_regs =
+               (struct mx28_power_regs *)MXS_POWER_BASE;
+       int power_5vctrl = readl(&power_regs->hw_power_5vctrl);
+
+       dprintf("%s@%d: 0\n", __func__, __LINE__,
+               !!(power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT));
+       return power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT;
+#else
+       dprintf("%s@%d: 0\n", __func__, __LINE__);
+       return 0;
+#endif
+}
+
+static void memdump(unsigned long addr, unsigned long len)
+{
+       int i;
+       uint32_t *ptr = (void *)addr;
+
+       for (i = 0; i < len; i++) {
+               if (i % 4 == 0)
+                       dprintf("\n%p:", &ptr[i]);
+               dprintf(" %x", ptr[i]);
+       }
+       dprintf("\n");
+}
+
+//#undef CONFIG_SPL_FIXED_BATT_SUPPLY
+
+__static void mx28_power_clock2xtal(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /* Set XTAL as CPU reference clock */
        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 }
 
-void mx28_power_clock2pll(void)
+__static void mx28_power_clock2pll(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        writel(CLKCTRL_PLL0CTRL0_POWER,
                &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
        early_delay(100);
@@ -52,11 +128,12 @@ void mx28_power_clock2pll(void)
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
 }
 
-void mx28_power_clear_auto_restart(void)
+__static void mx28_power_clear_auto_restart(void)
 {
        struct mx28_rtc_regs *rtc_regs =
                (struct mx28_rtc_regs *)MXS_RTC_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
        while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
                ;
@@ -64,7 +141,7 @@ void mx28_power_clear_auto_restart(void)
        writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
        while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
                ;
-
+#ifdef CONFIG_MACH_MX28EVK
        /*
         * Due to the hardware design bug of mx28 EVK-A
         * we need to set the AUTO_RESTART bit.
@@ -83,17 +160,19 @@ void mx28_power_clear_auto_restart(void)
                ;
        while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
                ;
+#endif
 }
 
-void mx28_power_set_linreg(void)
+__static void mx28_power_set_linreg(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /* Set linear regulator 25mV below switching converter */
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
-                       POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+                       POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_ABOVE);
 
        clrsetbits_le32(&power_regs->hw_power_vddactrl,
                        POWER_VDDACTRL_LINREG_OFFSET_MASK,
@@ -102,13 +181,15 @@ void mx28_power_set_linreg(void)
        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
+       dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
 }
 
-void mx28_power_setup_5v_detect(void)
+__static void mx28_power_setup_5v_detect(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /* Start 5V detection */
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
@@ -116,11 +197,12 @@ void mx28_power_setup_5v_detect(void)
                        POWER_5VCTRL_PWRUP_VBUS_CMPS);
 }
 
-void mx28_src_power_init(void)
+__static void mx28_src_power_init(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /* Improve efficieny and reduce transient ripple */
        writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
                POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
@@ -140,18 +222,20 @@ void mx28_src_power_init(void)
 
        clrsetbits_le32(&power_regs->hw_power_minpwr,
                        POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
-
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        /* 5V to battery handoff ... FIXME */
        setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
        early_delay(30);
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+#endif
 }
 
-void mx28_power_init_4p2_params(void)
+__static void mx28_power_init_4p2_params(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -169,15 +253,18 @@ void mx28_power_init_4p2_params(void)
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
                0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+       dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
+       dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
 }
 
-void mx28_enable_4p2_dcdc_input(int xfer)
+__static void mx28_enable_4p2_dcdc_input(int xfer)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
 
+       dprintf("%s@%d: %d\n", __func__, __LINE__, xfer);
        prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
                                POWER_5VCTRL_PWDN_5VBRNOUT;
        prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
@@ -200,7 +287,7 @@ void mx28_enable_4p2_dcdc_input(int xfer)
         */
        tmp = readl(&power_regs->hw_power_5vctrl);
        vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
-       vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
+       vbus_5vdetect = mx28_power_vbus_valid();
 
        pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
 
@@ -260,19 +347,20 @@ void mx28_enable_4p2_dcdc_input(int xfer)
                        &power_regs->hw_power_ctrl_clr);
 
        if (prev_5v_droop)
-               clrbits_le32(&power_regs->hw_power_ctrl,
+               setbits_le32(&power_regs->hw_power_ctrl,
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
        else
-               setbits_le32(&power_regs->hw_power_ctrl,
+               clrbits_le32(&power_regs->hw_power_ctrl,
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
 }
 
-void mx28_power_init_4p2_regulator(void)
+__static void mx28_power_init_4p2_regulator(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, tmp2;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
 
        writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
@@ -351,11 +439,13 @@ void mx28_power_init_4p2_regulator(void)
        writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 }
 
-void mx28_power_init_dcdc_4p2_source(void)
+__static void mx28_power_init_dcdc_4p2_source(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
                hang();
@@ -371,15 +461,20 @@ void mx28_power_init_dcdc_4p2_source(void)
                writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
                        &power_regs->hw_power_5vctrl_set);
        }
+#else
+       clrbits_le32(&power_regs->hw_power_dcdc4p2,
+               POWER_DCDC4P2_ENABLE_4P2 | POWER_DCDC4P2_ENABLE_DCDC);
+#endif
 }
 
-void mx28_power_enable_4p2(void)
+__static void mx28_power_enable_4p2(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        vdddctrl = readl(&power_regs->hw_power_vdddctrl);
        vddactrl = readl(&power_regs->hw_power_vddactrl);
        vddioctrl = readl(&power_regs->hw_power_vddioctrl);
@@ -405,8 +500,12 @@ void mx28_power_enable_4p2(void)
 
        mx28_power_init_dcdc_4p2_source();
 
+       readl(&power_regs->hw_power_vdddctrl);
+       readl(&power_regs->hw_power_vddactrl);
+       readl(&power_regs->hw_power_vddioctrl);
        writel(vdddctrl, &power_regs->hw_power_vdddctrl);
        early_delay(20);
+       memdump(0x80044000, 0x60);
        writel(vddactrl, &power_regs->hw_power_vddactrl);
        early_delay(20);
        writel(vddioctrl, &power_regs->hw_power_vddioctrl);
@@ -427,11 +526,12 @@ void mx28_power_enable_4p2(void)
                        &power_regs->hw_power_charge_clr);
 }
 
-void mx28_boot_valid_5v(void)
+__static void mx28_boot_valid_5v(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
@@ -454,17 +554,20 @@ void mx28_powerdown(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
+
+       dprintf("%s@%d: \n", __func__, __LINE__);
        writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
        writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
                &power_regs->hw_power_reset);
 }
 
-void mx28_handle_5v_conflict(void)
+__static inline void mx28_handle_5v_conflict(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        setbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDIOCTRL_BO_OFFSET_MASK);
 
@@ -486,50 +589,75 @@ void mx28_handle_5v_conflict(void)
        }
 }
 
-int mx28_get_batt_volt(void)
+__static int mx28_get_batt_volt(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t volt = readl(&power_regs->hw_power_battmonitor);
+
+       dprintf("%s@%d: \n", __func__, __LINE__);
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
        volt *= 8;
        return volt;
 }
 
-int mx28_is_batt_ready(void)
+#define __maybe_unused __attribute__((unused))
+
+__static int __maybe_unused mx28_is_batt_ready(void)
 {
+       dprintf("%s@%d: \n", __func__, __LINE__);
        return (mx28_get_batt_volt() >= 3600);
 }
 
-void mx28_5v_boot(void)
+__static void mx28_5v_boot(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        /*
         * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
         * but their implementation always returns 1 so we omit it here.
         */
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       if (mx28_power_vdd5v_gt_vddio()) {
                mx28_boot_valid_5v();
                return;
        }
 
        early_delay(1000);
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       if (mx28_power_vdd5v_gt_vddio()) {
                mx28_boot_valid_5v();
                return;
        }
 
        mx28_handle_5v_conflict();
+#else
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+       writel(1 << POWER_5VCTRL_PWD_CHARGE_4P2_OFFSET, &power_regs->hw_power_5vctrl_set);
+
+       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
+                       POWER_VDDDCTRL_DISABLE_FET,
+                       POWER_VDDDCTRL_ENABLE_LINREG |
+                       POWER_VDDDCTRL_DISABLE_STEPPING);
+#endif
 }
 
-void mx28_init_batt_bo(void)
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
+#define BATT_BO_VALUE  15
+#else
+/* Brownout at 3.08V */
+#define BATT_BO_VALUE  17
+#endif
+
+__static void mx28_init_batt_bo(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        /* Brownout at 3V */
        clrsetbits_le32(&power_regs->hw_power_battmonitor,
                POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
@@ -537,13 +665,19 @@ void mx28_init_batt_bo(void)
 
        writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+#else
+       clrbits_le32(&power_regs->hw_power_battmonitor,
+               POWER_BATTMONITOR_PWDN_BATTBRNOUT);
+       writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+#endif
 }
 
-void mx28_switch_vddd_to_dcdc_source(void)
+__static void mx28_switch_vddd_to_dcdc_source(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -553,12 +687,13 @@ void mx28_switch_vddd_to_dcdc_source(void)
                POWER_VDDDCTRL_DISABLE_STEPPING);
 }
 
-int mx28_is_batt_good(void)
+__static int __maybe_unused mx28_is_batt_good(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t volt;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        volt = readl(&power_regs->hw_power_battmonitor);
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
@@ -601,46 +736,54 @@ int mx28_is_batt_good(void)
        return 0;
 }
 
-void mx28_power_configure_power_source(void)
+__static void mx28_power_configure_power_source(void)
 {
-       mx28_src_power_init();
+       dprintf("%s@%d: \n", __func__, __LINE__);
 
+       mx28_src_power_init();
        mx28_5v_boot();
+
        mx28_power_clock2pll();
 
        mx28_init_batt_bo();
+
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
        mx28_switch_vddd_to_dcdc_source();
+#endif
 }
 
-void mx28_enable_output_rail_protection(void)
+__static void mx28_enable_output_rail_protection(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-
+#if 0
        setbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_PWDN_BRNOUT);
 
        setbits_le32(&power_regs->hw_power_vddactrl,
                        POWER_VDDACTRL_PWDN_BRNOUT);
-
+#endif
        setbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDIOCTRL_PWDN_BRNOUT);
 }
 
-int mx28_get_vddio_power_source_off(void)
+__static int mx28_get_vddio_power_source_off(void)
 {
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       dprintf("%s@%d: \n", __func__, __LINE__);
+       if (mx28_power_vdd5v_gt_vddio()) {
                tmp = readl(&power_regs->hw_power_vddioctrl);
                if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
                        if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
                                POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
+                               dprintf("%s@%d: 1\n", __func__, __LINE__);
                                return 1;
                        }
                }
@@ -649,25 +792,32 @@ int mx28_get_vddio_power_source_off(void)
                        POWER_5VCTRL_ENABLE_DCDC)) {
                        if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
                                POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
+                               dprintf("%s@%d: 1\n", __func__, __LINE__);
                                return 1;
                        }
                }
        }
-
+       dprintf("%s@%d: 0\n", __func__, __LINE__);
        return 0;
-
+#else
+       dprintf("%s@%d: 1\n", __func__, __LINE__);
+       return 1;
+#endif
 }
 
-int mx28_get_vddd_power_source_off(void)
+__static int mx28_get_vddd_power_source_off(void)
 {
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        tmp = readl(&power_regs->hw_power_vdddctrl);
        if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
                if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
                        POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
+                       dprintf("%s@%d: 1\n", __func__, __LINE__);
                        return 1;
                }
        }
@@ -675,6 +825,7 @@ int mx28_get_vddd_power_source_off(void)
        if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
                if (!(readl(&power_regs->hw_power_5vctrl) &
                        POWER_5VCTRL_ENABLE_DCDC)) {
+                       dprintf("%s@%d: 1\n", __func__, __LINE__);
                        return 1;
                }
        }
@@ -682,21 +833,31 @@ int mx28_get_vddd_power_source_off(void)
        if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
                if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
                        POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
+                       dprintf("%s@%d: 1\n", __func__, __LINE__);
                        return 1;
                }
        }
-
+       dprintf("%s@%d: 0\n", __func__, __LINE__);
        return 0;
+#else
+       dprintf("%s@%d: 1\n", __func__, __LINE__);
+       return 1;
+#endif
 }
 
-void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
+__static void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
+       uint32_t powered_by_linreg;
 
-       new_brownout = new_target - new_brownout;
+       dprintf("%s@%d: \n", __func__, __LINE__);
+       new_brownout = (new_target - new_brownout) / 25;
+       if (new_brownout > 7) {
+               dprintf("Bad VDDD brownout offset\n");
+               new_brownout = 7;
+       }
 
        cur_target = readl(&power_regs->hw_power_vddioctrl);
        cur_target &= POWER_VDDIOCTRL_TRG_MASK;
@@ -704,6 +865,12 @@ void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
        cur_target += 2800;     /* 2800 mV lowest */
 
        powered_by_linreg = mx28_get_vddio_power_source_off();
+       if (new_target != cur_target)
+               dprintf("%s@%d: stepping VDDIO from %u to %u\n", __func__, __LINE__,
+                       cur_target, new_target);
+       else
+               dprintf("%s@%d: VDDIO is at %u\n", __func__, __LINE__,
+                       cur_target, new_target);
        if (new_target > cur_target) {
 
                if (powered_by_linreg) {
@@ -725,6 +892,7 @@ void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
 
                        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
                                POWER_VDDIOCTRL_TRG_MASK, diff);
+                       dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
 
                        if (powered_by_linreg)
                                early_delay(1500);
@@ -747,7 +915,9 @@ void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
                        if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
                                setbits_le32(&power_regs->hw_power_vddioctrl,
                                                POWER_CTRL_ENIRQ_VDDIO_BO);
+                       dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
                }
+               dprintf("%s@%d: Done\n", __func__, __LINE__);
        } else {
                do {
                        if (cur_target - new_target > 100)
@@ -775,28 +945,40 @@ void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
                        cur_target *= 50;       /* 50 mV step*/
                        cur_target += 2800;     /* 2800 mV lowest */
                } while (new_target < cur_target);
+               dprintf("%s@%d: Done\n", __func__, __LINE__);
        }
 
        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDDCTRL_BO_OFFSET_MASK,
                        new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+                       dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
 }
 
-void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
+__static void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
-
-       new_brownout = new_target - new_brownout;
+       uint32_t powered_by_linreg;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
+       new_brownout = (new_target - new_brownout) / 25;
+       if (new_brownout > 7) {
+               dprintf("Bad VDDD brownout offset\n");
+               new_brownout = 7;
+       }
        cur_target = readl(&power_regs->hw_power_vdddctrl);
        cur_target &= POWER_VDDDCTRL_TRG_MASK;
        cur_target *= 25;       /* 25 mV step*/
        cur_target += 800;      /* 800 mV lowest */
 
        powered_by_linreg = mx28_get_vddd_power_source_off();
+       if (new_target != cur_target)
+               dprintf("%s@%d: stepping VDDD from %u to %u\n", __func__, __LINE__,
+                       cur_target, new_target);
+       else
+               dprintf("%s@%d: VDDD is at %u\n", __func__, __LINE__,
+                       cur_target, new_target);
        if (new_target > cur_target) {
                if (powered_by_linreg) {
                        bo_int = readl(&power_regs->hw_power_vdddctrl);
@@ -841,6 +1023,7 @@ void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
                                setbits_le32(&power_regs->hw_power_vdddctrl,
                                                POWER_CTRL_ENIRQ_VDDD_BO);
                }
+               dprintf("%s@%d: Done\n", __func__, __LINE__);
        } else {
                do {
                        if (cur_target - new_target > 100)
@@ -868,6 +1051,7 @@ void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
                        cur_target *= 25;       /* 25 mV step*/
                        cur_target += 800;      /* 800 mV lowest */
                } while (new_target < cur_target);
+               dprintf("%s@%d: Done\n", __func__, __LINE__);
        }
 
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
@@ -880,25 +1064,79 @@ void mx28_power_init(void)
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s: %s %s\n", __func__, __DATE__, __TIME__);
+       dprintf("ctrl=%x\n", readl(&power_regs->hw_power_ctrl));
+       dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
+#ifdef CONFIG_SPL_FIXED_BATT_SUPPLY_
+       writel(0x00018024, &power_regs->hw_power_ctrl);
+       writel(0x20100592, &power_regs->hw_power_5vctrl);
+       writel(0x00000018, &power_regs->hw_power_dcdc4p2);
+       writel(0x0061071c, &power_regs->hw_power_vdddctrl);
+       writel(0x0000270c, &power_regs->hw_power_vddactrl);
+       writel(0x0004260a, &power_regs->hw_power_vddioctrl);
+#else
+       dprintf("%s@%d\n", __func__, __LINE__);
        mx28_power_clock2xtal();
+       dprintf("%s@%d\n", __func__, __LINE__);
        mx28_power_clear_auto_restart();
+       dprintf("%s@%d\n", __func__, __LINE__);
        mx28_power_set_linreg();
+       dprintf("%s@%d\n", __func__, __LINE__);
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        mx28_power_setup_5v_detect();
+       dprintf("%s@%d\n", __func__, __LINE__);
        mx28_power_configure_power_source();
-       mx28_enable_output_rail_protection();
+//     dprintf("%s@%d\n", __func__, __LINE__);
+//     mx28_enable_output_rail_protection();
+       dprintf("%s@%d\n", __func__, __LINE__);
 
        mx28_power_set_vddio(3300, 3150);
+       dprintf("%s@%d\n", __func__, __LINE__);
 
-       mx28_power_set_vddd(1350, 1200);
+       mx28_power_set_vddd(1500, 1325);
+       dprintf("%s@%d\n", __func__, __LINE__);
 
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
                POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
                POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 
+#ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
        writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
-
+#endif
        early_delay(1000);
+#else
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_src_power_init();
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_5v_boot();
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_power_clock2pll();
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_init_batt_bo();
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_switch_vddd_to_dcdc_source();
+
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_power_set_vddio(3300, 3150);
+
+       dprintf("%s@%d\n", __func__, __LINE__);
+       mx28_power_set_vddd(1500, 1325);
+       dprintf("%s@%d\n", __func__, __LINE__);
+
+       writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
+               POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
+               POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
+               POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+#endif
+#endif
+       dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
+       dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
+       dprintf("vdddctrl=%x\n", readl(&power_regs->hw_power_vdddctrl));
+       dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
+       dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
+       dprintf("%s@%d: Finished\n", __func__, __LINE__);
+       memdump(0x80044000, 0x60);
 }
 
 #ifdef CONFIG_SPL_MX28_PSWITCH_WAIT
@@ -907,6 +1145,7 @@ void mx28_power_wait_pswitch(void)
        struct mx28_power_regs *power_regs =
                (struct mx28_power_regs *)MXS_POWER_BASE;
 
+       dprintf("%s@%d: \n", __func__, __LINE__);
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
 }