Merge "feat(hcx): initialize HCRX_EL2 to its default value" into integration
diff --git a/Makefile b/Makefile
index 4b60863..98e448f 100644
--- a/Makefile
+++ b/Makefile
@@ -1185,6 +1185,10 @@
         ENABLE_FEAT_RNG_TRAP \
         ENABLE_FEAT_SEL2 \
         ENABLE_FEAT_TCR2 \
+        ENABLE_FEAT_S2PIE \
+        ENABLE_FEAT_S1PIE \
+        ENABLE_FEAT_S2POE \
+        ENABLE_FEAT_S1POE \
         ENABLE_FEAT_VHE \
         ENABLE_MPAM_FOR_LOWER_ELS \
         ENABLE_RME \
@@ -1321,6 +1325,10 @@
         ENABLE_FEAT_CSV2_2 \
         ENABLE_FEAT_PAN \
         ENABLE_FEAT_TCR2 \
+        ENABLE_FEAT_S2PIE \
+        ENABLE_FEAT_S1PIE \
+        ENABLE_FEAT_S2POE \
+        ENABLE_FEAT_S1POE \
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 9394304..1582b9d 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -210,6 +210,14 @@
 	/* v8.9 features */
 	check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
 		      "TCR2", 1, 1);
+	check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(),
+		      "S2PIE", 1, 1);
+	check_feature(ENABLE_FEAT_S1PIE, read_feat_s1pie_id_field(),
+		      "S1PIE", 1, 1);
+	check_feature(ENABLE_FEAT_S2POE, read_feat_s2poe_id_field(),
+		      "S2POE", 1, 1);
+	check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
+		      "S1POE", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index bffca72..9b934c9 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -477,8 +477,8 @@
 
 Arm Morello and N1SDP Platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Manoj Kumar <manoj.kumar3@arm.com>
-:|G|: `manojkumar-arm`_
+:|M|: Anurag Koul <anurag.koul@arm.com>
+:|G|: `anukou`_
 :|M|: Chandni Cherukuri <chandni.cherukuri@arm.com>
 :|G|: `chandnich`_
 :|F|: plat/arm/board/morello
@@ -954,7 +954,7 @@
 .. _raghuncstate: https://github.com/raghuncstate
 .. _CJKay: https://github.com/cjkay
 .. _nmenon: https://github.com/nmenon
-.. _manojkumar-arm: https://github.com/manojkumar-arm
+.. _anukou: https://github.com/anukou
 .. _chandnich: https://github.com/chandnich
 .. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
 .. _vishnu-banavath: https://github.com/vishnu-banavath
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e078e47..03be786 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -354,6 +354,26 @@
    flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 81f4fbe..4fe0d2f 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -89,6 +89,16 @@
 make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
 	ZYNQMP_ATF_MEM_BASE=0x40000 ZYNQMP_ATF_MEM_SIZE=<size>
 
+Configurable Stack Size
+-----------------------
+
+The stack size in TF-A for ZynqMP platform is configurable.
+The custom package can define the desired stack size as per the requirement in
+the make file as follows,
+
+PLATFORM_STACK_SIZE := <value>
+$(eval $(call add_define,PLATFORM_STACK_SIZE))
+
 FSBL->TF-A Parameter Passing
 ----------------------------
 
diff --git a/drivers/rpi3/sdhost/rpi3_sdhost.c b/drivers/rpi3/sdhost/rpi3_sdhost.c
index c4b6fca..90c8509 100644
--- a/drivers/rpi3/sdhost/rpi3_sdhost.c
+++ b/drivers/rpi3/sdhost/rpi3_sdhost.c
@@ -245,13 +245,12 @@
 
 static void rpi3_sdhost_initialize(void)
 {
-	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
-
 	assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
 
 	rpi3_sdhost_reset();
 
-	mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_PREFERVAL);
+	rpi3_sdhost_set_ios(rpi3_sdhost_params.clk_rate_initial,
+		rpi3_sdhost_params.bus_width);
 	udelay(300);
 }
 
diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi
index f956b05..18a4ba9 100644
--- a/fdts/stm32mp15-bl2.dtsi
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -3,6 +3,9 @@
  * Copyright (c) 2020-2023, STMicroelectronics - All Rights Reserved
  */
 
+/omit-if-no-ref/ &i2c6;
+/omit-if-no-ref/ &spi6;
+
 / {
 #if !STM32MP_EMMC && !STM32MP_SDMMC
 	aliases {
@@ -39,11 +42,9 @@
 #if !STM32MP_USB_PROGRAMMER
 		/delete-node/ usbphyc@5a006000;
 #endif
-		/delete-node/ spi@5c001000;
 		/delete-node/ rtc@5c004000;
 		/delete-node/ etzpc@5c007000;
 		/delete-node/ stgen@5c008000;
-		/delete-node/ i2c@5c009000;
 		/delete-node/ tamp@5c00a000;
 	};
 
diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi
index c5a815e..6882224 100644
--- a/fdts/stm32mp15-bl32.dtsi
+++ b/fdts/stm32mp15-bl32.dtsi
@@ -3,6 +3,9 @@
  * Copyright (c) 2020-2023, STMicroelectronics - All Rights Reserved
  */
 
+/omit-if-no-ref/ &i2c6;
+/omit-if-no-ref/ &spi6;
+
 / {
 	aliases {
 		/delete-property/ mmc0;
@@ -23,8 +26,6 @@
 		/delete-node/ mmc@58005000;
 		/delete-node/ mmc@58007000;
 		/delete-node/ usbphyc@5a006000;
-		/delete-node/ spi@5c001000;
 		/delete-node/ stgen@5c008000;
-		/delete-node/ i2c@5c009000;
 	};
 };
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 596d020..89f4b40 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -355,6 +355,18 @@
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
 
+#define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
+#define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1POE_SHIFT		U(16)
+#define ID_AA64MMFR3_EL1_S1POE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S2PIE_SHIFT		U(12)
+#define ID_AA64MMFR3_EL1_S2PIE_MASK		ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1PIE_SHIFT		U(8)
+#define ID_AA64MMFR3_EL1_S1PIE_MASK		ULL(0xf)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
@@ -512,6 +524,7 @@
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
+#define SCR_PIEN_BIT		(UL(1) << 45)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
 #define SCR_HXEn_BIT		(UL(1) << 38)
@@ -1329,6 +1342,15 @@
 #define TCR2_EL2		S3_4_C2_C0_3
 
 /*******************************************************************************
+ * Permission indirection and overlay
+ ******************************************************************************/
+
+#define PIRE0_EL2		S3_4_C10_C2_2
+#define PIR_EL2			S3_4_C10_C2_3
+#define POR_EL2			S3_4_C10_C2_4
+#define S2PIR_EL2		S3_4_C10_C2_5
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 3ea08a6..840b117 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -234,6 +234,88 @@
 	return read_feat_tcrx_id_field() != 0U;
 }
 
+static unsigned int read_feat_s2poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
+}
+
+static inline bool is_feat_s2poe_supported(void)
+{
+	if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s2poe_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
+}
+
+static inline bool is_feat_s1poe_supported(void)
+{
+	if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s1poe_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpoe_supported(void)
+{
+	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
+}
+
+static unsigned int read_feat_s2pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
+}
+
+static inline bool is_feat_s2pie_supported(void)
+{
+	if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s2pie_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
+}
+
+static inline bool is_feat_s1pie_supported(void)
+{
+	if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_s1pie_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpie_supported(void)
+{
+	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
+}
+
 /*******************************************************************************
  * Functions to identify the presence of the Activity Monitors Extension
  ******************************************************************************/
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 04b64be..f877f5b 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -605,6 +605,14 @@
 /* FEAT_TCR2 Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
 
+/* FEAT_SxPIE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
+
+/* FEAT_SxPOE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
diff --git a/include/drivers/rpi3/sdhost/rpi3_sdhost.h b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
index 1653240..f4f6ec8 100644
--- a/include/drivers/rpi3/sdhost/rpi3_sdhost.h
+++ b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
@@ -15,6 +15,7 @@
 struct rpi3_sdhost_params {
 	uintptr_t	reg_base;
 	uint32_t	clk_rate;
+	uint32_t	clk_rate_initial;
 	uint32_t	bus_width;
 	uint32_t        flags;
 	uint32_t	current_cmd;
@@ -57,6 +58,8 @@
 #define HC_CMD_READ			0x0040
 #define HC_CMD_COMMAND_MASK		0x003f
 
+#define RPI3_SDHOST_MAX_CLOCK		250000000	// technically, we should obtain this number from the mailbox
+
 #define HC_CLOCKDIVISOR_MAXVAL		0x07ff
 #define HC_CLOCKDIVISOR_PREFERVAL	0x027b
 #define HC_CLOCKDIVISOR_SLOWVAL		0x0148
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index e5e7e74..a8e6d8a 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -230,9 +230,13 @@
 
 // Starting with Armv8.9
 #define CTX_TCR2_EL2            U(0x1d8)
+#define CTX_POR_EL2             U(0x1e0)
+#define CTX_PIRE0_EL2           U(0x1e8)
+#define CTX_PIR_EL2             U(0x1f0)
+#define CTX_S2PIR_EL2		U(0x1f8)
 
 /* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x1e0)
+#define CTX_EL2_SYSREGS_END	U(0x200)
 
 #endif /* CTX_INCLUDE_EL2_REGS */
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index ce78439..c411b73 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -368,6 +368,14 @@
 	}
 
 	/*
+	 * SCR_EL3.PIEN: Enable permission indirection and overlay
+	 * registers for AArch64 if present.
+	 */
+	if (is_feat_sxpie_supported() || is_feat_sxpoe_supported()) {
+		scr_el3 |= SCR_PIEN_BIT;
+	}
+
+	/*
 	 * CPTR_EL3 was initialized out of reset, copy that value to the
 	 * context register.
 	 */
@@ -1021,6 +1029,16 @@
 		if (is_feat_tcr2_supported()) {
 			write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
 		}
+		if (is_feat_sxpie_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
+		}
+		if (is_feat_s2pie_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+		}
+		if (is_feat_sxpoe_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+		}
 	}
 }
 
@@ -1088,6 +1106,16 @@
 		if (is_feat_tcr2_supported()) {
 			write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
 		}
+		if (is_feat_sxpie_supported()) {
+			write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
+			write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
+		}
+		if (is_feat_s2pie_supported()) {
+			write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+		}
+		if (is_feat_sxpoe_supported()) {
+			write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+		}
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index c70b377..6c6b23c 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -62,12 +62,17 @@
 	int rc;
 	aff_info_state_t target_aff_state;
 	int ret = plat_core_pos_by_mpidr(target_cpu);
-	unsigned int target_idx = (unsigned int)ret;
+	unsigned int target_idx;
 
 	/* Calling function must supply valid input arguments */
-	assert(ret >= 0);
 	assert(ep != NULL);
 
+	if ((ret < 0) || (ret >= (int)PLATFORM_CORE_COUNT)) {
+		ERROR("Unexpected core index.\n");
+		panic();
+	}
+
+	target_idx = (unsigned int)ret;
 
 	/*
 	 * This function must only be called on platforms where the
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index af980f5..808a058 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -176,6 +176,18 @@
 # Flag to enable access to TCR2 (FEAT_TCR2)
 ENABLE_FEAT_TCR2		:= 0
 
+# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE)
+ENABLE_FEAT_S2PIE		:= 0
+
+# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE)
+ENABLE_FEAT_S1PIE		:= 0
+
+# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE)
+ENABLE_FEAT_S2POE		:= 0
+
+# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
+ENABLE_FEAT_S1POE		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index ab6e0bf..3fb323b 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -77,6 +77,10 @@
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_TCR2		:= 2
+ENABLE_FEAT_S2PIE		:= 2
+ENABLE_FEAT_S1PIE		:= 2
+ENABLE_FEAT_S2POE		:= 2
+ENABLE_FEAT_S1POE		:= 2
 endif
 
 # The FVP platform depends on this macro to build with correct GIC driver.
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 661f8e2..7065a65 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -30,6 +30,20 @@
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
+/*
+ * Avoid the pointer dereference of the canonical mmio_read_8() implementation.
+ * This prevents the compiler from mis-interpreting the MMIO access as an
+ * illegal memory access to a very low address (the IMX ROM is mapped at 0).
+ */
+static uint8_t mmio_read_8_ldrb(uintptr_t address)
+{
+	uint8_t reg;
+
+	__asm__ volatile ("ldrb %w0, [%1]" : "=r" (reg) : "r" (address));
+
+	return reg;
+}
+
 static const mmap_region_t imx_mmap[] = {
 	MAP_REGION_FLAT(GPV_BASE, GPV_SIZE, MT_DEVICE | MT_RW), /* GPV map */
 	MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM map */
@@ -70,11 +84,11 @@
 	uint32_t ocotp_val;
 
 	imx_soc_revision = mmio_read_32(IMX_ANAMIX_BASE + ANAMIX_DIGPROG);
-	rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_A0);
+	rom_version = mmio_read_8_ldrb(IMX_ROM_BASE + ROM_SOC_INFO_A0);
 	if (rom_version == 0x10)
 		return;
 
