Merge git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / arch / arm / cpu / arm926ejs / mxs / spl_power_init.c
index 0d80158..e3b6cd9 100644 (file)
@@ -4,23 +4,7 @@
  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  * on behalf of DENX Software Engineering GmbH
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -30,7 +14,7 @@
 
 #include "mxs_init.h"
 
-void mxs_power_clock2xtal(void)
+static void mxs_power_clock2xtal(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -40,7 +24,7 @@ void mxs_power_clock2xtal(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 }
 
-void mxs_power_clock2pll(void)
+static void mxs_power_clock2pll(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -52,7 +36,7 @@ void mxs_power_clock2pll(void)
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
-void mxs_power_clear_auto_restart(void)
+static void mxs_power_clear_auto_restart(void)
 {
        struct mxs_rtc_regs *rtc_regs =
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
@@ -85,7 +69,7 @@ void mxs_power_clear_auto_restart(void)
                ;
 }
 
-void mxs_power_set_linreg(void)
+static void mxs_power_set_linreg(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -104,7 +88,7 @@ void mxs_power_set_linreg(void)
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
 }
 
-int mxs_get_batt_volt(void)
+static int mxs_get_batt_volt(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -115,12 +99,12 @@ int mxs_get_batt_volt(void)
        return volt;
 }
 
-int mxs_is_batt_ready(void)
+static int mxs_is_batt_ready(void)
 {
        return (mxs_get_batt_volt() >= 3600);
 }
 
-int mxs_is_batt_good(void)
+static int mxs_is_batt_good(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -160,7 +144,7 @@ int mxs_is_batt_good(void)
        return 0;
 }
 
-void mxs_power_setup_5v_detect(void)
+static void mxs_power_setup_5v_detect(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -172,7 +156,7 @@ void mxs_power_setup_5v_detect(void)
                        POWER_5VCTRL_PWRUP_VBUS_CMPS);
 }
 
-void mxs_src_power_init(void)
+static void mxs_src_power_init(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -203,7 +187,7 @@ void mxs_src_power_init(void)
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
 }
 
-void mxs_power_init_4p2_params(void)
+static void mxs_power_init_4p2_params(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -227,7 +211,7 @@ void mxs_power_init_4p2_params(void)
                0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 }
 
-void mxs_enable_4p2_dcdc_input(int xfer)
+static void mxs_enable_4p2_dcdc_input(int xfer)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -323,7 +307,7 @@ void mxs_enable_4p2_dcdc_input(int xfer)
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
 }
 
-void mxs_power_init_4p2_regulator(void)
+static void mxs_power_init_4p2_regulator(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -407,7 +391,7 @@ void mxs_power_init_4p2_regulator(void)
        writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 }
 
-void mxs_power_init_dcdc_4p2_source(void)
+static void mxs_power_init_dcdc_4p2_source(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -429,7 +413,7 @@ void mxs_power_init_dcdc_4p2_source(void)
        }
 }
 
-void mxs_power_enable_4p2(void)
+static void mxs_power_enable_4p2(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -488,7 +472,7 @@ void mxs_power_enable_4p2(void)
                        &power_regs->hw_power_charge_clr);
 }
 
-void mxs_boot_valid_5v(void)
+static void mxs_boot_valid_5v(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -511,7 +495,7 @@ void mxs_boot_valid_5v(void)
        mxs_power_enable_4p2();
 }
 
-void mxs_powerdown(void)
+static void mxs_powerdown(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -520,7 +504,7 @@ void mxs_powerdown(void)
                &power_regs->hw_power_reset);
 }
 
-void mxs_batt_boot(void)
+static void mxs_batt_boot(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -564,7 +548,7 @@ void mxs_batt_boot(void)
                0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 }
 
-void mxs_handle_5v_conflict(void)
+static void mxs_handle_5v_conflict(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -600,7 +584,7 @@ void mxs_handle_5v_conflict(void)
        }
 }
 
-void mxs_5v_boot(void)
+static void mxs_5v_boot(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -623,7 +607,7 @@ void mxs_5v_boot(void)
        mxs_handle_5v_conflict();
 }
 
-void mxs_init_batt_bo(void)
+static void mxs_init_batt_bo(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -637,7 +621,7 @@ void mxs_init_batt_bo(void)
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
 }
 
-void mxs_switch_vddd_to_dcdc_source(void)
+static void mxs_switch_vddd_to_dcdc_source(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -651,7 +635,7 @@ void mxs_switch_vddd_to_dcdc_source(void)
                POWER_VDDDCTRL_DISABLE_STEPPING);
 }
 
-void mxs_power_configure_power_source(void)
+static void mxs_power_configure_power_source(void)
 {
        int batt_ready, batt_good;
        struct mxs_power_regs *power_regs =
@@ -687,9 +671,15 @@ void mxs_power_configure_power_source(void)
        mxs_init_batt_bo();
 
        mxs_switch_vddd_to_dcdc_source();
+
+#ifdef CONFIG_MX23
+       /* Fire up the VDDMEM LinReg now that we're all set. */
+       writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
+               &power_regs->hw_power_vddmemctrl);
+#endif
 }
 
