diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 28cdf7286bf2b4c6f307f4376a0e621d41e60400..38140782ab30b7ea2d15f901749d8ec5f56310d5 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -668,29 +668,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 					      MT_MEMORY | MT_RW | MT_NS);
 		assert(err == 0);
 
-		/* Configuration of TZC400 */
-		stm32mp1_security_setup_begin();
-
-#if STM32MP_SP_MIN_IN_DDR || defined(AARCH32_SP_OPTEE)
-		stm32mp1_security_add_region(sec_base_address, sec_size, true);
-
-		if (sec_base_address > STM32MP_DDR_BASE) {
-			stm32mp1_security_add_region(STM32MP_DDR_BASE,
-						     sec_base_address - STM32MP_DDR_BASE,
-						     false);
-		}
-
-		ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U;
-		if (sec_base_address + sec_size < ddr_top) {
-			stm32mp1_security_add_region(sec_base_address + sec_size,
-						     ddr_top - (sec_base_address + sec_size) + 1U,
-						     false);
-		}
-#else
-		stm32mp1_security_add_region(STM32MP_DDR_BASE, dt_get_ddr_size(), false);
-#endif
-		stm32mp1_security_setup_end();
-
 		break;
 	case BL32_IMAGE_ID:
 #if defined(AARCH32_SP_OPTEE)
@@ -759,3 +736,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 
 	return err;
 }
+
+void bl2_el3_plat_prepare_exit(void)
+{
+	stm32mp1_security_setup();
+}
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 475d7557768cdfac541cae5eb1bceb6135afb45b..cb5f84aaf7c7ef835b858cec5bf22c9fc50896ff 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -43,8 +43,6 @@ void stm32mp1_syscfg_init(void);
 void stm32mp1_syscfg_enable_io_compensation(void);
 void stm32mp1_syscfg_disable_io_compensation(void);
 
-uint32_t stm32mp_get_ddr_ns_size(void);
-
 void stm32mp1_init_scmi_server(void);
 void stm32mp1_pm_save_scmi_state(uint8_t *state, size_t size);
 void stm32mp1_pm_restore_scmi_state(uint8_t *state, size_t size);
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 6d6cf2f022231de20d6792b021ce3ed792a1a882..17820f1441e91b12b8c921d0473ee5e9104caa30 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -196,12 +196,12 @@ PLAT_BL_COMMON_SOURCES	+=	drivers/arm/tzc/tzc400.c				\
 				plat/st/stm32mp1/stm32mp1_context.c			\
 				plat/st/stm32mp1/stm32mp1_dbgmcu.c			\
 				plat/st/stm32mp1/stm32mp1_helper.S			\
-				plat/st/stm32mp1/stm32mp1_security.c			\
 				plat/st/stm32mp1/stm32mp1_syscfg.c
 
 BL2_SOURCES		+=	lib/fconf/fconf.c				\
 				lib/fconf/fconf_dyn_cfg_getter.c			\
-				plat/st/common/stm32mp_fconf_io.c
+				plat/st/common/stm32mp_fconf_io.c			\
+				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
 
 BL2_SOURCES		+=	drivers/io/io_block.c					\
 				drivers/io/io_fip.c					\
diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
new file mode 100644
index 0000000000000000000000000000000000000000..f2699e3765911ee488a9a60f9269ea6a8566ea3c
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/tzc400.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <lib/fconf/fconf.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <stm32mp_fconf_getter.h>
+
+#define STM32MP_REGION_PARAMS	4
+#define STM32MP_MAX_REGIONS	8
+#define FORCE_SEC_REGION	BIT(31)
+
+static uint32_t nb_regions;
+
+struct dt_id_attr {
+	fdt32_t id_attr[STM32MP_MAX_REGIONS];
+};
+
+void stm32mp1_arch_security_setup(void)
+{
+	stm32mp_clk_enable(TZC1);
+	stm32mp_clk_enable(TZC2);
+
+	tzc400_init(STM32MP1_TZC_BASE);
+	tzc400_disable_filters();
+
+	/*
+	 * Region 0 set to cover all DRAM at 0xC000_0000
+	 * Only secure access is granted in read/write.
+	 */
+	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+
+	tzc400_set_action(TZC_ACTION_ERR);
+	tzc400_enable_filters();
+}
+
+void stm32mp1_security_setup(void)
+{
+	uint8_t i;
+
+	assert(nb_regions > 0U);
+
+	tzc400_init(STM32MP1_TZC_BASE);
+	tzc400_disable_filters();
+
+	/*
+	 * Region 0 set to cover all DRAM at 0xC000_0000
+	 * No access is allowed.
+	 */
+	tzc400_configure_region0(TZC_REGION_S_NONE, 0);
+
+	for (i = 1U; i <= nb_regions; i++) {
+		tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
+	}
+
+	tzc400_set_action(TZC_ACTION_INT);
+	tzc400_enable_filters();
+}
+
+static int fconf_populate_stm32mp1_firewall(uintptr_t config)
+{
+	int node, len;
+	unsigned int i;
+	const struct dt_id_attr *conf_list;
+	const void *dtb = (const void *)config;
+
+	/* Assert the node offset point to "st,mem-firewall" compatible property */
+	const char *compatible_str = "st,mem-firewall";
+
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+	if (node < 0) {
+		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+		return node;
+	}
+
+	conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
+	if (conf_list == NULL) {
+		WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
+		return -1;
+	}
+
+	/* Locate the memory cells and read all values */
+	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
+		uint32_t base;
+		uint32_t size;
+		uint32_t sec_attr;
+		uint32_t nsaid;
+
+		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
+		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
+		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
+		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
+
+		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+			base, size, sec_attr, nsaid);
+
+		nb_regions++;
+
+		/* Configure region but keep disabled for secure access for BL2 load */
+		tzc400_configure_region(0, nb_regions, (unsigned long long)base,
+					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
+	}
+
+	/* Force flush as the value will be used cache off */
+	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
+
+	return 0;
+}
+
+FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 5c5a35f1db345dd6dbe569c50afe06c676502bf2..fe651f09c4f9574e8eec8ab3442fcd989689c504 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -749,31 +749,6 @@ int plat_bind_regulator(struct stm32mp_regulator *regu)
 	return 0;
 }
 