-	rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_B0);
+	rom_version = mmio_read_8_ldrb(IMX_ROM_BASE + ROM_SOC_INFO_B0);
 	if (rom_version == 0x20) {
 		imx_soc_revision &= ~0xff;
 		imx_soc_revision |= rom_version;
diff --git a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
index 82bb6cb..b30a11e 100644
--- a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
+++ b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
@@ -21,17 +21,25 @@
 #define FLAGOUTSETCLR_F2SDRAM0_IDLEREQ		(BIT(0))
 #define FLAGOUTSETCLR_F2SDRAM1_IDLEREQ		(BIT(3))
 #define FLAGOUTSETCLR_F2SDRAM2_IDLEREQ		(BIT(6))
-#define FLAGINTSTATUS_F2SDRAM0_IDLEACK		(BIT(1))
-#define FLAGINTSTATUS_F2SDRAM1_IDLEACK		(BIT(5))
-#define FLAGINTSTATUS_F2SDRAM2_IDLEACK		(BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_IDLEACK		(BIT(1))
+#define FLAGINSTATUS_F2SDRAM1_IDLEACK		(BIT(5))
+#define FLAGINSTATUS_F2SDRAM2_IDLEACK		(BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_CMDIDLE		(BIT(2))
+#define FLAGINSTATUS_F2SDRAM1_CMDIDLE		(BIT(6))
+#define FLAGINSTATUS_F2SDRAM2_CMDIDLE		(BIT(10))
+#define FLAGINSTATUS_F2SDRAM0_NOCIDLE		(BIT(0))
+#define FLAGINSTATUS_F2SDRAM1_NOCIDLE		(BIT(4))
+#define FLAGINSTATUS_F2SDRAM2_NOCIDLE		(BIT(8))
+
 #define FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN	(BIT(2))
 #define FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN	(BIT(5))
 #define FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN	(BIT(8))
 
-#define FLAGINTSTATUS_F2SOC_RESPEMPTY		(BIT(3))
-#define FLAGINTSTATUS_F2SDRAM0_RESPEMPTY	(BIT(3))
-#define FLAGINTSTATUS_F2SDRAM1_RESPEMPTY	(BIT(7))
-#define FLAGINTSTATUS_F2SDRAM2_RESPEMPTY	(BIT(11))
+#define FLAGINSTATUS_F2SOC_RESPEMPTY		(BIT(3))
+#define FLAGINSTATUS_F2SDRAM0_RESPEMPTY		(BIT(3))
+#define FLAGINSTATUS_F2SDRAM1_RESPEMPTY		(BIT(7))
+#define FLAGINSTATUS_F2SDRAM2_RESPEMPTY		(BIT(11))
+#define FLAGINSTATUS_F2S_FM_TRACKERIDLE		(BIT(4))
 
 #define SOCFPGA_F2SDRAMMGR(_reg)	(SOCFPGA_F2SDRAMMGR_REG_BASE \
 						+ (SOCFPGA_F2SDRAMMGR_##_reg))
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index bb4efab..77d9a73 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -14,7 +14,6 @@
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
 
-
 void deassert_peripheral_reset(void)
 {
 	mmio_clrbits_32(SOCFPGA_RSTMGR(PER1MODRST),
@@ -89,11 +88,12 @@
 	mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), or_mask);
 }
 
-static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
 {
-	int time_out = 300;
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
 
-	while (time_out--) {
 		if ((mmio_read_32(addr) & mask) == match) {
 			return 0;
 		}
@@ -102,9 +102,24 @@
 	return -ETIMEDOUT;
 }
 
+static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
+					 uint32_t match, uint32_t delay_clk_cycles)
+{
+	int time_out = delay_clk_cycles;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
 static void socfpga_s2f_bridge_mask(uint32_t mask,
-				uint32_t *brg_mask,
-				uint32_t *noc_mask)
+				    uint32_t *brg_mask,
+				    uint32_t *noc_mask)
 {
 	*brg_mask = 0;
 	*noc_mask = 0;
@@ -121,12 +136,13 @@
 }
 
 static void socfpga_f2s_bridge_mask(uint32_t mask,
-				uint32_t *brg_mask,
-				uint32_t *f2s_idlereq,
-				uint32_t *f2s_force_drain,
-				uint32_t *f2s_en,
-				uint32_t *f2s_idleack,
-				uint32_t *f2s_respempty)
+				    uint32_t *brg_mask,
+				    uint32_t *f2s_idlereq,
+				    uint32_t *f2s_force_drain,
+				    uint32_t *f2s_en,
+				    uint32_t *f2s_idleack,
+				    uint32_t *f2s_respempty,
+				    uint32_t *f2s_cmdidle)
 {
 	*brg_mask = 0;
 	*f2s_idlereq = 0;
@@ -134,6 +150,7 @@
 	*f2s_en = 0;
 	*f2s_idleack = 0;
 	*f2s_respempty = 0;
+	*f2s_cmdidle = 0;
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 	if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -144,24 +161,27 @@
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
 	}
 	if ((mask & F2SDRAM1_MASK) != 0U) {
 		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM1_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM1_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM1_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM1_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM1_CMDIDLE;
 	}
 	if ((mask & F2SDRAM2_MASK) != 0U) {
 		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM2_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM2_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM2_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM2_CMDIDLE;
 	}
 #else
 	if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -169,8 +189,9 @@
 		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
 		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
 		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-		*f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-		*f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
 	}
 #endif
 }
