feat(stm32mp1): allow configuration of DDR AXI ports number

A new flag STM32MP_DDR_DUAL_AXI_PORT is added, and enabled by default.
It will allow choosing single or dual AXI ports for DDR.

Change-Id: I48826a66a6f4d18df87e081c0960af89ddda1b9d
Signed-off-by: Yann Gautier <yann.gautier@st.com>
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index fbb480a..e890c4d 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -54,9 +54,17 @@
 #define DDRCTL_REG_REG_SIZE	25	/* st,ctl-reg */
 #define DDRCTL_REG_TIMING_SIZE	12	/* st,ctl-timing */
 #define DDRCTL_REG_MAP_SIZE	9	/* st,ctl-map */
+#if STM32MP_DDR_DUAL_AXI_PORT
 #define DDRCTL_REG_PERF_SIZE	17	/* st,ctl-perf */
+#else
+#define DDRCTL_REG_PERF_SIZE	11	/* st,ctl-perf */
+#endif
 
+#if STM32MP_DDR_32BIT_INTERFACE
 #define DDRPHY_REG_REG_SIZE	11	/* st,phy-reg */
+#else
+#define DDRPHY_REG_REG_SIZE	9	/* st,phy-reg */
+#endif
 #define	DDRPHY_REG_TIMING_SIZE	10	/* st,phy-timing */
 
 #define DDRCTL_REG_REG(x)	DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
@@ -130,12 +138,14 @@
 	DDRCTL_REG_PERF(pcfgqos1_0),
 	DDRCTL_REG_PERF(pcfgwqos0_0),
 	DDRCTL_REG_PERF(pcfgwqos1_0),
+#if STM32MP_DDR_DUAL_AXI_PORT
 	DDRCTL_REG_PERF(pcfgr_1),
 	DDRCTL_REG_PERF(pcfgw_1),
 	DDRCTL_REG_PERF(pcfgqos0_1),
 	DDRCTL_REG_PERF(pcfgqos1_1),
 	DDRCTL_REG_PERF(pcfgwqos0_1),
 	DDRCTL_REG_PERF(pcfgwqos1_1),
+#endif
 };
 
 #define DDRPHY_REG_REG(x)	DDRPHY_REG(x, stm32mp1_ddrphy_reg)
@@ -149,8 +159,10 @@
 	DDRPHY_REG_REG(zq0cr1),
 	DDRPHY_REG_REG(dx0gcr),
 	DDRPHY_REG_REG(dx1gcr),
+#if STM32MP_DDR_32BIT_INTERFACE
 	DDRPHY_REG_REG(dx2gcr),
 	DDRPHY_REG_REG(dx3gcr),
+#endif
 };
 
 #define DDRPHY_REG_TIMING(x)	DDRPHY_REG(x, stm32mp1_ddrphy_timing)
@@ -587,10 +599,12 @@
 			DDRPHYC_DXNDLLCR_DLLDIS);
 	mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
+#if STM32MP_DDR_32BIT_INTERFACE
 	mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
 	mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
+#endif
 
 	/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
 	mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
@@ -861,10 +875,12 @@
 		(uintptr_t)&priv->ctl->pctrl_0,
 		mmio_read_32((uintptr_t)&priv->ctl->pctrl_0));
 
+#if STM32MP_DDR_DUAL_AXI_PORT
 	/* Enable uMCTL2 AXI port 1 */
 	mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1,
 			DDRCTRL_PCTRL_N_PORT_EN);
 	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n",
 		(uintptr_t)&priv->ctl->pctrl_1,
 		mmio_read_32((uintptr_t)&priv->ctl->pctrl_1));
+#endif
 }
diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c
index fcb4cfc..e0621b5 100644
--- a/drivers/st/ddr/stm32mp1_ddr_helpers.c
+++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c
@@ -1,21 +1,23 @@
 /*
- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
-
 #include <drivers/st/stm32mp1_ddr_helpers.h>
 #include <lib/mmio.h>
 
+#include <platform_def.h>
+
 void ddr_enable_clock(void)
 {
 	stm32mp1_clk_rcc_regs_lock();
 
 	mmio_setbits_32(stm32mp_rcc_base() + RCC_DDRITFCR,
 			RCC_DDRITFCR_DDRC1EN |
+#if STM32MP_DDR_DUAL_AXI_PORT
 			RCC_DDRITFCR_DDRC2EN |
+#endif
 			RCC_DDRITFCR_DDRPHYCEN |
 			RCC_DDRITFCR_DDRPHYCAPBEN |
 			RCC_DDRITFCR_DDRCAPBEN);
diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h
index b434930..67dfac3 100644
--- a/include/drivers/st/stm32mp1_ddr.h
+++ b/include/drivers/st/stm32mp1_ddr.h
@@ -101,12 +101,14 @@
 	uint32_t pcfgqos1_0;
 	uint32_t pcfgwqos0_0;
 	uint32_t pcfgwqos1_0;
+#if STM32MP_DDR_DUAL_AXI_PORT
 	uint32_t pcfgr_1;
 	uint32_t pcfgw_1;
 	uint32_t pcfgqos0_1;
 	uint32_t pcfgqos1_1;
 	uint32_t pcfgwqos0_1;
 	uint32_t pcfgwqos1_1;
+#endif
 };
 
 struct stm32mp1_ddrphy_reg {
@@ -119,8 +121,10 @@
 	uint32_t zq0cr1;
 	uint32_t dx0gcr;
 	uint32_t dx1gcr;
+#if STM32MP_DDR_32BIT_INTERFACE
 	uint32_t dx2gcr;
 	uint32_t dx3gcr;
+#endif
 };
 
 struct stm32mp1_ddrphy_timing {
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
index e821206..264cd34 100644
--- a/include/drivers/st/stm32mp1_ddr_regs.h
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -128,6 +128,7 @@
 	uint32_t pcfgwqos1_0;	/* 0x4a0 Write QoS Configuration 1 */
 	uint8_t reserved4a4[0x4b4 - 0x4a4];
 
