stm32mp1: ram: add support for LPDDR2/LPDDR3
authorPatrick Delaunay <patrick.delaunay@st.com>
Wed, 10 Apr 2019 12:09:26 +0000 (14:09 +0200)
committerPatrice Chotard <patrice.chotard@st.com>
Thu, 23 May 2019 09:38:11 +0000 (11:38 +0200)
Manage power supply configuration for board using stpmic1
with LPDDR2 or with LPDDR3:
+ VDD_DDR1 = 1.8V with BUCK3 (bypass if possible)
+ VDD_DDR2 = 1.2V with BUCK2

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
arch/arm/mach-stm32mp/include/mach/ddr.h
board/st/stm32mp1/board.c
drivers/ram/stm32mp1/stm32mp1_ddr.c
drivers/ram/stm32mp1/stm32mp1_ddr_regs.h

index 18575842ba9a7f098f19605b4f3210c024a27ebf..b8a17cfbddb8ac1976dd5fc3950c99875b58ea1d 100644 (file)
@@ -6,6 +6,13 @@
 #ifndef __MACH_STM32MP_DDR_H_
 #define __MACH_STM32MP_DDR_H_
 
-int board_ddr_power_init(void);
+/* DDR power initializations */
+enum ddr_type {
+       STM32MP_DDR3,
+       STM32MP_LPDDR2,
+       STM32MP_LPDDR3,
+};
+
+int board_ddr_power_init(enum ddr_type ddr_type);
 
 #endif
index 5c1acca20d79dd3213357d99f99b02a09affe550..c3d832f58489bd3ca5e5b37ad6696dc94c4eb727 100644 (file)
@@ -38,9 +38,10 @@ void board_debug_uart_init(void)
 #endif
 
 #ifdef CONFIG_PMIC_STPMIC1
-int board_ddr_power_init(void)
+int board_ddr_power_init(enum ddr_type ddr_type)
 {
        struct udevice *dev;
+       bool buck3_at_1800000v = false;
        int ret;
 
        ret = uclass_get_device_by_driver(UCLASS_PMIC,
@@ -49,53 +50,127 @@ int board_ddr_power_init(void)
                /* No PMIC on board */
                return 0;
 
-       /* VTT = Set LDO3 to sync mode */
-       ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
-       if (ret < 0)
-               return ret;
-
-       ret &= ~STPMIC1_LDO3_MODE;
-       ret &= ~STPMIC1_LDO12356_VOUT_MASK;
-       ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
-
-       ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-                            ret);
-       if (ret < 0)
-               return ret;
-
-       /* VDD_DDR = Set BUCK2 to 1.35V */
-       ret = pmic_clrsetbits(dev,
-                             STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-                             STPMIC1_BUCK_VOUT_MASK,
-                             STPMIC1_BUCK2_1350000V);
-       if (ret < 0)
-               return ret;
-
-       /* Enable VDD_DDR = BUCK2 */
-       ret = pmic_clrsetbits(dev,
-                             STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-                             STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
-       if (ret < 0)
-               return ret;
-
-       mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-       /* Enable VREF */
-       ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
-                             STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
-       if (ret < 0)
-               return ret;
-
-       mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-       /* Enable LDO3 */
-       ret = pmic_clrsetbits(dev,
-                             STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-                             STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
-       if (ret < 0)
-               return ret;
-
-       mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+       switch (ddr_type) {
+       case STM32MP_DDR3:
+               /* VTT = Set LDO3 to sync mode */
+               ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+               if (ret < 0)
+                       return ret;
+
+               ret &= ~STPMIC1_LDO3_MODE;
+               ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+               ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
+
+               ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+                                    ret);
+               if (ret < 0)
+                       return ret;
+
+               /* VDD_DDR = Set BUCK2 to 1.35V */
+               ret = pmic_clrsetbits(dev,
+                                     STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+                                     STPMIC1_BUCK_VOUT_MASK,
+                                     STPMIC1_BUCK2_1350000V);
+               if (ret < 0)
+                       return ret;
+
+               /* Enable VDD_DDR = BUCK2 */
+               ret = pmic_clrsetbits(dev,
+                                     STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+                                     STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               /* Enable VREF */
+               ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+                                     STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               /* Enable VTT = LDO3 */
+               ret = pmic_clrsetbits(dev,
+                                     STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+                                     STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               break;
+
+       case STM32MP_LPDDR2:
+       case STM32MP_LPDDR3:
+               /*
+                * configure VDD_DDR1 = LDO3
+                * Set LDO3 to 1.8V
+                * + bypass mode if BUCK3 = 1.8V
+                * + normal mode if BUCK3 != 1.8V
+                */
+               ret = pmic_reg_read(dev,
+                                   STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
+               if (ret < 0)
+                       return ret;
+
+               if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
+                       buck3_at_1800000v = true;
+
+               ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+               if (ret < 0)
+                       return ret;
+
+               ret &= ~STPMIC1_LDO3_MODE;
+               ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+               ret |= STPMIC1_LDO3_1800000;
+               if (buck3_at_1800000v)
+                       ret |= STPMIC1_LDO3_MODE;
+
+               ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+                                    ret);
+               if (ret < 0)
+                       return ret;
+
+               /* VDD_DDR2 : Set BUCK2 to 1.2V */
+               ret = pmic_clrsetbits(dev,
+                                     STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+                                     STPMIC1_BUCK_VOUT_MASK,
+                                     STPMIC1_BUCK2_1200000V);
+               if (ret < 0)
+                       return ret;
+
+               /* Enable VDD_DDR1 = LDO3 */
+               ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+                                     STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               /* Enable VDD_DDR2 =BUCK2 */
+               ret = pmic_clrsetbits(dev,
+                                     STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+                                     STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               /* Enable VREF */
+               ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+                                     STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+               if (ret < 0)
+                       return ret;
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               break;
+
+       default:
+               break;
+       };
 
        return 0;
 }
index 5e1041dffeb706ef67dae9ab6a6b1710dd1a6eca..cfd223e37fd8404f1b8ec6a6dc804f07407953d4 100644 (file)
@@ -372,7 +372,7 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
 }
 
 /* board-specific DDR power initializations. */
-__weak int board_ddr_power_init(void)
+__weak int board_ddr_power_init(enum ddr_type ddr_type)
 {
        return 0;
 }
@@ -382,9 +382,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
                       const struct stm32mp1_ddr_config *config)
 {
        u32 pir;
-       int ret;
+       int ret = -EINVAL;
 
-       ret = board_ddr_power_init();
+       if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
+               ret = board_ddr_power_init(STM32MP_DDR3);
+       else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
+               ret = board_ddr_power_init(STM32MP_LPDDR2);
+       else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
+               ret = board_ddr_power_init(STM32MP_LPDDR3);
 
        if (ret)
                panic("ddr power init failed\n");
index a606b2bcbe27dc9d8ef9da2eb71ebee2be0625f0..97f268e66dddf6bdd558686a8f668abb8d93c2cd 100644 (file)
@@ -234,6 +234,8 @@ struct stm32mp1_ddrphy {
 
 /* DDRCTRL REGISTERS */
 #define DDRCTRL_MSTR_DDR3                      BIT(0)
+#define DDRCTRL_MSTR_LPDDR2                    BIT(2)
+#define DDRCTRL_MSTR_LPDDR3                    BIT(3)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK       GENMASK(13, 12)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL       (0 << 12)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF       (1 << 12)