@@ -185,6 +206,7 @@
 	uint32_t f2s_en = 0;
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
 
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -198,7 +220,7 @@
 
 		/* Wait until idle ack becomes 0 */
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-						noc_mask, 0);
+				       noc_mask, 0, 300);
 		if (ret < 0) {
 			ERROR("S2F bridge enable: "
 					"Timeout waiting for idle ack\n");
@@ -207,37 +229,84 @@
 
 	/* Enable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-						&f2s_force_drain, &f2s_en,
-						&f2s_idleack, &f2s_respempty);
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
 	if (brg_mask != 0U) {
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_idlereq);
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_idlereq);
 
-		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
-			SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0);
+		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0),
+				       f2s_idleack, 0, 300);
+
 		if (ret < 0) {
 			ERROR("F2S bridge enable: "
-					"Timeout waiting for idle ack");
+			      "Timeout waiting for idle ack");
 		}
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_force_drain);
+		/* Clear the force drain */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_force_drain);
 		udelay(5);
 
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-			f2s_en);
+				f2s_en);
 		udelay(5);
 	}
 
 	return ret;
 }
 
+int socfpga_bridge_nongraceful_disable(uint32_t mask)
+{
+	int ret = 0;
+	int timeout = 1000;
+	uint32_t brg_mask = 0;
+	uint32_t f2s_idlereq = 0;
+	uint32_t f2s_force_drain = 0;
+	uint32_t f2s_en = 0;
+	uint32_t f2s_idleack = 0;
+	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
+
+	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+
+	mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_idlereq);
+
+	/* Time out Error - Bus is still active */
+	/* Performing a non-graceful shutdown with Force drain */
+	mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_force_drain);
+
+	ret = -ETIMEDOUT;
+	do {
+		/* Read response queue status to ensure it is empty */
+		uint32_t idle_status;
+
+		idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+		if ((idle_status & f2s_respempty) != 0U) {
+			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+			if ((idle_status & f2s_respempty) != 0U) {
+				/* No time-out we are good! */
+				ret = 0;
+				break;
+			}
+		}
+
+		asm("nop");
+
+	} while (timeout-- > 0);
+
+	return ret;
+}
+
 int socfpga_bridges_disable(uint32_t mask)
 {
 	int ret = 0;
-	int timeout = 300;
 	uint32_t brg_mask = 0;
 	uint32_t noc_mask = 0;
 	uint32_t f2s_idlereq = 0;
@@ -245,6 +314,7 @@
 	uint32_t f2s_en = 0;
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
 
 	/* Disable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -255,17 +325,17 @@
 		mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
 
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-						noc_mask, noc_mask);
+				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
 			ERROR("S2F Bridge disable: "
-					"Timeout waiting for idle ack\n");
+			      "Timeout waiting for idle ack\n");
 		}
 
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
-						noc_mask, noc_mask);
+				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
 			ERROR("S2F Bridge disable: "
-					"Timeout waiting for idle status\n");
+			      "Timeout waiting for idle status\n");
 		}
 
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
@@ -275,43 +345,35 @@
 
 	/* Disable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-						&f2s_force_drain, &f2s_en,
-						&f2s_idleack, &f2s_respempty);
+				&f2s_force_drain, &f2s_en,
+				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
 	if (brg_mask != 0U) {
+
+		if (mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST)) & brg_mask) {
+			/* Bridge cannot be reset twice */
+			return 0;
+		}
+
+		/* Starts the fence and drain traffic from F2SDRAM to MPFE */
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
 				RSTMGR_HDSKEN_FPGAHSEN);
