Merge changes I09ab0a5c,I87d0a492,I613a52ae,I2fcd8d32,Ie91527a7, ... into integration

* changes:
  feat(stm32mp2): manage DDR FW via FIP
  feat(stm32mp2): introduce DDR type compilation flags
  feat(stm32mp2): add RISAB registers description
  feat(stm32mp2-fdts): add BL31 info in fw-config
  feat(stm32mp2): add minimal support for BL31
  feat(st): manage BL31 FCONF load_info struct
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 5d4ab4e..87bb6a5 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -85,7 +85,8 @@
 
 Boot with FIP
 ~~~~~~~~~~~~~
-You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) before building FIP binary.
+You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) and retrieve
+DDR PHY firmware before building FIP binary.
 
 U-Boot
 ______
@@ -106,9 +107,24 @@
         ARCH=arm PLATFORM=stm32mp2 \
         CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-ev1.dts
 
-TF-A BL2 & BL31
-_______________
-To build TF-A BL2 with its STM32 header and BL31 for SD-card boot:
+DDR PHY firmware
+________________
+DDR PHY firmware files may not be delivered inside TF-A repository, especially
+if you build directly from trustedfirmware.org repository. It then needs to be
+retrieved from `STMicroelectronics DDR PHY github`_.
+
+You can either clone the repository to the default directory:
+
+.. code:: bash
+
+    git clone https://github.com/STMicroelectronics/stm32-ddr-phy-binary.git drivers/st/ddr/phy/firmware/bin
+
+Or clone it somewhere else, and add ``STM32MP_DDR_FW_PATH=`` in your make command
+line when building FIP.
+
+TF-A BL2
+________
+To build TF-A BL2 with its STM32 header for SD-card boot:
 
 .. code:: bash
 
@@ -136,5 +152,6 @@
 
 .. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html
 .. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification
+.. _STMicroelectronics DDR PHY github: https://github.com/STMicroelectronics/stm32-ddr-phy-binary
 
 *Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index 769aab2..e250e3f 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -21,6 +21,9 @@
 	st-io_policies {
 		fip-handles {
 			compatible = "st,io-fip-handle";
+#if STM32MP_DDR_FIP_IO_STORAGE
+			ddr_fw_uuid = "b11249be-92dd-4b10-867c-2c6a4b47a7fb";
+#endif
 			fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
 			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
 			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
index b187ad2..102980d 100644
--- a/fdts/stm32mp25-fw-config.dtsi
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -25,6 +25,12 @@
 			id = <BL33_IMAGE_ID>;
 		};
 
+		soc_fw {
+			load-address = <0x0 STM32MP_SYSRAM_BASE>;
+			max-size = <STM32MP_BL31_SIZE>;
+			id = <BL31_IMAGE_ID>;
+		};
+
 		tos_fw {
 			id = <BL32_IMAGE_ID>;
 		};
diff --git a/include/drivers/st/stm32mp_risab_regs.h b/include/drivers/st/stm32mp_risab_regs.h
new file mode 100644
index 0000000..1f49bf6
--- /dev/null
+++ b/include/drivers/st/stm32mp_risab_regs.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_RISAB_REGS_H
+#define STM32MP_RISAB_REGS_H
+
+#define RISAB_CR				U(0x00)
+#define RISAB_IASR				U(0x08)
+#define RISAB_IACR				U(0x0C)
+#define RISAB_RIFLOCKR				U(0x10)
+#define RISAB_IAESR				U(0x20)
+#define RISAB_IADDR				U(0x24)
+#define RISAB_PG0_SECCFGR			U(0x100)
+#define RISAB_PG1_SECCFGR			U(0x104)
+#define RISAB_PG2_SECCFGR			U(0x108)
+#define RISAB_PG3_SECCFGR			U(0x10C)
+#define RISAB_PG4_SECCFGR			U(0x110)
+#define RISAB_PG5_SECCFGR			U(0x114)
+#define RISAB_PG6_SECCFGR			U(0x118)
+#define RISAB_PG7_SECCFGR			U(0x11C)
+#define RISAB_PG8_SECCFGR			U(0x120)
+#define RISAB_PG9_SECCFGR			U(0x124)
+#define RISAB_PG10_SECCFGR			U(0x128)
+#define RISAB_PG11_SECCFGR			U(0x12C)
+#define RISAB_PG12_SECCFGR			U(0x130)
+#define RISAB_PG13_SECCFGR			U(0x134)
+#define RISAB_PG14_SECCFGR			U(0x138)
+#define RISAB_PG15_SECCFGR			U(0x13C)
+#define RISAB_PG16_SECCFGR			U(0x140)
+#define RISAB_PG17_SECCFGR			U(0x144)
+#define RISAB_PG18_SECCFGR			U(0x148)
+#define RISAB_PG19_SECCFGR			U(0x14C)
+#define RISAB_PG20_SECCFGR			U(0x150)
+#define RISAB_PG21_SECCFGR			U(0x154)
+#define RISAB_PG22_SECCFGR			U(0x158)
+#define RISAB_PG23_SECCFGR			U(0x15C)
+#define RISAB_PG24_SECCFGR			U(0x160)
+#define RISAB_PG25_SECCFGR			U(0x164)
+#define RISAB_PG26_SECCFGR			U(0x168)
+#define RISAB_PG27_SECCFGR			U(0x16C)
+#define RISAB_PG28_SECCFGR			U(0x170)
+#define RISAB_PG29_SECCFGR			U(0x174)
+#define RISAB_PG30_SECCFGR			U(0x178)
+#define RISAB_PG31_SECCFGR			U(0x17C)
+#define RISAB_PG0_PRIVCFGR			U(0x200)
+#define RISAB_PG1_PRIVCFGR			U(0x204)
+#define RISAB_PG2_PRIVCFGR			U(0x208)
+#define RISAB_PG3_PRIVCFGR			U(0x20C)
+#define RISAB_PG4_PRIVCFGR			U(0x210)
+#define RISAB_PG5_PRIVCFGR			U(0x214)
+#define RISAB_PG6_PRIVCFGR			U(0x218)
+#define RISAB_PG7_PRIVCFGR			U(0x21C)
+#define RISAB_PG8_PRIVCFGR			U(0x220)
+#define RISAB_PG9_PRIVCFGR			U(0x224)
+#define RISAB_PG10_PRIVCFGR			U(0x228)
+#define RISAB_PG11_PRIVCFGR			U(0x22C)
+#define RISAB_PG12_PRIVCFGR			U(0x230)
+#define RISAB_PG13_PRIVCFGR			U(0x234)
+#define RISAB_PG14_PRIVCFGR			U(0x238)
+#define RISAB_PG15_PRIVCFGR			U(0x23C)
+#define RISAB_PG16_PRIVCFGR			U(0x240)
+#define RISAB_PG17_PRIVCFGR			U(0x244)
+#define RISAB_PG18_PRIVCFGR			U(0x248)
+#define RISAB_PG19_PRIVCFGR			U(0x24C)
+#define RISAB_PG20_PRIVCFGR			U(0x250)
+#define RISAB_PG21_PRIVCFGR			U(0x254)
+#define RISAB_PG22_PRIVCFGR			U(0x258)
+#define RISAB_PG23_PRIVCFGR			U(0x25C)
+#define RISAB_PG24_PRIVCFGR			U(0x260)
+#define RISAB_PG25_PRIVCFGR			U(0x264)
+#define RISAB_PG26_PRIVCFGR			U(0x268)
+#define RISAB_PG27_PRIVCFGR			U(0x26C)
+#define RISAB_PG28_PRIVCFGR			U(0x270)
+#define RISAB_PG29_PRIVCFGR			U(0x274)
+#define RISAB_PG30_PRIVCFGR			U(0x278)
+#define RISAB_PG31_PRIVCFGR			U(0x27C)
+#define RISAB_PG0_C2PRIVCFGR			U(0x600)
+#define RISAB_PG1_C2PRIVCFGR			U(0x604)
+#define RISAB_PG2_C2PRIVCFGR			U(0x608)
+#define RISAB_PG3_C2PRIVCFGR			U(0x60C)
+#define RISAB_PG4_C2PRIVCFGR			U(0x610)
+#define RISAB_PG5_C2PRIVCFGR			U(0x614)
+#define RISAB_PG6_C2PRIVCFGR			U(0x618)
+#define RISAB_PG7_C2PRIVCFGR			U(0x61C)
+#define RISAB_PG8_C2PRIVCFGR			U(0x620)
+#define RISAB_PG9_C2PRIVCFGR			U(0x624)
+#define RISAB_PG10_C2PRIVCFGR			U(0x628)
+#define RISAB_PG11_C2PRIVCFGR			U(0x62C)
+#define RISAB_PG12_C2PRIVCFGR			U(0x630)
+#define RISAB_PG13_C2PRIVCFGR			U(0x634)
+#define RISAB_PG14_C2PRIVCFGR			U(0x638)
+#define RISAB_PG15_C2PRIVCFGR			U(0x63C)
+#define RISAB_PG16_C2PRIVCFGR			U(0x640)
+#define RISAB_PG17_C2PRIVCFGR			U(0x644)
+#define RISAB_PG18_C2PRIVCFGR			U(0x648)
+#define RISAB_PG19_C2PRIVCFGR			U(0x64C)
+#define RISAB_PG20_C2PRIVCFGR			U(0x650)
+#define RISAB_PG21_C2PRIVCFGR			U(0x654)
+#define RISAB_PG22_C2PRIVCFGR			U(0x658)
+#define RISAB_PG23_C2PRIVCFGR			U(0x65C)
+#define RISAB_PG24_C2PRIVCFGR			U(0x660)
+#define RISAB_PG25_C2PRIVCFGR			U(0x664)
+#define RISAB_PG26_C2PRIVCFGR			U(0x668)
+#define RISAB_PG27_C2PRIVCFGR			U(0x66C)
+#define RISAB_PG28_C2PRIVCFGR			U(0x670)
+#define RISAB_PG29_C2PRIVCFGR			U(0x674)
+#define RISAB_PG30_C2PRIVCFGR			U(0x678)
+#define RISAB_PG31_C2PRIVCFGR			U(0x67C)
+#define RISAB_CID0PRIVCFGR			U(0x800)
+#define RISAB_CID0RDCFGR			U(0x808)
+#define RISAB_CID0WRCFGR			U(0x810)
+#define RISAB_CID1PRIVCFGR			U(0x820)
+#define RISAB_CID1RDCFGR			U(0x828)
+#define RISAB_CID1WRCFGR			U(0x830)
+#define RISAB_CID2PRIVCFGR			U(0x840)
+#define RISAB_CID2RDCFGR			U(0x848)
+#define RISAB_CID2WRCFGR			U(0x850)
+#define RISAB_CID3PRIVCFGR			U(0x860)
+#define RISAB_CID3RDCFGR			U(0x868)
+#define RISAB_CID3WRCFGR			U(0x870)
+#define RISAB_CID4PRIVCFGR			U(0x880)
+#define RISAB_CID4RDCFGR			U(0x888)
+#define RISAB_CID4WRCFGR			U(0x890)
+#define RISAB_CID5PRIVCFGR			U(0x8A0)
+#define RISAB_CID5RDCFGR			U(0x8A8)
+#define RISAB_CID5WRCFGR			U(0x8B0)
+#define RISAB_CID6PRIVCFGR			U(0x8C0)
+#define RISAB_CID6RDCFGR			U(0x8C8)
+#define RISAB_CID6WRCFGR			U(0x8D0)
+#define RISAB_PG0_CIDCFGR			U(0xA00)
+#define RISAB_PG1_CIDCFGR			U(0xA04)
+#define RISAB_PG2_CIDCFGR			U(0xA08)
+#define RISAB_PG3_CIDCFGR			U(0xA0C)
+#define RISAB_PG4_CIDCFGR			U(0xA10)
+#define RISAB_PG5_CIDCFGR			U(0xA14)
+#define RISAB_PG6_CIDCFGR			U(0xA18)
+#define RISAB_PG7_CIDCFGR			U(0xA1C)
+#define RISAB_PG8_CIDCFGR			U(0xA20)
+#define RISAB_PG9_CIDCFGR			U(0xA24)
+#define RISAB_PG10_CIDCFGR			U(0xA28)
+#define RISAB_PG11_CIDCFGR			U(0xA2C)
+#define RISAB_PG12_CIDCFGR			U(0xA30)
+#define RISAB_PG13_CIDCFGR			U(0xA34)
+#define RISAB_PG14_CIDCFGR			U(0xA38)
+#define RISAB_PG15_CIDCFGR			U(0xA3C)
+#define RISAB_PG16_CIDCFGR			U(0xA40)
+#define RISAB_PG17_CIDCFGR			U(0xA44)
+#define RISAB_PG18_CIDCFGR			U(0xA48)
+#define RISAB_PG19_CIDCFGR			U(0xA4C)
+#define RISAB_PG20_CIDCFGR			U(0xA50)
+#define RISAB_PG21_CIDCFGR			U(0xA54)
+#define RISAB_PG22_CIDCFGR			U(0xA58)
+#define RISAB_PG23_CIDCFGR			U(0xA5C)
+#define RISAB_PG24_CIDCFGR			U(0xA60)
+#define RISAB_PG25_CIDCFGR			U(0xA64)
+#define RISAB_PG26_CIDCFGR			U(0xA68)
+#define RISAB_PG27_CIDCFGR			U(0xA6C)
+#define RISAB_PG28_CIDCFGR			U(0xA70)
+#define RISAB_PG29_CIDCFGR			U(0xA74)
+#define RISAB_PG30_CIDCFGR			U(0xA78)
+#define RISAB_PG31_CIDCFGR			U(0xA7C)
+#define RISAB_HWCFGR3				U(0xFE8)
+#define RISAB_HWCFGR2				U(0xFEC)
+#define RISAB_HWCFGR1				U(0xFF0)
+#define RISAB_VERR				U(0xFF4)
+#define RISAB_IPIDR				U(0xFF8)
+#define RISAB_SIDR				U(0xFFC)
+
+/* RISAB_CR register fields */
+#define RISAB_CR_GLOCK				BIT(0)
+#define RISAB_CR_SRWIAD				BIT(31)
+
+/* RISAB_IASR register fields */
+#define RISAB_IASR_CAEF				BIT(0)
+#define RISAB_IASR_IAEF				BIT(1)
+
+/* RISAB_IACR register fields */
+#define RISAB_IACR_CAEF				BIT(0)
+#define RISAB_IACR_IAEF				BIT(1)
+
+/* RISAB_RIFLOCKR register fields */
+#define RISAB_RIFLOCKR_RLOCK0			BIT(0)
+#define RISAB_RIFLOCKR_RLOCK1			BIT(1)
+#define RISAB_RIFLOCKR_RLOCK2			BIT(2)
+#define RISAB_RIFLOCKR_RLOCK3			BIT(3)
+#define RISAB_RIFLOCKR_RLOCK4			BIT(4)
+#define RISAB_RIFLOCKR_RLOCK5			BIT(5)
+#define RISAB_RIFLOCKR_RLOCK6			BIT(6)
+#define RISAB_RIFLOCKR_RLOCK7			BIT(7)
+#define RISAB_RIFLOCKR_RLOCK8			BIT(8)
+#define RISAB_RIFLOCKR_RLOCK9			BIT(9)
+#define RISAB_RIFLOCKR_RLOCK10			BIT(10)
+#define RISAB_RIFLOCKR_RLOCK11			BIT(11)
+#define RISAB_RIFLOCKR_RLOCK12			BIT(12)
+#define RISAB_RIFLOCKR_RLOCK13			BIT(13)
+#define RISAB_RIFLOCKR_RLOCK14			BIT(14)
+#define RISAB_RIFLOCKR_RLOCK15			BIT(15)
+#define RISAB_RIFLOCKR_RLOCK16			BIT(16)
+#define RISAB_RIFLOCKR_RLOCK17			BIT(17)
+#define RISAB_RIFLOCKR_RLOCK18			BIT(18)
+#define RISAB_RIFLOCKR_RLOCK19			BIT(19)
+#define RISAB_RIFLOCKR_RLOCK20			BIT(20)
+#define RISAB_RIFLOCKR_RLOCK21			BIT(21)
+#define RISAB_RIFLOCKR_RLOCK22			BIT(22)
+#define RISAB_RIFLOCKR_RLOCK23			BIT(23)
+#define RISAB_RIFLOCKR_RLOCK24			BIT(24)
+#define RISAB_RIFLOCKR_RLOCK25			BIT(25)
+#define RISAB_RIFLOCKR_RLOCK26			BIT(26)
+#define RISAB_RIFLOCKR_RLOCK27			BIT(27)
+#define RISAB_RIFLOCKR_RLOCK28			BIT(28)
+#define RISAB_RIFLOCKR_RLOCK29			BIT(29)
+#define RISAB_RIFLOCKR_RLOCK30			BIT(30)
+#define RISAB_RIFLOCKR_RLOCK31			BIT(31)
+
+/* RISAB_IAESR register fields */
+#define RISAB_IAESR_IACID_MASK			GENMASK(2, 0)
+#define RISAB_IAESR_IACID_SHIFT			0
+#define RISAB_IAESR_IAPRIV			BIT(4)
+#define RISAB_IAESR_IASEC			BIT(5)
+#define RISAB_IAESR_IANRW			BIT(7)
+
+/* RISAB_PGx_SECCFGR register fields */
+#define RISAB_PGx_SECCFGR_SEC(_y)		BIT(_y)
+
+/* RISAB_PGx_PRIVCFGR register fields */
+#define RISAB_PGx_PRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_PGx_CmPRIVCFGR register fields */
+#define RISAB_PGx_CmPRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxPRIVCFGR register fields */
+#define RISAB_CIDxPRIVCFGR_PPRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxRDCFGR register fields */
+#define RISAB_CIDxRDCFGR_PRDEN(_y)		BIT(_y)
+
+/* RISAB_CIDxWRCFGR register fields */
+#define RISAB_CIDxWRCFGR_PWREN(_y)		BIT(_y)
+
+/* RISAB_PGx_CIDCFGR register fields */
+#define RISAB_PGx_CIDCFGR_CFEN			BIT(0)
+#define RISAB_PGx_CIDCFGR_DCEN			BIT(2)
+#define RISAB_PGx_CIDCFGR_DCCID_MASK		GENMASK(6, 4)
+#define RISAB_PGx_CIDCFGR_DCCID_SHIFT		4
+
+/* RISAB_HWCFGR1 register fields */
+#define RISAB_HWCFGR1_CFG1_MASK			GENMASK(3, 0)
+#define RISAB_HWCFGR1_CFG1_SHIFT		0
+#define RISAB_HWCFGR1_CFG2_MASK			GENMASK(7, 4)
+#define RISAB_HWCFGR1_CFG2_SHIFT		4
+#define RISAB_HWCFGR1_CFG3_MASK			GENMASK(11, 8)
+#define RISAB_HWCFGR1_CFG3_SHIFT		8
+#define RISAB_HWCFGR1_CFG4_MASK			GENMASK(15, 12)
+#define RISAB_HWCFGR1_CFG4_SHIFT		12
+#define RISAB_HWCFGR1_CFG5_MASK			GENMASK(19, 16)
+#define RISAB_HWCFGR1_CFG5_SHIFT		16
+#define RISAB_HWCFGR1_CFG6_MASK			GENMASK(23, 20)
+#define RISAB_HWCFGR1_CFG6_SHIFT		20
+#define RISAB_HWCFGR1_CFG7_MASK			GENMASK(27, 24)
+#define RISAB_HWCFGR1_CFG7_SHIFT		24
+
+/* RISAB_VERR register fields */
+#define RISAB_VERR_MINREV_MASK			GENMASK(3, 0)
+#define RISAB_VERR_MINREV_SHIFT			0
+#define RISAB_VERR_MAJREV_MASK			GENMASK(7, 4)
+#define RISAB_VERR_MAJREV_SHIFT			4
+
+#endif /* STM32MP_RISAB_REGS_H */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 6ed09d9..1aecece 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -76,14 +76,28 @@
 
 #define DEFAULT_UUID_NUMBER	U(7)
 
+#ifdef __aarch64__
+#define BL31_UUID_NUMBER	U(1)
+#else
+#define BL31_UUID_NUMBER	U(0)
+#endif
+
 #if TRUSTED_BOARD_BOOT
 #define TBBR_UUID_NUMBER	U(6)
 #else
 #define TBBR_UUID_NUMBER	U(0)
 #endif
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_UUID_NUMBER	U(1)
+#else
+#define DDR_FW_UUID_NUMBER	U(0)
+#endif
+
 #define FCONF_ST_IO_UUID_NUMBER	(DEFAULT_UUID_NUMBER + \
-				 TBBR_UUID_NUMBER)
+				 BL31_UUID_NUMBER + \
+				 TBBR_UUID_NUMBER + \
+				 DDR_FW_UUID_NUMBER)
 
 static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
 static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
@@ -95,7 +109,13 @@
 
 /* image id to property name table */
 static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	{DDR_FW_ID, "ddr_fw_uuid"},
+#endif
 	{FW_CONFIG_ID, "fw_cfg_uuid"},
+#ifdef __aarch64__
+	{BL31_IMAGE_ID, "bl31_uuid"},
+#endif
 	{BL32_IMAGE_ID, "bl32_uuid"},
 	{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
 	{BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index edada72..50d19ab 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <cdefs.h>
+#include <errno.h>
 #include <stdint.h>
 
 #include <common/debug.h>
@@ -14,6 +15,7 @@
 #include <drivers/mmc.h>
 #include <drivers/st/regulator_fixed.h>
 #include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp_risab_regs.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/mmio.h>
@@ -195,6 +197,17 @@
 		panic();
 	}
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/*
+	 * RISAB3 setup (dedicated for SRAM1)
+	 *
+	 * Allow secure read/writes data accesses to non-secure
+	 * blocks or pages, all RISAB registers are writable.
+	 * DDR firmwares are saved there before being loaded in DDRPHY memory.
+	 */
+	mmio_write_32(RISAB3_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+#endif
+
 	stm32_save_boot_info(boot_context);
 
 	if (stm32mp_uart_console_setup() != 0) {
@@ -229,7 +242,12 @@
 int bl2_plat_handle_post_image_load(unsigned int image_id)
 {
 	int err = 0;
-	bl_mem_params_node_t *bl_mem_params __maybe_unused = get_bl_mem_params_node(image_id);
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+	const struct dyn_cfg_dtb_info_t *config_info;
+	unsigned int i;
+	const unsigned int image_ids[] = {
+		BL31_IMAGE_ID,
+	};
 
 	assert(bl_mem_params != NULL);
 
@@ -253,6 +271,30 @@
 				FW_CONFIG_ID);
 		fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
 
+		/* Iterate through all the fw config IDs */
+		for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
+			bl_mem_params = get_bl_mem_params_node(image_ids[i]);
+			assert(bl_mem_params != NULL);
+
+			config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
+			if (config_info == NULL) {
+				continue;
+			}
+
+			bl_mem_params->image_info.image_base = config_info->config_addr;
+			bl_mem_params->image_info.image_max_size = config_info->config_max_size;
+
+			bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+			switch (image_ids[i]) {
+			case BL31_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+
 		/*
 		 * After this step, the BL2 device tree area will be overwritten
 		 * with BL31 binary, no other data should be read from BL2 DT.
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
new file mode 100644
index 0000000..dbf1371
--- /dev/null
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <drivers/st/stm32_console.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	bl_params_t *params_from_bl2;
+	int ret;
+
+	/*
+	 * Invalidate remaining data from second half of SYSRAM (used by BL2) as this area will
+	 * be later used as non-secure.
+	 */
+	inv_dcache_range(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+			 STM32MP_SYSRAM_SIZE / 2U);
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+#if USE_COHERENT_MEM
+	/* Map coherent memory */
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+	configure_mmu();
+
+	/*
+	 * Map upper SYSRAM where bl_params_t are stored in BL2
+	 */
+	ret = mmap_add_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_SIZE / 2U, MT_RO_DATA | MT_SECURE);
+	if (ret < 0) {
+		ERROR("BL2 params area mapping: %d\n", ret);
+		panic();
+	}
+
+	assert(arg0 != 0UL);
+	params_from_bl2 = (bl_params_t *)arg0;
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+	while (bl_params != NULL) {
+		bl_params = bl_params->next_params_info;
+	}
+
+	ret = mmap_remove_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+					 STM32MP_SYSRAM_SIZE / 2U);
+	if (ret < 0) {
+		ERROR("BL2 params area unmapping: %d\n", ret);
+		panic();
+	}
+}
+
+void bl31_plat_arch_setup(void)
+{
+}
+
+void bl31_platform_setup(void)
+{
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	return NULL;
+}
diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
index 5dfd41f..830bf88 100644
--- a/plat/st/stm32mp2/include/plat_tbbr_img_def.h
+++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
@@ -40,8 +40,16 @@
 #define STM32MP_CONFIG_CERT_ID		U(24)
 #define GPT_IMAGE_ID			U(25)
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_ID			U(26)
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(27)
+
+#else
 /* Increase the MAX_NUMBER_IDS to match the authentication pool required */
 #define MAX_NUMBER_IDS			U(26)
 
+#endif
+
 #endif /* PLAT_TBBR_IMG_DEF_H */
 
diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h
index 0f22a93..89ca032 100644
--- a/plat/st/stm32mp2/include/platform_def.h
+++ b/plat/st/stm32mp2/include/platform_def.h
@@ -8,6 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 #include <plat/common/common_def.h>
 
@@ -32,9 +33,9 @@
 #define PLATFORM_CORE_COUNT		U(2)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
 
-#define PLAT_MAX_PWR_LVL		U(5)
-#define PLAT_MAX_CPU_SUSPEND_PWR_LVL	U(5)
-#define PLAT_NUM_PWR_DOMAINS		U(7)
+#define PLAT_MAX_PWR_LVL		U(3)
+#define PLAT_MIN_SUSPEND_PWR_LVL	U(2)
+#define PLAT_NUM_PWR_DOMAINS		U(6)
 
 /* Local power state for power domains in Run state. */
 #define STM32MP_LOCAL_STATE_RUN		U(0)
@@ -98,4 +99,59 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
 
+/*
+ * Secure Interrupt: based on the standard ARM mapping
+ */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_NON_SEC_SGI_0		U(0)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+/* Platform IRQ Priority */
+#define STM32MP_IRQ_SEC_SPI_PRIO	U(0x10)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index 0ef522e..f845560 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -19,6 +19,24 @@
  * the next executable image id.
  ******************************************************************************/
 static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/* Fill FW_DDR related information if it exists */
+	{
+		.image_id = DDR_FW_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      0),
+
+		.image_info.image_base = STM32MP_DDR_FW_BASE,
+		.image_info.image_max_size = STM32MP_DDR_FW_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+#endif
+
 	/* Fill FW_CONFIG related information if it exists */
 	{
 		.image_id = FW_CONFIG_ID,
@@ -34,6 +52,23 @@
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index eacbd96..32d6235 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -27,6 +27,23 @@
 # Set load address for serial boot devices
 DWL_BUFFER_BASE 		?=	0x87000000
 
+# DDR types
+STM32MP_DDR3_TYPE		?=	0
+STM32MP_DDR4_TYPE		?=	0
+STM32MP_LPDDR4_TYPE		?=	0
+ifeq (${STM32MP_DDR3_TYPE},1)
+DDR_TYPE			:=	ddr3
+endif
+ifeq (${STM32MP_DDR4_TYPE},1)
+DDR_TYPE			:=	ddr4
+endif
+ifeq (${STM32MP_LPDDR4_TYPE},1)
+DDR_TYPE			:=	lpddr4
+endif
+
+# DDR features
+STM32MP_DDR_FIP_IO_STORAGE	:=	1
+
 # Device tree
 BL2_DTSI			:=	stm32mp25-bl2.dtsi
 FDT_SOURCES			:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
@@ -38,13 +55,26 @@
 
 STM32MP_FW_CONFIG_NAME		:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
 STM32MP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+STM32MP_DDR_FW_PATH		?=	drivers/st/ddr/phy/firmware/bin/stm32mp2
+STM32MP_DDR_FW_NAME		:=	${DDR_TYPE}_pmu_train.bin
+STM32MP_DDR_FW			:=	${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME}
+endif
 FDT_SOURCES			+=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+# Add the FW_DDR to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
+endif
 
 # Enable flags for C files
 $(eval $(call assert_booleans,\
 	$(sort \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
 		STM32MP25 \
 )))
 
@@ -58,9 +88,14 @@
 $(eval $(call add_defines,\
 	$(sort \
 		DWL_BUFFER_BASE \
+		PLAT_DEF_FIP_UUID \
 		PLAT_PARTITION_MAX_ENTRIES \
 		PLAT_TBBR_IMG_DEF \
 		STM32_TF_A_COPIES \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
 		STM32MP25 \
 )))
 
@@ -98,5 +133,35 @@
 
 BL2_SOURCES			+=	drivers/st/ddr/stm32mp2_ddr_helpers.c
 
+# BL31 sources
+BL31_SOURCES			+=	${FDT_WRAPPERS_SOURCES}
+
+BL31_SOURCES			+=	plat/st/stm32mp2/bl31_plat_setup.c			\
+					plat/st/stm32mp2/stm32mp2_pm.c				\
+					plat/st/stm32mp2/stm32mp2_topology.c
+# Generic GIC v2
+include drivers/arm/gic/v2/gicv2.mk
+
+BL31_SOURCES			+=	${GICV2_SOURCES}					\
+					plat/common/plat_gicv2.c				\
+					plat/st/common/stm32mp_gic.c
+
+# Generic PSCI
+BL31_SOURCES			+=	plat/common/plat_psci_common.c
+
 # Compilation rules
+.PHONY: check_ddr_type
+.SUFFIXES:
+
+bl2: check_ddr_type
+
+check_ddr_type:
+	$(eval DDR_TYPE = $(shell echo $$(($(STM32MP_DDR3_TYPE) + \
+					   $(STM32MP_DDR4_TYPE) + \
+					   $(STM32MP_LPDDR4_TYPE)))))
+	@if [ ${DDR_TYPE} != 1 ]; then \
+		echo "One and only one DDR type must be defined"; \
+		false; \
+	fi
+
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 81fdaae..d3290c3 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -71,6 +71,9 @@
  ******************************************************************************/
 #define STM32MP_SYSRAM_BASE			U(0x0E000000)
 #define STM32MP_SYSRAM_SIZE			U(0x00040000)
+#define SRAM1_BASE				U(0x0E040000)
+#define SRAM1_SIZE_FOR_TFA			U(0x00010000)
+#define STM32MP_SEC_SYSRAM_SIZE			STM32MP_SYSRAM_SIZE
 
 /* DDR configuration */
 #define STM32MP_DDR_BASE			U(0x80000000)
@@ -106,6 +109,10 @@
 #define STM32MP_BL2_RO_SIZE			U(0x00020000) /* 128 KB */
 #define STM32MP_BL2_SIZE			U(0x00029000) /* 164 KB for BL2 */
 
+/* Allocate remaining sysram to BL31 */
+#define STM32MP_BL31_SIZE			(STM32MP_SEC_SYSRAM_SIZE - \
+						 STM32MP_BL2_SIZE)
+
 #define STM32MP_BL2_BASE			(STM32MP_SYSRAM_BASE + \
 						 STM32MP_SYSRAM_SIZE - \
 						 STM32MP_BL2_SIZE)
@@ -139,6 +146,11 @@
 #define STM32MP_DTB_BASE			STM32MP_BL2_DTB_BASE
 #endif
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define STM32MP_DDR_FW_BASE			SRAM1_BASE
+#define STM32MP_DDR_FW_MAX_SIZE			U(0x8800)
+#endif
+
 #define STM32MP_FW_CONFIG_MAX_SIZE		PAGE_SIZE
 #define STM32MP_FW_CONFIG_BASE			STM32MP_SYSRAM_BASE
 
@@ -359,6 +371,11 @@
 #define SYSCFG_BASE				U(0x44230000)
 
 /*******************************************************************************
+ * STM32MP RIF
+ ******************************************************************************/
+#define RISAB3_BASE				U(0x42110000)
+
+/*******************************************************************************
  * STM32MP CA35SSC
  ******************************************************************************/
 #define A35SSC_BASE				U(0x48800000)
diff --git a/plat/st/stm32mp2/stm32mp2_pm.c b/plat/st/stm32mp2/stm32mp2_pm.c
new file mode 100644
index 0000000..5bb381d
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_pm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+static uintptr_t stm32_sec_entrypoint;
+
+static void stm32_cpu_standby(plat_local_state_t cpu_state)
+{
+}
+
+static int stm32_pwr_domain_on(u_register_t mpidr)
+{
+	return PSCI_E_INTERN_FAIL;
+}
+
+static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Nothing to do */
+}
+
+static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+}
+
+/*******************************************************************************
+ * STM32MP2 handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
+					    *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						  *target_state)
+{
+	ERROR("stm32mp2 Power Down WFI: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_off(void)
+{
+	ERROR("stm32mp2 System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_reset(void)
+{
+	stm32mp_system_reset();
+}
+
+static int stm32_validate_power_state(unsigned int power_state,
+				      psci_power_state_t *req_state)
+{
+	return PSCI_E_INVALID_PARAMS;
+}
+
+static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/* The non-secure entry point must be in DDR */
+	if (entrypoint < STM32MP_DDR_BASE) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+}
+
+/*******************************************************************************
+ * Export the platform handlers. The ARM Standard platform layer will take care
+ * of registering the handlers with PSCI.
+ ******************************************************************************/
+static const plat_psci_ops_t stm32_psci_ops = {
+	.cpu_standby = stm32_cpu_standby,
+	.pwr_domain_on = stm32_pwr_domain_on,
+	.pwr_domain_off = stm32_pwr_domain_off,
+	.pwr_domain_suspend = stm32_pwr_domain_suspend,
+	.pwr_domain_on_finish = stm32_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
+	.pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
+	.system_off = stm32_system_off,
+	.system_reset = stm32_system_reset,
+	.validate_power_state = stm32_validate_power_state,
+	.validate_ns_entrypoint = stm32_validate_ns_entrypoint,
+	.get_sys_suspend_power_state = stm32_get_sys_suspend_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	stm32_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &stm32_psci_ops;
+
+	return 0;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 2801a7f..99f6be2 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -12,12 +12,31 @@
 
 #define BKPR_BOOT_MODE	96U
 
+#if defined(IMAGE_BL31)
+/* BL31 only uses the first half of the SYSRAM */
+#define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
+					STM32MP_SYSRAM_SIZE / 2U, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#else
 #define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
 					STM32MP_SYSRAM_SIZE, \
 					MT_MEMORY | \
 					MT_RW | \
 					MT_SECURE | \
 					MT_EXECUTE_NEVER)