-/* Get the non-secure DDR size */
-uint32_t stm32mp_get_ddr_ns_size(void)
-{
-#if STM32MP_SP_MIN_IN_DDR
-	return STM32MP_BL32_BASE - STM32MP_DDR_BASE;
-#else
-	static uint32_t ddr_ns_size;
-	uint32_t ddr_size;
-
-	if (ddr_ns_size != 0U) {
-		return ddr_ns_size;
-	}
-
-	ddr_size = dt_get_ddr_size();
-	if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
-	    (ddr_size > STM32MP_DDR_MAX_SIZE)) {
-		panic();
-	}
-
-	ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
-
-	return ddr_ns_size;
-#endif
-}
-
 bool stm32mp_boot_action_is_wakeup_from_standby(void)
 {
 	return (stm32mp_get_boot_action() == BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) ||
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
deleted file mode 100644
index 6bcfb6289df1a7c74875cdf12027ab4f2e1b687a..0000000000000000000000000000000000000000
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <drivers/arm/tzc400.h>
-#include <drivers/st/stm32mp1_clk.h>
-#include <dt-bindings/clock/stm32mp1-clks.h>
-#include <lib/mmio.h>
-
-#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
-	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)
-
-static unsigned int region_nb;
-
-static void init_tzc400_begin(unsigned int region0_attr)
-{
-	tzc400_init(STM32MP1_TZC_BASE);
-	tzc400_disable_filters();
-
-	/* Region 0 set to cover all DRAM at 0xC000_0000 */
-	tzc400_configure_region0(region0_attr, 0);
-
-	region_nb = 1U;
-}
-
-static void init_tzc400_end(unsigned int action)
-{
-	tzc400_set_action(action);
-	tzc400_enable_filters();
-}
-
-static void tzc400_add_region(unsigned long long region_base,
-			      unsigned long long region_top, bool sec)
-{
-	unsigned int sec_attr;
-	unsigned int nsaid_permissions;
-
-	if (sec) {
-		sec_attr = TZC_REGION_S_RDWR;
-		nsaid_permissions = 0;
-	} else {
-		sec_attr = TZC_REGION_S_NONE;
-		nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR;
-	}
-
-	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base,
-				region_top, sec_attr, nsaid_permissions);
-
-	region_nb++;
-}
-
-/*******************************************************************************
- * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
- * and allow Non-Secure masters full access.
- ******************************************************************************/
-static void init_tzc400(void)
-{
-	unsigned long long region_base, region_top;
-	unsigned long long ddr_base = STM32MP_DDR_BASE;
-	unsigned long long ddr_ns_size =
-		(unsigned long long)stm32mp_get_ddr_ns_size();
-	unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U);
-	unsigned long long ddr_top __unused;
-
-	init_tzc400_begin(TZC_REGION_S_NONE);
-
-	/*
-	 * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the
-	 * same configuration to all filters in the TZC.
-	 */
-	region_base = ddr_base;
-	region_top = ddr_ns_top;
-	tzc400_add_region(region_base, region_top, false);
-
-#if (defined AARCH32_SP_OPTEE) || STM32MP_SP_MIN_IN_DDR
-	/* Region 2 set to cover all secure DRAM. */
-	region_base = region_top + 1U;
-	region_top += STM32MP_DDR_S_SIZE;
-	tzc400_add_region(region_base, region_top, true);
-
-	ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U;
-	if (region_top < ddr_top) {
-		/* Region 3 set to cover non-secure memory DRAM after BL32. */
-		region_base = region_top + 1U;
-		region_top = ddr_top;
-		tzc400_add_region(region_base, region_top, false);
-	}
-#endif
-
-	/*
-	 * Raise an interrupt (secure FIQ) if a NS device tries to access
-	 * secure memory
-	 */
-	init_tzc400_end(TZC_ACTION_INT);
-}
-
-/*******************************************************************************
- * Initialize the TrustZone Controller.
- * Early initialization create only one region with full access to secure.
- * This setting is used before and during DDR initialization.
- ******************************************************************************/
-static void early_init_tzc400(void)
-{
-	stm32mp_clk_enable(TZC1);
-	stm32mp_clk_enable(TZC2);
-
-	/* Region 0 set to cover all DRAM secure at 0xC000_0000 */
-	init_tzc400_begin(TZC_REGION_S_RDWR);
-
-	/* Raise an exception if a NS device tries to access secure memory */
-	init_tzc400_end(TZC_ACTION_ERR);
-}
-
-/*******************************************************************************
- * Initialize the secure environment. At this moment only the TrustZone
- * Controller is initialized.
- ******************************************************************************/
-void stm32mp1_arch_security_setup(void)
-{
-	early_init_tzc400();
-}
-
-/*******************************************************************************
- * Initialize the secure environment. At this moment only the TrustZone
- * Controller is initialized.
- ******************************************************************************/
-void stm32mp1_security_setup(void)
-{
-	init_tzc400();
-}
-
-void stm32mp1_security_setup_begin(void)
-{
-	init_tzc400_begin(TZC_REGION_S_NONE);
-}
-
-void stm32mp1_security_setup_end(void)
-{
-	init_tzc400_end(TZC_ACTION_INT);
-}
-
-void stm32mp1_security_add_region(unsigned long long region_base,
-				  unsigned long long region_size, bool sec)
-{
-	tzc400_add_region(region_base, region_base + region_size - 1ULL, sec);
-}