]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
mxs: spl: remove duplicate debug messages
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mxs / spl_power_init.c
index 8fc08afbca64a1e74748061ad886c90c3577e559..561c04db279f9161979fb23e310d3c7c295a46c0 100644 (file)
 
 #include "mxs_init.h"
 
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+                               POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
+#else
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+                               POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
+#endif
 #ifdef CONFIG_SYS_SPL_VDDD_VAL
 #define VDDD_VAL       CONFIG_SYS_SPL_VDDD_VAL
 #else
@@ -86,6 +93,8 @@ static void mxs_power_clock2xtal(void)
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
+       debug("SPL: Switching CPU clock to 24MHz XTAL\n");
+
        /* Set XTAL as CPU reference clock */
        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
                &clkctrl_regs->hw_clkctrl_clkseq_set);
@@ -103,9 +112,23 @@ static void mxs_power_clock2pll(void)
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
+       debug("SPL: Switching CPU core clock source to PLL\n");
+
+       /*
+        * TODO: Are we really? It looks like we turn on PLL0, but we then
+        * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already
+        * set by mxs_power_clock2xtal()). Clearing this bit here seems to
+        * introduce some instability (causing the CPU core to hang). Maybe
+        * we aren't giving PLL0 enough time to stabilise?
+        */
        setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
                        CLKCTRL_PLL0CTRL0_POWER);
        early_delay(100);
+
+       /*
+        * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a
+        * wait on the PLL0 LOCK bit?
+        */
        setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
@@ -134,6 +157,8 @@ static int mxs_power_set_auto_restart(int on)
 {
        struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
 
+       debug("SPL: Setting auto-restart bit\n");
+
        if (mxs_power_wait_rtc_stat(RTC_STAT_STALE_REGS_PERSISTENT0))
                return 1;
 
@@ -168,14 +193,17 @@ static int mxs_power_set_auto_restart(int on)
 static void mxs_power_set_linreg(void)
 {
        /* Set linear regulator 25mV below switching converter */
+       debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                        POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
 
+       debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
        clrsetbits_le32(&power_regs->hw_power_vddactrl,
                        POWER_VDDACTRL_LINREG_OFFSET_MASK,
                        POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
 
+       debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -193,6 +221,8 @@ static int mxs_get_batt_volt(void)
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
        volt *= 8;
+
+       debug("SPL: Battery Voltage = %dmV\n", volt);
        return volt;
 }
 
@@ -218,8 +248,10 @@ static int mxs_is_batt_good(void)
 {
        uint32_t volt = mxs_get_batt_volt();
 
-       if ((volt >= 2400) && (volt <= 4300))
+       if ((volt >= 2400) && (volt <= 4300)) {
+               debug("SPL: Battery is good\n");
                return 1;
+       }
 
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
@@ -239,6 +271,16 @@ static int mxs_is_batt_good(void)
 
        volt = mxs_get_batt_volt();
 
+       if (volt >= 3500) {
+               debug("SPL: Battery Voltage too high\n");
+               return 0;
+       }
+
+       if (volt >= 2400) {
+               debug("SPL: Battery is good\n");
+               return 1;
+       }
+
        writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
                &power_regs->hw_power_charge_clr);
        writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
@@ -249,6 +291,7 @@ static int mxs_is_batt_good(void)
        if (volt >= 2400) {
                return 1;
        }
+       debug("SPL: Battery Voltage too low\n");
        return 0;
 }
 
@@ -264,6 +307,7 @@ static int mxs_is_batt_good(void)
 static void mxs_power_setup_5v_detect(void)
 {
        /* Start 5V detection */
+       debug("SPL: Starting 5V input detection comparator\n");
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
                        POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
@@ -278,6 +322,8 @@ static void mxs_power_setup_5v_detect(void)
  */
 static void mxs_src_power_init(void)
 {
+       debug("SPL: Pre-Configuring power block\n");
+
        /* 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);
@@ -320,6 +366,8 @@ static void mxs_src_power_init(void)
  */
 static void mxs_power_init_4p2_params(void)
 {
+       debug("SPL: Configuring common 4P2 regulator params\n");
+
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -331,8 +379,7 @@ static void mxs_power_init_4p2_params(void)
 
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_DROPOUT_CTRL_MASK,
-               POWER_DCDC4P2_DROPOUT_CTRL_100MV |
-               POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
+               DCDC4P2_DROPOUT_CONFIG);
 
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
@@ -350,6 +397,13 @@ static void mxs_enable_4p2_dcdc_input(int xfer)
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
 
+       debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
+
+       if (xfer && (readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+               return;
+       }
+
        prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
                                POWER_5VCTRL_PWDN_5VBRNOUT;
        prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
@@ -361,11 +415,6 @@ static void mxs_enable_4p2_dcdc_input(int xfer)
 
        clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
 
-       if (xfer && (readl(&power_regs->hw_power_5vctrl) &
-                       POWER_5VCTRL_ENABLE_DCDC)) {
-               return;
-       }
-
        /*
         * Recording orignal values that will be modified temporarlily
         * to handle a chip bug. See chip errata for CQ ENGR00115837
@@ -449,6 +498,8 @@ static void mxs_power_init_4p2_regulator(void)
 {
        uint32_t tmp, tmp2;
 
+       debug("SPL: Enabling 4P2 regulator\n");
+
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
 
        writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
@@ -466,6 +517,7 @@ static void mxs_power_init_4p2_regulator(void)
         * gradually to avoid large inrush current from the 5V cable which can
         * cause transients/problems
         */
+       debug("SPL: Charging 4P2 capacitor\n");
        mxs_enable_4p2_dcdc_input(0);
 
        if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
@@ -479,6 +531,8 @@ static void mxs_power_init_4p2_regulator(void)
                        POWER_DCDC4P2_ENABLE_DCDC);
                writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
                        &power_regs->hw_power_5vctrl_set);
+
+               debug("SPL: Unable to recover from mx23 errata 5837\n");
                hang();
        }
 
@@ -492,6 +546,7 @@ static void mxs_power_init_4p2_regulator(void)
         * current limit until the brownout status is false or until we've
         * reached our maximum defined 4p2 current limit.
         */
+       debug("SPL: Setting 4P2 brownout level\n");
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                        POWER_DCDC4P2_BO_MASK,
                        22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
@@ -535,8 +590,11 @@ static void mxs_power_init_4p2_regulator(void)
  */
 static void mxs_power_init_dcdc_4p2_source(void)
 {
+       debug("SPL: Switching DC-DC converters to 4P2\n");
+
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
+               debug("SPL: Already switched - aborting\n");
                hang();
        }
 
@@ -563,6 +621,8 @@ static void mxs_power_enable_4p2(void)
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
 
+       debug("SPL: Powering up 4P2 regulator\n");
+
        vdddctrl = readl(&power_regs->hw_power_vdddctrl);
        vddactrl = readl(&power_regs->hw_power_vddactrl);
        vddioctrl = readl(&power_regs->hw_power_vddioctrl);
@@ -613,6 +673,8 @@ static void mxs_power_enable_4p2(void)
        if (tmp)
                writel(POWER_CHARGE_ENABLE_LOAD,
                        &power_regs->hw_power_charge_clr);
+
+       debug("SPL: 4P2 regulator powered-up\n");
 }
 
 /**
@@ -625,6 +687,8 @@ static void mxs_power_enable_4p2(void)
  */
 static void mxs_boot_valid_5v(void)
 {
+       debug("SPL: Booting from 5V supply\n");
+
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
@@ -650,6 +714,8 @@ static void mxs_boot_valid_5v(void)
  */
 static void mxs_powerdown(void)
 {
+       debug("Powering Down\n");
+
        writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
        writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
                &power_regs->hw_power_reset);
@@ -663,6 +729,8 @@ static void mxs_powerdown(void)
  */
 static void mxs_batt_boot(void)
 {
+       debug("SPL: Configuring power block to boot from battery\n");
+
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
 
@@ -716,6 +784,8 @@ static void mxs_handle_5v_conflict(void)
 {
        uint32_t tmp;
 
+       debug("SPL: Resolving 5V conflict\n");
+
        setbits_le32(&power_regs->hw_power_vddioctrl,
                        POWER_VDDIOCTRL_BO_OFFSET_MASK);
 
@@ -727,19 +797,27 @@ static void mxs_handle_5v_conflict(void)
                         * If VDDIO has a brownout, then the VDD5V_GT_VDDIO
                         * becomes unreliable
                         */
+                       debug("SPL: VDDIO has a brownout\n");
                        mxs_powerdown();
                        break;
                }
 
                if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
+                       debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
                        mxs_boot_valid_5v();
                        break;
                } else {
+                       debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
                        mxs_powerdown();
                        break;
                }
 
+               /*
+                * TODO: I can't see this being reached. We'll either
+                * powerdown or boot from a stable 5V supply.
+                */
                if (tmp & POWER_STS_PSWITCH_MASK) {
+                       debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
                        mxs_batt_boot();
                        break;
                }
@@ -754,30 +832,29 @@ static void mxs_handle_5v_conflict(void)
  */
 static void mxs_5v_boot(void)
 {
+       debug("SPL: Configuring power block to boot from 5V input\n");
+
        /*
         * 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) {
+               debug("SPL: 5V VDD good\n");
                mxs_boot_valid_5v();
                return;
        }
 
        early_delay(1000);
        if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               debug("SPL: 5V VDD good (after delay)\n");
                mxs_boot_valid_5v();
                return;
        }
 
+       debug("SPL: 5V VDD not good\n");
        mxs_handle_5v_conflict();
 }
 
-/**
- * mxs_init_batt_bo() - Configure battery brownout threshold
- *
- * This function configures the battery input brownout threshold. The value
- * at which the battery brownout happens is configured to 3.0V in the code.
- */
 static void mxs_fixed_batt_boot(void)
 {
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
@@ -808,8 +885,17 @@ static void mxs_fixed_batt_boot(void)
                &power_regs->hw_power_5vctrl_clr);
 }
 
+/**
+ * mxs_init_batt_bo() - Configure battery brownout threshold
+ *
+ * This function configures the battery input brownout threshold. The value
+ * at which the battery brownout happens is configured to 3.0V in the code.
+ */
 static void mxs_init_batt_bo(void)
 {
+       debug("SPL: Initialising battery brown-out level to 3.0V\n");
+
+       /* Brownout at 3V */
        clrsetbits_le32(&power_regs->hw_power_battmonitor,
                POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
                BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
@@ -826,6 +912,8 @@ static void mxs_init_batt_bo(void)
  */
 static void mxs_switch_vddd_to_dcdc_source(void)
 {
+       debug("SPL: Switching VDDD to DC-DC converters\n");
+
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -849,6 +937,8 @@ static void mxs_power_configure_power_source(void)
        struct mxs_lradc_regs *lradc_regs =
                (struct mxs_lradc_regs *)MXS_LRADC_BASE;
 
+       debug("SPL: Configuring power source\n");
+
        mxs_src_power_init();
 
        if (!fixed_batt_supply) {
@@ -874,6 +964,10 @@ static void mxs_power_configure_power_source(void)
                mxs_fixed_batt_boot();
        }
 
+       /*
+        * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced
+        * from USB VBUS
+        */
        mxs_power_clock2pll();
 
        mxs_init_batt_bo();
@@ -882,6 +976,7 @@ static void mxs_power_configure_power_source(void)
 
 #ifdef CONFIG_SOC_MX23
        /* Fire up the VDDMEM LinReg now that we're all set. */
+       debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
        writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
                &power_regs->hw_power_vddmemctrl);
 #endif
@@ -898,6 +993,8 @@ static void mxs_power_configure_power_source(void)
  */
 static void mxs_enable_output_rail_protection(void)
 {
+       debug("SPL: Enabling output rail protection\n");
+
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 
@@ -1198,6 +1295,8 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
  */
 static void mxs_setup_batt_detect(void)
 {
+       debug("SPL: Starting battery voltage measurement logic\n");
+
        mxs_lradc_init();
        mxs_lradc_enable_batt_measurement();
        early_delay(10);
@@ -1230,8 +1329,12 @@ static void mxs_ungate_power(void)
  * This function calls all the power block initialization functions in
  * proper sequence to start the power block.
  */
+#define VDDX_VAL(v)    (v) / 1000, (v) / 100 % 10
+
 void mxs_power_init(void)
 {
+       debug("SPL: Initialising Power Block\n");
+
        mxs_ungate_power();
 
        mxs_power_clock2xtal();
@@ -1248,17 +1351,19 @@ void mxs_power_init(void)
        mxs_power_configure_power_source();
        mxs_enable_output_rail_protection();
 
+       debug("SPL: Setting VDDIO to %uV%u (brownout @ %uv%02u)\n",
+               VDDX_VAL(VDDIO_VAL), VDDX_VAL(VDDIO_VAL - VDDIO_BO_VAL));
        mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
+       debug("SPL: Setting VDDD to %uV%u (brownout @ %uv%02u)\n",
+               VDDX_VAL(VDDD_VAL), VDDX_VAL(VDDD_VAL - VDDD_BO_VAL));
        mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
+       debug("SPL: Setting VDDA to %uV%u (brownout @ %uv%02u)\n",
+               VDDX_VAL(VDDA_VAL), VDDX_VAL(VDDA_VAL - VDDA_BO_VAL));
        mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
 #ifdef CONFIG_SOC_MX23
+       debug("SPL: Setting VDDMEM to %uV%u (brownout @ %uv%02u)\n",
+               VDDX_VAL(VDDMEM_VAL), VDDX_VAL(VDDMEM_VAL - VDDMEM_BO_VAL));
        mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
-
-       setbits_le32(&power_regs->hw_power_vddmemctrl,
-               POWER_VDDMEMCTRL_ENABLE_LINREG);
-       early_delay(500);
-       clrbits_le32(&power_regs->hw_power_vddmemctrl,
-               POWER_VDDMEMCTRL_ENABLE_ILIMIT);
 #else
        clrbits_le32(&power_regs->hw_power_vddmemctrl,
                POWER_VDDMEMCTRL_ENABLE_LINREG);
@@ -1281,6 +1386,7 @@ void mxs_power_init(void)
  */
 void mxs_power_wait_pswitch(void)
 {
+       debug("SPL: Waiting for power switch input\n");
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
 }