-void mxs_enable_output_rail_protection(void)
+static void mxs_enable_output_rail_protection(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -707,7 +697,7 @@ void mxs_enable_output_rail_protection(void)
                        POWER_VDDIOCTRL_PWDN_BRNOUT);
 }
 
-int mxs_get_vddio_power_source_off(void)
+static int mxs_get_vddio_power_source_off(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -735,7 +725,7 @@ int mxs_get_vddio_power_source_off(void)
 
 }
 
-int mxs_get_vddd_power_source_off(void)
+static int mxs_get_vddd_power_source_off(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -778,10 +768,14 @@ struct mxs_vddx_cfg {
        uint32_t                bo_offset_offset;
 };
 
-const struct mxs_vddx_cfg mxs_vddio_cfg = {
+static const struct mxs_vddx_cfg mxs_vddio_cfg = {
        .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
                                        hw_power_vddioctrl),
+#if defined(CONFIG_MX23)
+       .step_mV                = 25,
+#else
        .step_mV                = 50,
+#endif
        .lowest_mV              = 2800,
        .powered_by_linreg      = mxs_get_vddio_power_source_off,
        .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
@@ -791,7 +785,7 @@ const struct mxs_vddx_cfg mxs_vddio_cfg = {
        .bo_offset_offset       = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
 };
 
-const struct mxs_vddx_cfg mxs_vddd_cfg = {
+static const struct mxs_vddx_cfg mxs_vddd_cfg = {
        .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
                                        hw_power_vdddctrl),
        .step_mV                = 25,
@@ -804,6 +798,21 @@ const struct mxs_vddx_cfg mxs_vddd_cfg = {
        .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
 };
 
+#ifdef CONFIG_MX23
+static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
+       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+                                       hw_power_vddmemctrl),
+       .step_mV                = 50,
+       .lowest_mV              = 1700,
+       .powered_by_linreg      = NULL,
+       .trg_mask               = POWER_VDDMEMCTRL_TRG_MASK,
+       .bo_irq                 = 0,
+       .bo_enirq               = 0,
+       .bo_offset_mask         = 0,
+       .bo_offset_offset       = 0,
+};
+#endif
+
 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
                                uint32_t new_target, uint32_t new_brownout)
 {
@@ -821,9 +830,10 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
        cur_target += cfg->lowest_mV;
 
        adjust_up = new_target > cur_target;
-       powered_by_linreg = cfg->powered_by_linreg();
+       if (cfg->powered_by_linreg)
+               powered_by_linreg = cfg->powered_by_linreg();
 
-       if (adjust_up) {
+       if (adjust_up && cfg->bo_irq) {
                if (powered_by_linreg) {
                        bo_int = readl(cfg->reg);
                        clrbits_le32(cfg->reg, cfg->bo_enirq);
@@ -864,28 +874,42 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
                cur_target += cfg->lowest_mV;
        } while (new_target > cur_target);
 
-       if (adjust_up && powered_by_linreg) {
-               writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
-               if (bo_int & cfg->bo_enirq)
-                       setbits_le32(cfg->reg, cfg->bo_enirq);
-       }
+       if (cfg->bo_irq) {
+               if (adjust_up && powered_by_linreg) {
+                       writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
+                       if (bo_int & cfg->bo_enirq)
+                               setbits_le32(cfg->reg, cfg->bo_enirq);
+               }
 
-       clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
-                       new_brownout << cfg->bo_offset_offset);
+               clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
+                               new_brownout << cfg->bo_offset_offset);
+       }
 }
 
-void mxs_setup_batt_detect(void)
+static void mxs_setup_batt_detect(void)
 {
        mxs_lradc_init();
        mxs_lradc_enable_batt_measurement();
        early_delay(10);
 }
 
+static void mxs_ungate_power(void)
+{
+#ifdef CONFIG_MX23
+       struct mxs_power_regs *power_regs =
+               (struct mxs_power_regs *)MXS_POWER_BASE;
+
+       writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
+#endif
+}
+
 void mxs_power_init(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
 
+       mxs_ungate_power();
+
        mxs_power_clock2xtal();
        mxs_power_clear_auto_restart();
        mxs_power_set_linreg();
@@ -897,8 +921,10 @@ void mxs_power_init(void)
        mxs_enable_output_rail_protection();
 
        mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
-       mxs_power_set_vddx(&mxs_vddd_cfg, 1350, 1200);
-
+       mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
+#ifdef CONFIG_MX23
+       mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
+#endif
        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 |
@@ -909,7 +935,7 @@ void mxs_power_init(void)
        early_delay(1000);
 }
 
-#ifdef CONFIG_SPL_MX28_PSWITCH_WAIT
+#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
 void mxs_power_wait_pswitch(void)
 {
        struct mxs_power_regs *power_regs =