stm32mp1: ram: add support for LPDDR2/LPDDR3

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>
diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h
index 1857584..b8a17cf 100644
--- a/arch/arm/mach-stm32mp/include/mach/ddr.h
+++ b/arch/arm/mach-stm32mp/include/mach/ddr.h
@@ -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
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index 5c1acca..c3d832f 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -38,9 +38,10 @@
 #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 @@
 		/* 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;
+	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 &= ~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;
+		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;
+		/* 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;
+		/* 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);
+		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;
+		/* 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);
+		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;
+		/* 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);
+		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;
 }
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index 5e1041d..cfd223e 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -372,7 +372,7 @@
 }
 
 /* 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 @@
 		       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");
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
index a606b2b..97f268e 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
@@ -234,6 +234,8 @@
 
 /* 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)