-
+		udelay(5);
+		/* Ignoring FPGA ACK as it will time-out */
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
 				RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGAHSACK_MASK,
-				RSTMGR_HDSKACK_FPGAHSACK_MASK);
+		ret = poll_idle_status_by_clkcycles(SOCFPGA_RSTMGR(HDSKACK),
+						    RSTMGR_HDSKACK_FPGAHSACK_MASK,
+						    RSTMGR_HDSKACK_FPGAHSACK_MASK, 1000);
 
-		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+		/* DISABLE F2S Bridge */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
 				f2s_en);
 		udelay(5);
 
-		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-				f2s_force_drain);
-		udelay(5);
-
-		do {
-			/* Read response queue status to ensure it is empty */
-			uint32_t idle_status;
+		ret = socfpga_bridge_nongraceful_disable(mask);
 
-			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-				SIDEBANDMGR_FLAGINSTATUS0));
-			if ((idle_status & f2s_respempty) != 0U) {
-				idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-					SIDEBANDMGR_FLAGINSTATUS0));
-				if ((idle_status & f2s_respempty) != 0U) {
-					break;
-				}
-			}
-			udelay(1000);
-		} while (timeout-- > 0);
-
+		/* Bridge reset */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 		/* Software must never write a 0x1 to FPGA2SOC_MASK bit */
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
@@ -320,8 +382,9 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 				brg_mask);
 #endif
+		/* Re-enable traffic to SDRAM*/
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-				RSTMGR_HDSKEQ_FPGAHSREQ);
+				RSTMGR_HDSKREQ_FPGAHSREQ);
 
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
 				f2s_idlereq);
diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c
index db71817..80e4d8d 100644
--- a/plat/rpi/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl2_setup.c
@@ -35,7 +35,9 @@
 	params.reg_base = RPI3_SDHOST_BASE;
 	params.bus_width = MMC_BUS_WIDTH_1;
 	params.clk_rate = 50000000;
+	params.clk_rate_initial = (RPI3_SDHOST_MAX_CLOCK / HC_CLOCKDIVISOR_MAXVAL);
 	mmc_info.mmc_dev_type = MMC_IS_SD_HC;
+	mmc_info.ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4;
 	rpi3_sdhost_init(&params, &mmc_info);
 }
 
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index aebce30..fb1130f 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -21,7 +21,9 @@
  ******************************************************************************/
 
 /* Size of cacheable stacks */
+#ifndef PLATFORM_STACK_SIZE
 #define PLATFORM_STACK_SIZE 0x440
+#endif
 
 #define PLATFORM_CORE_COUNT		U(4)
 #define PLAT_NUM_POWER_DOMAINS		U(5)