+#endif
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define MAP_SRAM1	MAP_REGION_FLAT(SRAM1_BASE, \
+					SRAM1_SIZE_FOR_TFA, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#endif
 
 #define MAP_DEVICE	MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \
 					STM32MP_DEVICE_SIZE, \
@@ -29,6 +48,16 @@
 #if defined(IMAGE_BL2)
 static const mmap_region_t stm32mp2_mmap[] = {
 	MAP_SYSRAM,
+#if STM32MP_DDR_FIP_IO_STORAGE
+	MAP_SRAM1,
+#endif
+	MAP_DEVICE,
+	{0}
+};
+#endif
+#if defined(IMAGE_BL31)
+static const mmap_region_t stm32mp2_mmap[] = {
+	MAP_SYSRAM,
 	MAP_DEVICE,
 	{0}
 };
diff --git a/plat/st/stm32mp2/stm32mp2_topology.c b/plat/st/stm32mp2/stm32mp2_topology.c
new file mode 100644
index 0000000..cc2d58c
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_topology.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* 1 cluster, all cores into */
+static const unsigned char stm32mp2_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CORE_COUNT,
+};
+
+/* This function returns the platform topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return stm32mp2_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+	u_register_t mpidr_copy = mpidr;
+
+	mpidr_copy &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+		return -1;
+	}
+
+	cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in one
+	 * of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT) {
+		return -1;
+	}
+
+	return (int)cpu_id;
+}