+#if STM32MP_DDR_DUAL_AXI_PORT
 	/* PORT 1 */
 	uint32_t pcfgr_1;	/* 0x4b4 Configuration Read */
 	uint32_t pcfgw_1;	/* 0x4b8 Configuration Write */
@@ -137,6 +138,7 @@
 	uint32_t pcfgqos1_1;	/* 0x548 Read QoS Configuration 1 */
 	uint32_t pcfgwqos0_1;	/* 0x54c Write QoS Configuration 0 */
 	uint32_t pcfgwqos1_1;	/* 0x550 Write QoS Configuration 1 */
+#endif
 } __packed;
 
 /* DDR Physical Interface Control (DDRPHYC) registers*/
@@ -214,6 +216,7 @@
 	uint32_t dx1dqtr;	/* 0x210 Byte lane 1 DQ Timing */
 	uint32_t dx1dqstr;	/* 0x214 Byte lane 1 QS Timing */
 	uint8_t res6[0x240 - 0x218];	/* 0x218 */
+#if STM32MP_DDR_32BIT_INTERFACE
 	uint32_t dx2gcr;	/* 0x240 Byte lane 2 General Configuration */
 	uint32_t dx2gsr0;	/* 0x244 Byte lane 2 General Status 0 */
 	uint32_t dx2gsr1;	/* 0x248 Byte lane 2 General Status 1 */
@@ -227,6 +230,7 @@
 	uint32_t dx3dllcr;	/* 0x28c Byte lane 3 DLL Control */
 	uint32_t dx3dqtr;	/* 0x290 Byte lane 3 DQ Timing */
 	uint32_t dx3dqstr;	/* 0x294 Byte lane 3 QS Timing */
+#endif
 } __packed;
 
 /* DDR Controller registers offsets */
@@ -249,7 +253,9 @@
 #define DDRCTRL_SWSTAT				0x324
 #define DDRCTRL_PSTAT				0x3FC
 #define DDRCTRL_PCTRL_0				0x490
+#if STM32MP_DDR_DUAL_AXI_PORT
 #define DDRCTRL_PCTRL_1				0x540
+#endif
 
 /* DDR Controller Register fields */
 #define DDRCTRL_MSTR_DDR3			BIT(0)
@@ -339,10 +345,12 @@
 #define DDRPHYC_DX0DLLCR			0x1CC
 #define DDRPHYC_DX1GCR				0x200
 #define DDRPHYC_DX1DLLCR			0x20C
+#if STM32MP_DDR_32BIT_INTERFACE
 #define DDRPHYC_DX2GCR				0x240
 #define DDRPHYC_DX2DLLCR			0x24C
 #define DDRPHYC_DX3GCR				0x280
 #define DDRPHYC_DX3DLLCR			0x28C
+#endif
 
 /* DDR PHY Register fields */
 #define DDRPHYC_PIR_INIT			BIT(0)
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index cc1e0d9..5462297 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,6 +23,10 @@
 # Enable dynamic memory mapping
 PLAT_XLAT_TABLES_DYNAMIC :=	1
 
+# DDR controller with dual AXI port and 32-bit interface
+STM32MP_DDR_DUAL_AXI_PORT:=	1
+STM32MP_DDR_32BIT_INTERFACE:=	1
+
 ifeq ($(AARCH32_SP),sp_min)
 # Disable Neon support: sp_min runtime may conflict with non-secure world
 TF_CFLAGS		+=	-mfloat-abi=soft
@@ -127,6 +131,8 @@
 $(eval $(call assert_booleans,\
 	$(sort \
 		PLAT_XLAT_TABLES_DYNAMIC \
+		STM32MP_DDR_32BIT_INTERFACE \
+		STM32MP_DDR_DUAL_AXI_PORT \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
@@ -151,6 +157,8 @@
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_A_COPIES \
 		STM32_TF_VERSION \
+		STM32MP_DDR_32BIT_INTERFACE \
+		STM32MP_DDR_DUAL_AXI_PORT \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \