Merge changes from topic "soc_id" into integration

* changes:
  refactor(plat/nvidia): use SOC_ID defines
  refactor(plat/mediatek): use SOC_ID defines
  refactor(plat/arm): use SOC_ID defines
  feat(plat/st): implement platform functions for SMCCC_ARCH_SOC_ID
  refactor(plat/st): export functions to get SoC information
  feat(smccc): add bit definition for SMCCC_ARCH_SOC_ID
diff --git a/Makefile b/Makefile
index 2376b9a..017fc65 100644
--- a/Makefile
+++ b/Makefile
@@ -521,6 +521,10 @@
         ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
             DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
         endif
+
+        ifeq ($(TS_SP_FW_CONFIG),1)
+            DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
+        endif
     else
         # All other SPDs in spd directory
         SPD_DIR := spd
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 30b2ab2..df73331 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -449,8 +449,8 @@
 
 MediaTek platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Yidi Lin (林以廸) <yidi.lin@mediatek.com>
-:|G|: `mtk09422`_
+:|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
+:|G|: `mtk-rex-bc-chen`_
 :|F|: plat/mediatek/
 
 Marvell platform ports and SoC drivers
@@ -681,6 +681,20 @@
 :|F|: Makefile
 :|F|: make_helpers/
 
+Threat Model
+~~~~~~~~~~~~~
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|M|: Joanna Farley <joanna.farley@arm.com>
+:|G|: `joannafarley-arm`_
+:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|G|: `raghuncstate`_
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|F|: docs/threat_model/
+
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
@@ -703,7 +717,7 @@
 .. _michalsimek: https://github.com/michalsimek
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
-.. _mtk09422: https://github.com/mtk09422
+.. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
 .. _niej: https://github.com/niej
 .. _npoushin: https://github.com/npoushin
 .. _prabhakarlad: https://github.com/prabhakarlad
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 7eea22f..aa1ae67 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -112,7 +112,7 @@
 ----------------
 
 TF-A has been tested with pre-built binaries and file systems from `Linaro
-Release 19.06`_. Alternatively, you can build the binaries from source using
+Release 20.01`_. Alternatively, you can build the binaries from source using
 instructions in :ref:`Performing an Initial Build`.
 
 .. _prerequisites_get_source:
@@ -166,4 +166,4 @@
 .. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
 .. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
 .. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
-.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
+.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index db8d945..d4fa98d 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -104,6 +104,9 @@
    device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest
    file name contains pattern optee_sp.
 
+-  ``TS_SP_FW_CONFIG``: DTC build flag to include Trusted Services (Crypto and
+   secure-storage) as SP in tb_fw_config device tree.
+
 -  ``ARM_GPT_SUPPORT``: Enable GPT parser to get the entry address and length of
    the various partitions present in the GPT image. This support is available
    only for the BL2 component, and it is disabled by default.
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index fb38d91..8e46083 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -101,7 +101,7 @@
    the models. The models can be launched with ``-Q 100`` option if they are
    required to match the run time characteristics of the older versions.
 
-All the above platforms have been tested with `Linaro Release 19.06`_.
+All the above platforms have been tested with `Linaro Release 20.01`_.
 
 .. _build_options_arm_fvp_platform:
 
@@ -649,5 +649,5 @@
 .. _TB_FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
 .. _Arm's website: `FVP models`_
 .. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
+.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
 .. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
diff --git a/docs/plat/imx8m.rst b/docs/plat/imx8m.rst
index 0408730..0fe15c9 100644
--- a/docs/plat/imx8m.rst
+++ b/docs/plat/imx8m.rst
@@ -6,6 +6,9 @@
 reliability and embedded security needed to drive the growth of fast-growing
 edge node computing, streaming multimedia, and machine learning applications.
 
+imx8mq is dropped in TF-A CI build due to the small OCRAM size, but still actively
+maintained in NXP official release.
+
 Boot Sequence
 -------------
 
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 6bb66a0..23a1dfa 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -92,6 +92,25 @@
 }
 
 /*******************************************************************************
+ * Helper function to get the maximum SPI INTID + 1.
+ ******************************************************************************/
+unsigned int gicv3_get_spi_limit(uintptr_t gicd_base)
+{
+	unsigned int spi_limit;
+	unsigned int typer_reg = gicd_read_typer(gicd_base);
+
+	/* (maximum SPI INTID + 1) is equal to 32 * (GICD_TYPER.ITLinesNumber+1) */
+	spi_limit = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5;
+
+	/* Filter out special INTIDs 1020-1023 */
+	if (spi_limit > (MAX_SPI_ID + 1U)) {
+		return MAX_SPI_ID + 1U;
+	}
+
+	return spi_limit;
+}
+
+/*******************************************************************************
  * Helper function to configure the default attributes of (E)SPIs.
  ******************************************************************************/
 void gicv3_spis_config_defaults(uintptr_t gicd_base)
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index 416cdd0..7965f40 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -233,6 +233,7 @@
 /*******************************************************************************
  * Private GICv3 helper function prototypes
  ******************************************************************************/
+unsigned int gicv3_get_spi_limit(uintptr_t gicd_base);
 void gicv3_spis_config_defaults(uintptr_t gicd_base);
 void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base);
 unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 02fe97c..7377e5e 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -14,6 +14,7 @@
 
 #include <mvebu.h>
 #include <mvebu_def.h>
+#include <plat_marvell.h>
 
 #include "phy-comphy-3700.h"
 #include "phy-comphy-common.h"
@@ -29,15 +30,6 @@
 #define USB3_GBE1_PHY		(MVEBU_REGS_BASE + 0x5C000)
 #define COMPHY_SD_ADDR		(MVEBU_REGS_BASE + 0x1F000)
 
-/*
- * Below address in used only for reading, therefore no problem with concurrent
- * Linux access.
- */
-#define MVEBU_TEST_PIN_LATCH_N (MVEBU_NB_GPIO_REG_BASE + 0x8)
- #define MVEBU_XTAL_MODE_MASK		BIT(9)
- #define MVEBU_XTAL_MODE_OFFS		9
- #define MVEBU_XTAL_CLOCK_25MHZ		0x0
-
 struct sgmii_phy_init_data_fix {
 	uint16_t addr;
 	uint16_t value;
@@ -125,20 +117,6 @@
 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000	/*1F8 */
 };
 
-/* returns reference clock in MHz (25 or 40) */
-static uint32_t get_ref_clk(void)
-{
-	uint32_t val;
-
-	val = (mmio_read_32(MVEBU_TEST_PIN_LATCH_N) & MVEBU_XTAL_MODE_MASK) >>
-		MVEBU_XTAL_MODE_OFFS;
-
-	if (val == MVEBU_XTAL_CLOCK_25MHZ)
-		return 25;
-	else
-		return 40;
-}
-
 /* PHY selector configures with corresponding modes */
 static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
 						uint32_t comphy_mode)
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index c8ba9b8..86f4c77 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -53,13 +53,13 @@
 #define SYS_CTRL_FROM_COMPHY_ADDR(x)	((x & ~0xffffff) + 0x440000)
 
 /* DFX register spaces */
-#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET	(0)
-#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK	(0x1 << \
-					SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
-#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET	(1)
-#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK	(0x1 << \
-					SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
-#define SAR_STATUS_0_REG			200
+#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET	(30)
+#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK	(0x1UL << \
+					SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET)
+#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET	(31)
+#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK	(0x1UL << \
+					SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET)
+#define SAR_STATUS_0_REG			0x40600
 #define DFX_FROM_COMPHY_ADDR(x)			((x & ~0xffffff) + DFX_BASE)
 /* Common Phy training  */
 #define COMPHY_TRX_TRAIN_COMPHY_OFFS		0x1000
@@ -1318,11 +1318,11 @@
 	reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
 			   SAR_STATUS_0_REG);
 	if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
-		clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
-					  SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
+		clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK) >>
+					  SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET;
 	else
-		clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
-					  SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
+		clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK) >>
+					  SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET;
 
 	debug("On lane %d\n", comphy_index);
 	debug("PCIe clock direction = %x\n", clk_dir);
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index b377321..218fd86 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -45,15 +45,13 @@
 	cbz	w2, init_fail
 
 	/* Program the baudrate */
-	/* Divisor =  Uart clock / (16 * baudrate) */
+	/* Divisor = Round(Uartclock / (16 * baudrate)) */
 	lsl	w2, w2, #4
+	add	w1, w1, w2, lsr #1
 	udiv	w2, w1, w2
-	and	w2, w2, #0x3ff
+	and	w2, w2, #0x3ff /* clear all other bits to use default clock */
 
-	ldr	w3, [x0, #UART_BAUD_REG]
-	bic	w3, w3, 0x3ff
-	orr	w3, w3, w2
-	str	w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */
+	str	w2, [x0, #UART_BAUD_REG]/* set baud rate divisor */
 
 	/* Set UART to default 16X scheme */
 	mov	w3, #0
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e288d47..c327e71 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -105,6 +105,36 @@
 	return MMC_GET_STATE(resp_data[0]);
 }
 
+static int mmc_send_part_switch_cmd(unsigned int part_config)
+{
+	int ret;
+	unsigned int part_time = 0;
+
+	ret = mmc_send_cmd(MMC_CMD(6),
+			   EXTCSD_WRITE_BYTES |
+			   EXTCSD_CMD(CMD_EXTCSD_PARTITION_CONFIG) |
+			   EXTCSD_VALUE(part_config) |
+			   EXTCSD_CMD_SET_NORMAL,
+			   MMC_RESPONSE_R1B, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Partition switch timing is in 10ms units */
+	part_time = mmc_ext_csd[CMD_EXTCSD_PART_SWITCH_TIME] * 10;
+
+	mdelay(part_time);
+
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
 static int mmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
 {
 	int ret;
@@ -668,7 +698,7 @@
 {
 	mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
 			PART_CFG_BOOT_PARTITION1_ENABLE |
-			PART_CFG_PARTITION1_ACCESS);
+			PART_CFG_BOOT_PARTITION1_ACCESS);
 }
 
 static inline void mmc_rpmb_disable(void)
@@ -710,6 +740,50 @@
 	return size_erased;
 }
 
+static int mmc_part_switch(unsigned int part_type)
+{
+	uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
+
+	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
+	part_config |= part_type;
+
+	return mmc_send_part_switch_cmd(part_config);
+}
+
+static unsigned char mmc_current_boot_part(void)
+{
+	return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]);
+}
+
+size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size)
+{
+	size_t size_read;
+	int ret;
+	unsigned char current_boot_part = mmc_current_boot_part();
+
+	if (current_boot_part != 1U &&
+	    current_boot_part != 2U) {
+		ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
+		return 0;
+	}
+
+	ret = mmc_part_switch(current_boot_part);
+	if (ret < 0) {
+		ERROR("Failed to switch to boot partition, %d\n", ret);
+		return 0;
+	}
+
+	size_read = mmc_read_blocks(lba, buf, size);
+
+	ret = mmc_part_switch(0);
+	if (ret < 0) {
+		ERROR("Failed to switch back to user partition, %d\n", ret);
+		return 0;
+	}
+
+	return size_read;
+}
+
 int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
 	     unsigned int width, unsigned int flags,
 	     struct mmc_device_info *device_info)
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
index 0ed7154..2bf88e6 100644
--- a/drivers/st/io/io_mmc.c
+++ b/drivers/st/io/io_mmc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,6 +29,7 @@
 static io_type_t device_type_mmc(void);
 
 static signed long long seek_offset;
+static size_t (*_read_blocks)(int lba, uintptr_t buf, size_t size);
 
 static const io_dev_connector_t mmc_dev_connector = {
 	.dev_open = mmc_dev_open
@@ -60,9 +61,15 @@
 /* Open a connection to the mmc device */
 static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info)
 {
+	struct io_mmc_dev_spec *device_spec =
+		(struct io_mmc_dev_spec *)init_params;
+
 	assert(dev_info != NULL);
 	*dev_info = (io_dev_info_t *)&mmc_dev_info;
 
+	_read_blocks = !device_spec->use_boot_part ?
+		mmc_read_blocks : mmc_boot_part_read_blocks;
+
 	return 0;
 }
 
@@ -100,8 +107,8 @@
 	uint8_t retries;
 
 	for (retries = 0U; retries < 3U; retries++) {
-		*length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
-					       buffer, length);
+		*length_read = _read_blocks(seek_offset / MMC_BLOCK_SIZE,
+					    buffer, length);
 
 		if (*length_read == length) {
 			return 0;
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b86a13e..9ef9c26 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -434,8 +434,16 @@
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
+#define MDCR_EnPMSN_BIT		(ULL(1) << 36)
+#define MDCR_MPMX_BIT		(ULL(1) << 35)
+#define MDCR_MCCD_BIT		(ULL(1) << 34)
 #define MDCR_MTPME_BIT		(ULL(1) << 28)
+#define MDCR_TDCC_BIT		(ULL(1) << 27)
 #define MDCR_SCCD_BIT		(ULL(1) << 23)
+#define MDCR_EPMAD_BIT		(ULL(1) << 21)
+#define MDCR_EDAD_BIT		(ULL(1) << 20)
+#define MDCR_TTRF_BIT		(ULL(1) << 19)
+#define MDCR_STE_BIT		(ULL(1) << 18)
 #define MDCR_SPME_BIT		(ULL(1) << 17)
 #define MDCR_SDD_BIT		(ULL(1) << 16)
 #define MDCR_SPD32(x)		((x) << 14)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index f759983..b610b37 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,8 +113,13 @@
 	 *
 	 * MDCR_EL3.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
 	 *  prohibited in Secure state. This bit is RES0 in versions of the
-	 *  architecture earlier than ARMv8.5, setting it to 1 doesn't have any
-	 *  effect on them.
+	 *  architecture with FEAT_PMUv3p5 not implemented, setting it to 1
+	 *  doesn't have any effect on them.
+	 *
+	 * MDCR_EL3.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
+	 *  prohibited in EL3. This bit is RES0 in versions of the
+	 *  architecture with FEAT_PMUv3p7 not implemented, setting it to 1
+	 *  doesn't have any effect on them.
 	 *
 	 * MDCR_EL3.SPME: Set to zero so that event counting by the programmable
 	 *  counters PMEVCNTR<n>_EL0 is prohibited in Secure state. If ARMv8.2
@@ -124,9 +129,9 @@
 	 * ---------------------------------------------------------------------
 	 */
 	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
-		      MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT) & \
-		    ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | MDCR_TDA_BIT | \
-		      MDCR_TPM_BIT))
+		      MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
+		      MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
+		      MDCR_TDA_BIT | MDCR_TPM_BIT))
 
 	msr	mdcr_el3, x0
 
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
index 7611f01..834a80f 100644
--- a/include/drivers/mmc.h
+++ b/include/drivers/mmc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -60,10 +60,16 @@
 #define CMD_EXTCSD_PARTITION_CONFIG	179
 #define CMD_EXTCSD_BUS_WIDTH		183
 #define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_PART_SWITCH_TIME	199
 #define CMD_EXTCSD_SEC_CNT		212
 
+#define EXT_CSD_PART_CONFIG_ACC_MASK	GENMASK(2, 0)
 #define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
-#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+#define PART_CFG_BOOT_PARTITION1_ACCESS (U(1) << 0)
+#define PART_CFG_BOOT_PART_EN_MASK		GENMASK(5, 3)
+#define PART_CFG_BOOT_PART_EN_SHIFT		3
+#define PART_CFG_CURRENT_BOOT_PARTITION(x)	(((x) & PART_CFG_BOOT_PART_EN_MASK) >> \
+	PART_CFG_BOOT_PART_EN_SHIFT)
 
 /* Values in EXT CSD register */
 #define MMC_BUS_WIDTH_1			U(0)
@@ -230,6 +236,7 @@
 size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
 size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
 size_t mmc_rpmb_erase_blocks(int lba, size_t size);
+size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size);
 int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
 	     unsigned int width, unsigned int flags,
 	     struct mmc_device_info *device_info);
diff --git a/include/drivers/st/io_mmc.h b/include/drivers/st/io_mmc.h
index b35b4b5..6179e89 100644
--- a/include/drivers/st/io_mmc.h
+++ b/include/drivers/st/io_mmc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,10 @@
 
 #include <drivers/io/io_driver.h>
 
+struct io_mmc_dev_spec {
+	bool use_boot_part;
+};
+
 int register_io_dev_mmc(const io_dev_connector_t **dev_con);
 
 #endif /* IO_MMC_H */
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
new file mode 100644
index 0000000..6a4cfdf
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A510_H
+#define CORTEX_A510_H
+
+#define CORTEX_A510_MIDR					U(0x410FD460)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A510_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A510_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A510_H */
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
new file mode 100644
index 0000000..44c540c
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A710_H
+#define CORTEX_A710_H
+
+#define CORTEX_A710_MIDR					U(0x410FD470)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A710_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A710_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_klein.h b/include/lib/cpus/aarch64/cortex_klein.h
deleted file mode 100644
index 729b3bf..0000000
--- a/include/lib/cpus/aarch64/cortex_klein.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_KLEIN_H
-#define CORTEX_KLEIN_H
-
-#define CORTEX_KLEIN_MIDR					U(0x410FD460)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_KLEIN_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_KLEIN_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_KLEIN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_KLEIN_H */
diff --git a/include/lib/cpus/aarch64/cortex_matterhorn.h b/include/lib/cpus/aarch64/cortex_matterhorn.h
deleted file mode 100644
index 0185533..0000000
--- a/include/lib/cpus/aarch64/cortex_matterhorn.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_MATTERHORN_H
-#define CORTEX_MATTERHORN_H
-
-#define CORTEX_MATTERHORN_MIDR					U(0x410FD470)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MATTERHORN_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MATTERHORN_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define CORTEX_MATTERHORN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_MATTERHORN_H */
diff --git a/include/lib/cpus/aarch64/cortex_matterhorn_elp_arm.h b/include/lib/cpus/aarch64/cortex_matterhorn_elp_arm.h
deleted file mode 100644
index 309578e..0000000
--- a/include/lib/cpus/aarch64/cortex_matterhorn_elp_arm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_MATTERHORN_ELP_ARM_H
-#define CORTEX_MATTERHORN_ELP_ARM_H
-
-#define CORTEX_MATTERHORN_ELP_ARM_MIDR					U(0x410FD480)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MATTERHORN_ELP_ARM_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MATTERHORN_ELP_ARM_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define CORTEX_MATTERHORN_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_MATTERHORN_ELP_ARM_H */
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
new file mode 100644
index 0000000..9ce1223
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X2_H
+#define CORTEX_X2_H
+
+#define CORTEX_X2_MIDR						U(0x410FD480)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUECTLR_EL1					S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT			U(1)
+
+#endif /* CORTEX_X2_H */
diff --git a/include/plat/marvell/armada/a3k/common/plat_marvell.h b/include/plat/marvell/armada/a3k/common/plat_marvell.h
index ea7cdcd..cb31481 100644
--- a/include/plat/marvell/armada/a3k/common/plat_marvell.h
+++ b/include/plat/marvell/armada/a3k/common/plat_marvell.h
@@ -100,4 +100,6 @@
 
 const mmap_region_t *plat_marvell_get_mmap(void);
 
+uint32_t get_ref_clk(void);
+
 #endif /* PLAT_MARVELL_H */
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
new file mode 100644
index 0000000..3310322
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a510.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex A510 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex A510 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a510_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A510_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_A510_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a510_core_pwr_dwn
+
+	/*
+	 * Errata printing function for Cortex A510. Must follow AAPCS.
+	 */
+#if REPORT_ERRATA
+func cortex_a510_errata_report
+	ret
+endfunc cortex_a510_errata_report
+#endif
+
+func cortex_a510_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_a510_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A510 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a510_regs, "aS"
+cortex_a510_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a510_cpu_reg_dump
+	adr	x6, cortex_a510_regs
+	mrs	x8, CORTEX_A510_CPUECTLR_EL1
+	ret
+endfunc cortex_a510_cpu_reg_dump
+
+declare_cpu_ops cortex_a510, CORTEX_A510_MIDR, \
+	cortex_a510_reset_func, \
+	cortex_a510_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
new file mode 100644
index 0000000..4f979f8
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a710.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex A710 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex A710 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a710_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A710_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_A710_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a710_core_pwr_dwn
+
+	/*
+	 * Errata printing function for Cortex A710. Must follow AAPCS.
+	 */
+#if REPORT_ERRATA
+func cortex_a710_errata_report
+	ret
+endfunc cortex_a710_errata_report
+#endif
+
+func cortex_a710_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_a710_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A710 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a710_regs, "aS"
+cortex_a710_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a710_cpu_reg_dump
+	adr	x6, cortex_a710_regs
+	mrs	x8, CORTEX_A710_CPUECTLR_EL1
+	ret
+endfunc cortex_a710_cpu_reg_dump
+
+declare_cpu_ops cortex_a710, CORTEX_A710_MIDR, \
+	cortex_a710_reset_func, \
+	cortex_a710_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_klein.S b/lib/cpus/aarch64/cortex_klein.S
deleted file mode 100644
index d3a8ab4..0000000
--- a/lib/cpus/aarch64/cortex_klein.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_klein.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Klein must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Klein supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_klein_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_KLEIN_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_KLEIN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_KLEIN_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_klein_core_pwr_dwn
-
-	/*
-	 * Errata printing function for Cortex Klein. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_klein_errata_report
-	ret
-endfunc cortex_klein_errata_report
-#endif
-
-func cortex_klein_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_klein_reset_func
-
-	/* ---------------------------------------------
-	 * This function provides Cortex-Klein specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_klein_regs, "aS"
-cortex_klein_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_klein_cpu_reg_dump
-	adr	x6, cortex_klein_regs
-	mrs	x8, CORTEX_KLEIN_CPUECTLR_EL1
-	ret
-endfunc cortex_klein_cpu_reg_dump
-
-declare_cpu_ops cortex_klein, CORTEX_KLEIN_MIDR, \
-	cortex_klein_reset_func, \
-	cortex_klein_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_matterhorn.S b/lib/cpus/aarch64/cortex_matterhorn.S
deleted file mode 100644
index 4156f3c..0000000
--- a/lib/cpus/aarch64/cortex_matterhorn.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_matterhorn.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Matterhorn must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Matterhorn supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_matterhorn_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_MATTERHORN_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_MATTERHORN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_MATTERHORN_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_matterhorn_core_pwr_dwn
-
-	/*
-	 * Errata printing function for Cortex Matterhorn. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_matterhorn_errata_report
-	ret
-endfunc cortex_matterhorn_errata_report
-#endif
-
-func cortex_matterhorn_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_matterhorn_reset_func
-
-	/* ---------------------------------------------
-	 * This function provides Cortex-Matterhorn specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_matterhorn_regs, "aS"
-cortex_matterhorn_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_matterhorn_cpu_reg_dump
-	adr	x6, cortex_matterhorn_regs
-	mrs	x8, CORTEX_MATTERHORN_CPUECTLR_EL1
-	ret
-endfunc cortex_matterhorn_cpu_reg_dump
-
-declare_cpu_ops cortex_matterhorn, CORTEX_MATTERHORN_MIDR, \
-	cortex_matterhorn_reset_func, \
-	cortex_matterhorn_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_matterhorn_elp_arm.S b/lib/cpus/aarch64/cortex_matterhorn_elp_arm.S
deleted file mode 100644
index b0f81a2..0000000
--- a/lib/cpus/aarch64/cortex_matterhorn_elp_arm.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_matterhorn_elp_arm.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Matterhorn ELP ARM must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Matterhorn ELP ARM supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_matterhorn_elp_arm_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_MATTERHORN_ELP_ARM_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_MATTERHORN_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_MATTERHORN_ELP_ARM_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_matterhorn_elp_arm_core_pwr_dwn
-
-	/*
-	 * Errata printing function for Cortex Matterhorn_elp_arm. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_matterhorn_elp_arm_errata_report
-	ret
-endfunc cortex_matterhorn_elp_arm_errata_report
-#endif
-
-func cortex_matterhorn_elp_arm_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_matterhorn_elp_arm_reset_func
-
-	/* ---------------------------------------------
-	 * This function provides Cortex-Matterhorn_elp_arm specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_matterhorn_elp_arm_regs, "aS"
-cortex_matterhorn_elp_arm_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_matterhorn_elp_arm_cpu_reg_dump
-	adr	x6, cortex_matterhorn_elp_arm_regs
-	mrs	x8, CORTEX_MATTERHORN_ELP_ARM_CPUECTLR_EL1
-	ret
-endfunc cortex_matterhorn_elp_arm_cpu_reg_dump
-
-declare_cpu_ops cortex_matterhorn_elp_arm, CORTEX_MATTERHORN_ELP_ARM_MIDR, \
-	cortex_matterhorn_elp_arm_reset_func, \
-	cortex_matterhorn_elp_arm_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
new file mode 100644
index 0000000..87a9bdf
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_x2.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex X2 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex X2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x2_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_X2_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_X2_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_x2_core_pwr_dwn
+
+	/*
+	 * Errata printing function for Cortex X2. Must follow AAPCS.
+	 */
+#if REPORT_ERRATA
+func cortex_x2_errata_report
+	ret
+endfunc cortex_x2_errata_report
+#endif
+
+func cortex_x2_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_x2_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex X2 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_x2_regs, "aS"
+cortex_x2_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_x2_cpu_reg_dump
+	adr	x6, cortex_x2_regs
+	mrs	x8, CORTEX_X2_CPUECTLR_EL1
+	ret
+endfunc cortex_x2_cpu_reg_dump
+
+declare_cpu_ops cortex_x2, CORTEX_X2_MIDR, \
+	cortex_x2_reset_func, \
+	cortex_x2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 730b09b..bd8f85f 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -144,7 +144,7 @@
 	 * If cpu_ops for the MIDR_EL1 cannot be found and
 	 * SUPPORT_UNKNOWN_MPID is enabled, it will try to look for a
 	 * default cpu_ops with an MIDR value of 0.
-	 * (Implementation number 0x0 should be reseverd for software use
+	 * (Implementation number 0x0 should be reserved for software use
 	 * and therefore no clashes should happen with that default value).
 	 *
 	 * Return :
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 2443001..81d793b 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,7 +49,7 @@
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
  * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
- * cm_e1_sysreg_context_restore().
+ * cm_el1_sysregs_context_restore().
  ******************************************************************************/
 void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 7daf30d..0ec9ffd 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -697,13 +697,14 @@
 	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
 
 	/* ----------------------------------------------------------
-	 * Check if earlier initialization MDCR_EL3.SCCD to 1 failed,
-	 * meaning that ARMv8-PMU is not implemented and PMCR_EL0
-	 * should be saved in non-secure context.
+	 * Check if earlier initialization MDCR_EL3.SCCD/MCCD to 1
+	 * failed, meaning that FEAT_PMUv3p5/7 is not implemented and
+	 * PMCR_EL0 should be saved in non-secure context.
 	 * ----------------------------------------------------------
 	 */
+	mov_imm	x10, (MDCR_SCCD_BIT | MDCR_MCCD_BIT)
 	mrs	x9, mdcr_el3
-	tst	x9, #MDCR_SCCD_BIT
+	tst	x9, x10
 	bne	1f
 
 	/* Secure Cycle Counter is not disabled */
@@ -792,13 +793,14 @@
 
 	/* ----------------------------------------------------------
 	 * Back to Non-secure state.
-	 * Check if earlier initialization MDCR_EL3.SCCD to 1 failed,
-	 * meaning that ARMv8-PMU is not implemented and PMCR_EL0
-	 * should be restored from non-secure context.
+	 * Check if earlier initialization MDCR_EL3.SCCD/MCCD to 1
+	 * failed, meaning that FEAT_PMUv3p5/7 is not implemented and
+	 * PMCR_EL0 should be restored from non-secure context.
 	 * ----------------------------------------------------------
 	 */
+	mov_imm	x1, (MDCR_SCCD_BIT | MDCR_MCCD_BIT)
 	mrs	x0, mdcr_el3
-	tst	x0, #MDCR_SCCD_BIT
+	tst	x0, x1
 	bne	2f
 	ldr	x0, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
 	msr	pmcr_el0, x0
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index e0e4298..96023b6 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -60,7 +60,7 @@
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
  * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
- * cm_e1_sysreg_context_restore().
+ * cm_el1_sysregs_context_restore().
  ******************************************************************************/
 void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
@@ -286,7 +286,7 @@
 
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
-	 * and other EL2 registers are set up by cm_prepare_ns_entry() as they
+	 * and other EL2 registers are set up by cm_prepare_el3_exit() as they
 	 * are not part of the stored cpu_context.
 	 */
 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
diff --git a/package-lock.json b/package-lock.json
index 4967107..46d8bf3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1922,9 +1922,9 @@
       }
     },
     "trim-newlines": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz",
-      "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
       "dev": true
     },
     "trim-off-newlines": {
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 4e38751..f1fd777 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -67,8 +67,8 @@
 				lib/cpus/aarch64/cortex_a78_ae.S	\
 				lib/cpus/aarch64/cortex_a65.S		\
 				lib/cpus/aarch64/cortex_a65ae.S		\
-				lib/cpus/aarch64/cortex_klein.S		\
-				lib/cpus/aarch64/cortex_matterhorn.S	\
+				lib/cpus/aarch64/cortex_a510.S		\
+				lib/cpus/aarch64/cortex_a710.S	\
 				lib/cpus/aarch64/cortex_makalu.S	\
 				lib/cpus/aarch64/cortex_makalu_elp_arm.S \
 				lib/cpus/aarch64/cortex_a78c.S
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
index 57d6792..088179b 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,6 @@
 			is_ffa_partition;
 			debug_name = "op-tee";
 			load_address = <0x6280000>;
-			smc_whitelist = <0xbe000000>;
 			vcpu_count = <8>;
 			mem_size = <1048576>;
 		};
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 14ad5f5..8ea6ba3 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -51,14 +51,14 @@
 			scp_bl2_uuid = "9766fd3d-89be-e849-ae5d-78a140608213";
 			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
 			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
-			bl32_extra1_uuid = "0b70c28b-2a5a-7840-9f65-0a5682738288";
+			bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
 			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
 			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
 			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
 			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
 			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
-			t_key_cert_uuid = "827ee890-f860-e411-a1b4-77a721b4f94c";
+			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
 			scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014";
 			soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8";
 			tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04";
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index b58a0d2..10258ad 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -131,8 +131,8 @@
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/cortex_a78_ae.S	\
-					lib/cpus/aarch64/cortex_klein.S		\
-					lib/cpus/aarch64/cortex_matterhorn.S	\
+					lib/cpus/aarch64/cortex_a510.S		\
+					lib/cpus/aarch64/cortex_a710.S	\
 					lib/cpus/aarch64/cortex_makalu.S	\
 					lib/cpus/aarch64/cortex_makalu_elp_arm.S \
 					lib/cpus/aarch64/cortex_a65.S		\
diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
index 221039c..0830d5c 100644
--- a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
@@ -27,8 +27,28 @@
 			debug_name = "op-tee";
 			load_address = <0xfd280000>;
 			vcpu_count = <8>;
-			mem_size = <30928896>; /* 32MB TZC DRAM - SPMC region */
+#ifdef TS_SP_FW_CONFIG
+			mem_size = <26738688>; /* 25MB TZC DRAM */
+#else
+			mem_size = <30928896>; /* 29MB TZC DRAM */
+#endif
 		};
+#ifdef TS_SP_FW_CONFIG
+		vm2 {
+			is_ffa_partition;
+			debug_name = "secure-storage";
+			load_address = <0xfee00000>;
+			vcpu_count = <1>;
+			mem_size = <2097152>; /* 2MB TZC DRAM */
+		};
+		vm3 {
+			is_ffa_partition;
+			debug_name = "crypto";
+			load_address = <0xfec00000>;
+			vcpu_count = <1>;
+			mem_size = <2097152>; /* 2MB TZC DRAM */
+		};
+#endif
 	};
 
 	cpus {
diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
index de5f95d..38fd0e0 100644
--- a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
+++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +27,16 @@
 
 	secure-partitions {
 		compatible = "arm,sp";
+#ifdef TS_SP_FW_CONFIG
+		secure-storage {
+		       uuid = "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14";
+		       load-address = <0xfee00000>;
+		};
+		crypto {
+		       uuid = "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0";
+		       load-address = <0xfec00000>;
+		};
+#endif
 #if OPTEE_SP_FW_CONFIG
 		op-tee {
 		       uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 20ea6e3..814ccd3 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -43,9 +43,9 @@
 
 PLAT_INCLUDES		+=	-I${TC0_BASE}/include/
 
-TC0_CPU_SOURCES	:=	lib/cpus/aarch64/cortex_klein.S         \
-			lib/cpus/aarch64/cortex_matterhorn.S \
-			lib/cpus/aarch64/cortex_matterhorn_elp_arm.S
+TC0_CPU_SOURCES	:=	lib/cpus/aarch64/cortex_a510.S         \
+			lib/cpus/aarch64/cortex_a710.S \
+			lib/cpus/aarch64/cortex_x2.S
 
 INTERCONNECT_SOURCES	:=	${TC0_BASE}/tc0_interconnect.c
 
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 7d9fd6c..946b732 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -151,10 +151,10 @@
 	 */
 	mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTCTLBASE_CNTFRQ, freq_val);
 
-#if defined(PLAT_juno) || defined(PLAT_n1sdp)
+#if defined(PLAT_juno) || defined(PLAT_n1sdp) || defined(PLAT_morello)
 	/*
 	 * Initialize CNTFRQ register in Non-secure CNTBase frame.
-	 * This is only required for Juno and N1SDP, because they do not
+	 * This is required for Juno, N1SDP and Morello because they do not
 	 * follow ARM ARM in that the value updated in CNTFRQ is not
 	 * reflected in CNTBASEN_CNTFRQ. Hence update the value manually.
 	 */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 1e2054f..8baf4ee 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -65,6 +65,8 @@
 override NEED_BL2U		:=	no
 override ARM_BL31_IN_DRAM	:=	1
 override ARM_PLAT_MT		:=	1
+override PSCI_EXTENDED_STATE_ID	:=	1
+override ARM_RECOM_STATE_ID_ENC	:=	1
 
 # System coherency is managed in hardware
 HW_ASSISTED_COHERENCY	:=	1
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index f9f5577..d4b3425 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -14,6 +14,7 @@
 #include <common/runtime_svc.h>
 #include <imx_sip_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
 #include <sci/sci.h>
 
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
@@ -145,6 +146,37 @@
 
 #endif /* defined(PLAT_imx8qm) || defined(PLAT_imx8qx) */
 
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+int imx_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    void *handle)
+{
+	uint32_t val;
+
+	switch (x1) {
+	case IMX_SIP_SRC_SET_SECONDARY_BOOT:
+		if (x2 != 0U) {
+			mmio_setbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
+					SRC_GPR10_PERSIST_SECONDARY_BOOT);
+		} else {
+			mmio_clrbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
+					SRC_GPR10_PERSIST_SECONDARY_BOOT);
+		}
+		break;
+	case IMX_SIP_SRC_IS_SECONDARY_BOOT:
+		val = mmio_read_32(IMX_SRC_BASE + SRC_GPR10_OFFSET);
+		return !!(val & SRC_GPR10_PERSIST_SECONDARY_BOOT);
+	default:
+		return SMC_UNK;
+
+	};
+
+	return 0;
+}
+#endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
+
 static uint64_t imx_get_commit_hash(u_register_t x2,
 		    u_register_t x3,
 		    u_register_t x4)
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 20e1479..fd54820 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -48,6 +48,11 @@
 	case IMX_SIP_MISC_SET_TEMP:
 		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
 #endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+	case IMX_SIP_SRC:
+		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
+		break;
+#endif
 	case  IMX_SIP_BUILDINFO:
 		SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
 	default:
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 0a2d750..6c7a760 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -17,6 +17,10 @@
 #define IMX_SIP_BUILDINFO			0xC2000003
 #define IMX_SIP_BUILDINFO_GET_COMMITHASH	0x00
 
+#define IMX_SIP_SRC			0xC2000005
+#define IMX_SIP_SRC_SET_SECONDARY_BOOT	0x10
+#define IMX_SIP_SRC_IS_SECONDARY_BOOT	0x11
+
 #define IMX_SIP_GET_SOC_INFO		0xC2000006
 
 #define IMX_SIP_WAKEUP_SRC		0xC2000009
@@ -38,6 +42,11 @@
 			 u_register_t x2, u_register_t x3);
 #endif
 
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+int imx_src_handler(uint32_t smc_fid, u_register_t x1,
+		    u_register_t x2, u_register_t x3, void *handle);
+#endif
+
 #if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
 int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
 			u_register_t x2, u_register_t x3);
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index ec915ad..f8efa56 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -124,6 +124,8 @@
 #define SRC_OTG1PHY_SCR			U(0x20)
 #define SRC_OTG2PHY_SCR			U(0x24)
 #define SRC_GPR1_OFFSET			U(0x74)
+#define SRC_GPR10_OFFSET		U(0x98)
+#define SRC_GPR10_PERSIST_SECONDARY_BOOT	BIT(30)
 
 #define SNVS_LPCR			U(0x38)
 #define SNVS_LPCR_SRTC_ENV		BIT(0)
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 9db3a13..6d6a865 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -103,6 +103,8 @@
 #define SRC_OTG1PHY_SCR			U(0x20)
 #define SRC_OTG2PHY_SCR			U(0x24)
 #define SRC_GPR1_OFFSET			U(0x74)
+#define SRC_GPR10_OFFSET		U(0x98)
+#define SRC_GPR10_PERSIST_SECONDARY_BOOT	BIT(30)
 
 #define SNVS_LPCR			U(0x38)
 #define SNVS_LPCR_SRTC_ENV		BIT(0)
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 79097f3..7d95e48 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -38,6 +38,7 @@
 				-I$/drivers/arm/gic/common/
 
 PLAT_BL_COMMON_SOURCES	:=	$(PLAT_COMMON_BASE)/aarch64/a3700_common.c \
+				$(PLAT_COMMON_BASE)/aarch64/a3700_clock.S \
 				$(MARVELL_DRV_BASE)/uart/a3700_console.S
 
 BL1_SOURCES		+=	$(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
diff --git a/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S b/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S
new file mode 100644
index 0000000..f79516f
--- /dev/null
+++ b/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+
+/*
+ * Below address in used only for reading, therefore no problem with concurrent
+ * Linux access.
+ */
+#define MVEBU_TEST_PIN_LATCH_N (MVEBU_NB_GPIO_REG_BASE + 0x8)
+ #define MVEBU_XTAL_MODE_MASK		BIT(9)
+
+	/* -----------------------------------------------------
+	 * uint32_t get_ref_clk (void);
+	 *
+	 * returns reference clock in MHz (25 or 40)
+	 * -----------------------------------------------------
+	 */
+.globl	get_ref_clk
+func get_ref_clk
+	mov_imm	x0, MVEBU_TEST_PIN_LATCH_N
+	ldr	w0, [x0]
+	tst	w0, #MVEBU_XTAL_MODE_MASK
+	bne	40
+	mov	w0, #25
+	ret
+40:
+	mov	w0, #40
+	ret
+endfunc get_ref_clk
diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h
index 057ee2e..f19d96b 100644
--- a/plat/marvell/armada/a3k/common/include/platform_def.h
+++ b/plat/marvell/armada/a3k/common/include/platform_def.h
@@ -163,14 +163,7 @@
 /*
  * PL011 related constants
  */
-#define PLAT_MARVELL_BOOT_UART_BASE		(MVEBU_REGS_BASE + 0x12000)
-#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ	25804800
-
-#define PLAT_MARVELL_CRASH_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
-
-#define PLAT_MARVELL_BL31_RUN_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+#define PLAT_MARVELL_UART_BASE			(MVEBU_REGS_BASE + 0x12000)
 
 /* Required platform porting definitions */
 #define PLAT_MAX_PWR_LVL			MPIDR_AFFLVL1
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
index 5147dd5..eb00874 100644
--- a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
@@ -41,8 +41,8 @@
 	len = sizeof(system_off_now);
 	system_off_now[len - 1] = add_xor_checksum(system_off_now, len);
 
-	console_16550_register(PLAT_MARVELL_BOOT_UART_BASE + 0x100,
-		PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, 115200, &console);
+	console_16550_register(PLAT_MARVELL_UART_BASE + 0x100,
+		PLAT_MARVELL_UART_CLK_IN_HZ, 115200, &console);
 
 	/* Send system_off_now to console */
 	for (i = 0; i < len; i++) {
diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h
index 7d85059..45860ba 100644
--- a/plat/marvell/armada/a8k/common/include/platform_def.h
+++ b/plat/marvell/armada/a8k/common/include/platform_def.h
@@ -168,14 +168,8 @@
 /*
  * PL011 related constants
  */
-#define PLAT_MARVELL_BOOT_UART_BASE		(MVEBU_REGS_BASE + 0x512000)
-#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ	200000000
-
-#define PLAT_MARVELL_CRASH_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
-
-#define PLAT_MARVELL_BL31_RUN_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+#define PLAT_MARVELL_UART_BASE			(MVEBU_REGS_BASE + 0x512000)
+#define PLAT_MARVELL_UART_CLK_IN_HZ		200000000
 
 /* Recovery image enable */
 #define PLAT_RECOVERY_IMAGE_ENABLE		0
diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S
index b798f17..3038ec0 100644
--- a/plat/marvell/armada/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S
@@ -63,8 +63,16 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
-	mov_imm	x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
+#ifdef PLAT_a3700
+	mov	x1, x30
+	bl	get_ref_clk
+	mov	x30, x1
+	mov_imm	x1, 1000000
+	mul	x1, x0, x1
+#else
+	mov_imm	x1, PLAT_MARVELL_UART_CLK_IN_HZ
+#endif
+	mov_imm	x0, PLAT_MARVELL_UART_BASE
 	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
 #ifdef PLAT_a3700
 	b	console_a3700_core_init
@@ -81,7 +89,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov_imm	x1, PLAT_MARVELL_CRASH_UART_BASE
+	mov_imm	x1, PLAT_MARVELL_UART_BASE
 #ifdef PLAT_a3700
 
 	b	console_a3700_core_putc
@@ -99,7 +107,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
+	mov_imm	x0, PLAT_MARVELL_UART_BASE
 #ifdef PLAT_a3700
 	b	console_a3700_core_flush
 #else
diff --git a/plat/marvell/armada/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c
index c84b004..ef54bff 100644
--- a/plat/marvell/armada/common/marvell_console.c
+++ b/plat/marvell/armada/common/marvell_console.c
@@ -14,6 +14,7 @@
 
 #ifdef PLAT_a3700
 #include <drivers/marvell/uart/a3700_console.h>
+#define PLAT_MARVELL_UART_CLK_IN_HZ (get_ref_clk() * 1000000)
 #define console_marvell_register console_a3700_register
 #else
 #include <drivers/ti/uart/uart_16550.h>
@@ -31,8 +32,8 @@
 void marvell_console_boot_init(void)
 {
 	int rc =
-	console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
-				 PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+	console_marvell_register(PLAT_MARVELL_UART_BASE,
+				 PLAT_MARVELL_UART_CLK_IN_HZ,
 				 MARVELL_CONSOLE_BAUDRATE,
 				 &marvell_boot_console);
 	if (rc == 0) {
@@ -58,8 +59,8 @@
 void marvell_console_runtime_init(void)
 {
 	int rc =
-	console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
-				 PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+	console_marvell_register(PLAT_MARVELL_UART_BASE,
+				 PLAT_MARVELL_UART_CLK_IN_HZ,
 				 MARVELL_CONSOLE_BAUDRATE,
 				 &marvell_runtime_console);
 	if (rc == 0)
diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
index fca6913..d9a79c4 100644
--- a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
+++ b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
@@ -26,12 +26,30 @@
 	while (retry != 0) {
 		udelay(WAIT_IDLE_POLLING_DELAY_US);
 		reg_rdata = mmio_read_32((uintptr_t)wacs_register);
-		if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_IDLE) {
+		/* if last read command timeout,clear vldclr bit
+		 * read command state machine:FSM_REQ-->wfdle-->WFVLDCLR;
+		 * write:FSM_REQ-->idle
+		 */
+		switch (GET_WACS_FSM(reg_rdata)) {
+		case SWINF_FSM_WFVLDCLR:
+			mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1);
+			INFO("WACS_FSM = SWINF_FSM_WFVLDCLR\n");
+			break;
+		case SWINF_FSM_WFDLE:
+			INFO("WACS_FSM = SWINF_FSM_WFDLE\n");
+			break;
+		case SWINF_FSM_REQ:
+			INFO("WACS_FSM = SWINF_FSM_REQ\n");
+			break;
+		case SWINF_FSM_IDLE:
+			goto done;
+		default:
 			break;
 		}
 		retry--;
 	};
 
+done:
 	if (retry == 0) {
 		/* timeout */
 		return E_PWR_WAIT_IDLE_TIMEOUT;
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
index d9541bd..26bed29 100644
--- a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
@@ -117,7 +117,7 @@
 			      NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
 	emi_mpu_set_protection(&region_info);
 
-	/* Forbidden All */
+	/* DSP protect address */
 	region_info.start = 0x40000000ULL;	/* dram base addr */
 	region_info.end = 0x1FFFF0000ULL;
 	region_info.region = 3;
@@ -128,6 +128,17 @@
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
 	emi_mpu_set_protection(&region_info);
 
+	/* Forbidden All */
+	region_info.start = 0x40000000ULL;	/* dram base addr */
+	region_info.end = 0x1FFFF0000ULL;
+	region_info.region = 4;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
+	emi_mpu_set_protection(&region_info);
+
 	dump_emi_mpu_regions();
 }
 
diff --git a/plat/mediatek/mt8195/aarch64/platform_common.c b/plat/mediatek/mt8195/aarch64/platform_common.c
index 745e547..a9314ea 100644
--- a/plat/mediatek/mt8195/aarch64/platform_common.c
+++ b/plat/mediatek/mt8195/aarch64/platform_common.c
@@ -17,6 +17,10 @@
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MTK_DEV_RNG2_BASE, MTK_DEV_RNG2_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DP_SEC_BASE, DP_SEC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(eDP_SEC_BASE, eDP_SEC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
 	{ 0 }
 };
 
diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.c b/plat/mediatek/mt8195/drivers/dp/mt_dp.c
new file mode 100644
index 0000000..7ab2194
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/dp/mt_dp.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mt_dp.h>
+#include <mtk_sip_svc.h>
+#include <platform_def.h>
+
+static uint32_t dp_write_sec_reg(uint32_t is_edp, uint32_t offset,
+				uint32_t value, uint32_t mask)
+{
+	uint32_t reg = (is_edp != 0U) ? eDP_SEC_BASE : DP_SEC_BASE;
+
+	mmio_clrsetbits_32(reg + offset, mask, value);
+
+	return mmio_read_32(reg + offset);
+}
+
+int32_t dp_secure_handler(uint64_t cmd, uint64_t para, uint32_t *val)
+{
+	int32_t ret = 0L;
+	uint32_t is_edp = 0UL;
+	uint32_t regval = 0UL;
+	uint32_t regmsk = 0UL;
+	uint32_t fldmask = 0UL;
+
+	if ((cmd > DP_ATF_CMD_COUNT) || (val == NULL)) {
+		INFO("dp_secure_handler error cmd 0x%llx\n", cmd);
+		return MTK_SIP_E_INVALID_PARAM;
+	}
+
+	switch (cmd) {
+	case DP_ATF_DP_VIDEO_UNMUTE:
+		INFO("[%s] DP_ATF_DP_VIDEO_UNMUTE\n", __func__);
+		is_edp = DP_ATF_TYPE_DP;
+		ret = MTK_SIP_E_SUCCESS;
+		break;
+	case DP_ATF_EDP_VIDEO_UNMUTE:
+		INFO("[%s] DP_ATF_EDP_VIDEO_UNMUTE\n", __func__);
+		is_edp = DP_ATF_TYPE_EDP;
+		ret = MTK_SIP_E_SUCCESS;
+		break;
+	default:
+		ret = MTK_SIP_E_INVALID_PARAM;
+		break;
+	}
+
+	if (ret == MTK_SIP_E_SUCCESS) {
+		regmsk = (VIDEO_MUTE_SEL_SECURE_FLDMASK |
+				VIDEO_MUTE_SW_SECURE_FLDMASK);
+		if (para > 0U) {
+			fldmask = VIDEO_MUTE_SW_SECURE_FLDMASK;
+		} else {
+			fldmask = 0;
+		}
+
+		regval = (VIDEO_MUTE_SEL_SECURE_FLDMASK | fldmask);
+		*val = dp_write_sec_reg(is_edp, DP_TX_SECURE_REG11,
+					regval, regmsk);
+	}
+
+	return ret;
+}
diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.h b/plat/mediatek/mt8195/drivers/dp/mt_dp.h
new file mode 100644
index 0000000..8157598
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/dp/mt_dp.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_DP_H
+#define MT_DP_H
+
+#define DP_TX_SECURE_REG11		(0x2c)
+
+#define VIDEO_MUTE_SEL_SECURE_FLDMASK	(0x10)
+#define VIDEO_MUTE_SW_SECURE_FLDMASK	(0x8)
+
+enum DP_ATF_HW_TYPE {
+	DP_ATF_TYPE_DP = 0,
+	DP_ATF_TYPE_EDP = 1
+};
+
+enum DP_ATF_CMD {
+	DP_ATF_DP_VIDEO_UNMUTE = 0x20,
+	DP_ATF_EDP_VIDEO_UNMUTE,
+	DP_ATF_CMD_COUNT
+};
+
+int32_t dp_secure_handler(uint64_t cmd, uint64_t para, uint32_t *val);
+
+#endif
diff --git a/plat/mediatek/mt8195/include/plat_sip_calls.h b/plat/mediatek/mt8195/include/plat_sip_calls.h
index 0e42322..181aec0 100644
--- a/plat/mediatek/mt8195/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8195/include/plat_sip_calls.h
@@ -10,6 +10,10 @@
 /*******************************************************************************
  * Plat SiP function constants
  ******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS    0
+#define MTK_PLAT_SIP_NUM_CALLS    2
+
+/* DP/eDP */
+#define MTK_SIP_DP_CONTROL_AARCH32	0x82000523
+#define MTK_SIP_DP_CONTROL_AARCH64	0xC2000523
 
 #endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index f6eb742..eaf5985 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -26,6 +26,14 @@
 #define SPM_BASE		(IO_PHYS + 0x00006000)
 
 /*******************************************************************************
+ * DP/eDP related constants
+ ******************************************************************************/
+#define eDP_SEC_BASE		(IO_PHYS + 0x0C504000)
+#define DP_SEC_BASE		(IO_PHYS + 0x0C604000)
+#define eDP_SEC_SIZE		0x1000
+#define DP_SEC_SIZE		0x1000
+
+/*******************************************************************************
  * GPIO related constants
  ******************************************************************************/
 #define GPIO_BASE		(IO_PHYS + 0x00005000)
diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c
index a1e3c36..99e1eb3 100644
--- a/plat/mediatek/mt8195/plat_sip_calls.c
+++ b/plat/mediatek/mt8195/plat_sip_calls.c
@@ -6,6 +6,9 @@
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <mt_dp.h>
+#include <mtk_sip_svc.h>
+#include "plat_sip_calls.h"
 
 uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid,
 				u_register_t x1,
@@ -16,7 +19,15 @@
 				void *handle,
 				u_register_t flags)
 {
+	int32_t ret;
+	uint32_t ret_val;
+
 	switch (smc_fid) {
+	case MTK_SIP_DP_CONTROL_AARCH32:
+	case MTK_SIP_DP_CONTROL_AARCH64:
+		ret = dp_secure_handler(x1, x2, &ret_val);
+		SMC_RET2(handle, ret, ret_val);
+		break;
 	default:
 		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
 		break;
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 4d3ad59..026cf41 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -12,6 +12,7 @@
                  -I${MTK_PLAT}/common/drivers/gpio/               \
                  -I${MTK_PLAT}/common/drivers/rtc/                \
                  -I${MTK_PLAT}/common/drivers/timer/              \
+                 -I${MTK_PLAT_SOC}/drivers/dp/                  \
                  -I${MTK_PLAT_SOC}/drivers/gpio/                  \
                  -I${MTK_PLAT_SOC}/drivers/mcdi/                  \
                  -I${MTK_PLAT_SOC}/drivers/pmic/                  \
@@ -50,6 +51,7 @@
                 ${MTK_PLAT_SOC}/aarch64/platform_common.c             \
                 ${MTK_PLAT_SOC}/aarch64/plat_helpers.S                \
                 ${MTK_PLAT_SOC}/bl31_plat_setup.c                     \
+                ${MTK_PLAT_SOC}/drivers/dp/mt_dp.c                    \
                 ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c                 \
                 ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c              \
                 ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c          \
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 6dedc98..0a18d99 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -31,9 +31,11 @@
 #include <plat/common/platform.h>
 
 /* IO devices */
+#ifndef AARCH32_SP_OPTEE
 static const io_dev_connector_t *dummy_dev_con;
 static uintptr_t dummy_dev_handle;
 static uintptr_t dummy_dev_spec;
+#endif
 
 static uintptr_t image_dev_handle;
 static uintptr_t storage_dev_handle;
@@ -60,6 +62,30 @@
 	.block_size = MMC_BLOCK_SIZE,
 };
 
+#if STM32MP_EMMC_BOOT
+static io_block_spec_t emmc_boot_ssbl_block_spec = {
+	.offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
+	.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
+};
+
+static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
+	/* It's used as temp buffer in block driver */
+	.buffer = {
+		.offset = (size_t)&block_buffer,
+		.length = MMC_BLOCK_SIZE,
+	},
+	.ops = {
+		.read = mmc_boot_part_read_blocks,
+		.write = NULL,
+	},
+	.block_size = MMC_BLOCK_SIZE,
+};
+#endif
+
+static struct io_mmc_dev_spec mmc_device_spec = {
+	.use_boot_part = false,
+};
+
 static const io_dev_connector_t *mmc_dev_con;
 #endif /* STM32MP_SDMMC || STM32MP_EMMC */
 
@@ -102,9 +128,9 @@
 	.binary_type = OPTEE_HEADER_BINARY_TYPE,
 };
 
-static const struct stm32image_part_info optee_pager_partition_spec = {
-	.name = OPTEE_PAGER_IMAGE_NAME,
-	.binary_type = OPTEE_PAGER_BINARY_TYPE,
+static const struct stm32image_part_info optee_core_partition_spec = {
+	.name = OPTEE_CORE_IMAGE_NAME,
+	.binary_type = OPTEE_CORE_BINARY_TYPE,
 };
 
 static const struct stm32image_part_info optee_paged_partition_spec = {
@@ -118,11 +144,6 @@
 };
 #endif
 
-static const io_block_spec_t bl2_block_spec = {
-	.offset = BL2_BASE,
-	.length = STM32MP_BL2_SIZE,
-};
-
 static const struct stm32image_part_info bl33_partition_spec = {
 	.name = BL33_IMAGE_NAME,
 	.binary_type = BL33_BINARY_TYPE,
@@ -132,7 +153,7 @@
 	IMG_IDX_BL33,
 #ifdef AARCH32_SP_OPTEE
 	IMG_IDX_OPTEE_HEADER,
-	IMG_IDX_OPTEE_PAGER,
+	IMG_IDX_OPTEE_CORE,
 	IMG_IDX_OPTEE_PAGED,
 #endif
 	IMG_IDX_NUM
@@ -149,9 +170,9 @@
 		.name = OPTEE_HEADER_IMAGE_NAME,
 		.binary_type = OPTEE_HEADER_BINARY_TYPE,
 	},
-	.part_info[IMG_IDX_OPTEE_PAGER] = {
-		.name = OPTEE_PAGER_IMAGE_NAME,
-		.binary_type = OPTEE_PAGER_BINARY_TYPE,
+	.part_info[IMG_IDX_OPTEE_CORE] = {
+		.name = OPTEE_CORE_IMAGE_NAME,
+		.binary_type = OPTEE_CORE_BINARY_TYPE,
 	},
 	.part_info[IMG_IDX_OPTEE_PAGED] = {
 		.name = OPTEE_PAGED_IMAGE_NAME,
@@ -167,7 +188,9 @@
 
 static const io_dev_connector_t *stm32image_dev_con __unused;
 
+#ifndef AARCH32_SP_OPTEE
 static int open_dummy(const uintptr_t spec);
+#endif
 static int open_image(const uintptr_t spec);
 static int open_storage(const uintptr_t spec);
 
@@ -178,11 +201,6 @@
 };
 
 static const struct plat_io_policy policies[] = {
-	[BL2_IMAGE_ID] = {
-		.dev_handle = &dummy_dev_handle,
-		.image_spec = (uintptr_t)&bl2_block_spec,
-		.check = open_dummy
-	},
 #ifdef AARCH32_SP_OPTEE
 	[BL32_IMAGE_ID] = {
 		.dev_handle = &image_dev_handle,
@@ -191,7 +209,7 @@
 	},
 	[BL32_EXTRA1_IMAGE_ID] = {
 		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&optee_pager_partition_spec,
+		.image_spec = (uintptr_t)&optee_core_partition_spec,
 		.check = open_image
 	},
 	[BL32_EXTRA2_IMAGE_ID] = {
@@ -225,10 +243,12 @@
 	}
 };
 
+#ifndef AARCH32_SP_OPTEE
 static int open_dummy(const uintptr_t spec)
 {
 	return io_dev_init(dummy_dev_handle, 0);
 }
+#endif
 
 static int open_image(const uintptr_t spec)
 {
@@ -240,6 +260,38 @@
 	return io_dev_init(storage_dev_handle, 0);
 }
 
+#if STM32MP_EMMC_BOOT
+static uint32_t get_boot_part_ssbl_header(void)
+{
+	uint32_t magic = 0;
+	int io_result;
+	size_t bytes_read;
+
+	io_result = register_io_dev_block(&mmc_dev_con);
+	if (io_result != 0) {
+		panic();
+	}
+
+	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
+				&storage_dev_handle);
+	assert(io_result == 0);
+
+	io_result = io_open(storage_dev_handle, (uintptr_t) &emmc_boot_ssbl_block_spec,
+			    &image_dev_handle);
+	assert(io_result == 0);
+
+	io_result = io_read(image_dev_handle, (uintptr_t) &magic, sizeof(magic),
+			    &bytes_read);
+	assert(io_result == 0);
+	assert(bytes_read == sizeof(magic));
+
+	io_result = io_dev_close(storage_dev_handle);
+	assert(io_result == 0);
+
+	return magic;
+}
+#endif
+
 static void print_boot_device(boot_api_context_t *boot_context)
 {
 	switch (boot_context->boot_interface_selected) {
@@ -277,7 +329,8 @@
 	uint8_t idx;
 	struct stm32image_part_info *part;
 	struct stm32_sdmmc2_params params;
-	const partition_entry_t *entry;
+	const partition_entry_t *entry __unused;
+	uint32_t magic __unused;
 
 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
 
@@ -309,6 +362,26 @@
 		panic();
 	}
 
+	stm32image_dev_info_spec.device_size =
+		stm32_sdmmc2_mmc_get_device_size();
+
+#if STM32MP_EMMC_BOOT
+	magic = get_boot_part_ssbl_header();
+
+	if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
+		VERBOSE("%s, header found, jump to emmc load\n", __func__);
+		idx = IMG_IDX_BL33;
+		part = &stm32image_dev_info_spec.part_info[idx];
+		part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
+		part->bkp_offset = 0U;
+		mmc_device_spec.use_boot_part = true;
+
+		goto emmc_boot;
+	} else {
+		WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
+	}
+#endif
+
 	/* Open MMC as a block device to read GPT table */
 	io_result = register_io_dev_block(&mmc_dev_con);
 	if (io_result != 0) {
@@ -324,9 +397,6 @@
 	io_result = io_dev_close(storage_dev_handle);
 	assert(io_result == 0);
 
-	stm32image_dev_info_spec.device_size =
-		stm32_sdmmc2_mmc_get_device_size();
-
 	for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
 		part = &stm32image_dev_info_spec.part_info[idx];
 		entry = get_partition_entry(part->name);
@@ -339,6 +409,9 @@
 		part->bkp_offset = 0U;
 	}
 
+#if STM32MP_EMMC_BOOT
+emmc_boot:
+#endif
 	/*
 	 * Re-open MMC with io_mmc, for better perfs compared to
 	 * io_block.
@@ -346,7 +419,8 @@
 	io_result = register_io_dev_mmc(&mmc_dev_con);
 	assert(io_result == 0);
 
-	io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
+	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
+				&storage_dev_handle);
 	assert(io_result == 0);
 
 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
@@ -396,7 +470,7 @@
 	part->part_offset = STM32MP_NOR_TEED_OFFSET;
 	part->bkp_offset = 0U;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NOR_TEEX_OFFSET;
 	part->bkp_offset = 0U;
@@ -449,7 +523,7 @@
 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
 	part->bkp_offset = nand_dev_spec.erase_size;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
 	part->bkp_offset = nand_dev_spec.erase_size;
@@ -503,7 +577,7 @@
 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
 	part->bkp_offset = spi_nand_dev_spec.erase_size;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
 	part->bkp_offset = spi_nand_dev_spec.erase_size;
@@ -533,12 +607,14 @@
 		     boot_context->boot_partition_used_toboot);
 	}
 
+#ifndef AARCH32_SP_OPTEE
 	io_result = register_io_dev_dummy(&dummy_dev_con);
 	assert(io_result == 0);
 
 	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
 				&dummy_dev_handle);
 	assert(io_result == 0);
+#endif
 
 	switch (boot_context->boot_interface_selected) {
 #if STM32MP_SDMMC
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index b45f8fb..2d7d369 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -27,10 +27,10 @@
 
 #ifdef AARCH32_SP_OPTEE
 #define OPTEE_HEADER_IMAGE_NAME		"teeh"
+#define OPTEE_CORE_IMAGE_NAME		"teex"
 #define OPTEE_PAGED_IMAGE_NAME		"teed"
-#define OPTEE_PAGER_IMAGE_NAME		"teex"
 #define OPTEE_HEADER_BINARY_TYPE	U(0x20)
-#define OPTEE_PAGER_BINARY_TYPE		U(0x21)
+#define OPTEE_CORE_BINARY_TYPE		U(0x21)
 #define OPTEE_PAGED_BINARY_TYPE		U(0x22)
 #endif
 
@@ -88,6 +88,12 @@
  */
 #define PLAT_STM32MP_NS_IMAGE_OFFSET	BL33_BASE
 
+/*
+ * SSBL offset in case it's stored in eMMC boot partition.
+ * We can fix it to 256K because TF-A size can't be bigger than SRAM
+ */
+#define PLAT_EMMC_BOOT_SSBL_OFFSET		U(0x40000)
+
 /*******************************************************************************
  * DTB specific defines.
  ******************************************************************************/
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 50fb1b7..128dbc4 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -42,6 +42,7 @@
 STM32MP_RAW_NAND	?=	0
 STM32MP_SPI_NAND	?=	0
 STM32MP_SPI_NOR		?=	0
+STM32MP_EMMC_BOOT	?=	0
 
 ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \
 	${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
@@ -77,6 +78,7 @@
 		STM32MP_RAW_NAND \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
+		STM32MP_EMMC_BOOT \
 		PLAT_XLAT_TABLES_DYNAMIC \
 )))
 
@@ -93,6 +95,7 @@
 		STM32MP_RAW_NAND \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
+		STM32MP_EMMC_BOOT \
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_A_COPIES \
 		PLAT_PARTITION_MAX_ENTRIES \
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index b3365d9..ec433ff 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -62,156 +62,156 @@
 } zynqmp_devices[] = {
 	{
 		.id = 0x10,
-		.name = "3EG",
+		.name = "XCZU3EG",
 	},
 	{
 		.id = 0x10,
 		.ver = 0x2c,
-		.name = "3CG",
+		.name = "XCZU3CG",
 	},
 	{
 		.id = 0x11,
-		.name = "2EG",
+		.name = "XCZU2EG",
 	},
 	{
 		.id = 0x11,
 		.ver = 0x2c,
-		.name = "2CG",
+		.name = "XCZU2CG",
 	},
 	{
 		.id = 0x20,
-		.name = "5EV",
+		.name = "XCZU5EV",
 		.evexists = true,
 	},
 	{
 		.id = 0x20,
 		.ver = 0x100,
-		.name = "5EG",
+		.name = "XCZU5EG",
 		.evexists = true,
 	},
 	{
 		.id = 0x20,
 		.ver = 0x12c,
-		.name = "5CG",
+		.name = "XCZU5CG",
 	},
 	{
 		.id = 0x21,
-		.name = "4EV",
+		.name = "XCZU4EV",
 		.evexists = true,
 	},
 	{
 		.id = 0x21,
 		.ver = 0x100,
-		.name = "4EG",
+		.name = "XCZU4EG",
 		.evexists = true,
 	},
 	{
 		.id = 0x21,
 		.ver = 0x12c,
-		.name = "4CG",
+		.name = "XCZU4CG",
 	},
 	{
 		.id = 0x30,
-		.name = "7EV",
+		.name = "XCZU7EV",
 		.evexists = true,
 	},
 	{
 		.id = 0x30,
 		.ver = 0x100,
-		.name = "7EG",
+		.name = "XCZU7EG",
 		.evexists = true,
 	},
 	{
 		.id = 0x30,
 		.ver = 0x12c,
-		.name = "7CG",
+		.name = "XCZU7CG",
 	},
 	{
 		.id = 0x38,
-		.name = "9EG",
+		.name = "XCZU9EG",
 	},
 	{
 		.id = 0x38,
 		.ver = 0x2c,
-		.name = "9CG",
+		.name = "XCZU9CG",
 	},
 	{
 		.id = 0x39,
-		.name = "6EG",
+		.name = "XCZU6EG",
 	},
 	{
 		.id = 0x39,
 		.ver = 0x2c,
-		.name = "6CG",
+		.name = "XCZU6CG",
 	},
 	{
 		.id = 0x40,
-		.name = "11EG",
+		.name = "XCZU11EG",
 	},
 	{ /* For testing purpose only */
 		.id = 0x50,
 		.ver = 0x2c,
-		.name = "15CG",
+		.name = "XCZU15CG",
 	},
 	{
 		.id = 0x50,
-		.name = "15EG",
+		.name = "XCZU15EG",
 	},
 	{
 		.id = 0x58,
-		.name = "19EG",
+		.name = "XCZU19EG",
 	},
 	{
 		.id = 0x59,
-		.name = "17EG",
+		.name = "XCZU17EG",
 	},
 	{
 		.id = 0x60,
-		.name = "28DR",
+		.name = "XCZU28DR",
 	},
 	{
 		.id = 0x61,
-		.name = "21DR",
+		.name = "XCZU21DR",
 	},
 	{
 		.id = 0x62,
-		.name = "29DR",
+		.name = "XCZU29DR",
 	},
 	{
 		.id = 0x63,
-		.name = "23DR",
+		.name = "XCZU23DR",
 	},
 	{
 		.id = 0x64,
-		.name = "27DR",
+		.name = "XCZU27DR",
 	},
 	{
 		.id = 0x65,
-		.name = "25DR",
+		.name = "XCZU25DR",
 	},
 	{
 		.id = 0x66,
-		.name = "39DR",
+		.name = "XCZU39DR",
 	},
 	{
 		.id = 0x7d,
-		.name = "43DR",
+		.name = "XCZU43DR",
 	},
 	{
 		.id = 0x78,
-		.name = "46DR",
+		.name = "XCZU46DR",
 	},
 	{
 		.id = 0x7f,
-		.name = "47DR",
+		.name = "XCZU47DR",
 	},
 	{
 		.id = 0x7b,
-		.name = "48DR",
+		.name = "XCZU48DR",
 	},
 	{
 		.id = 0x7e,
-		.name = "49DR",
+		.name = "XCZU49DR",
 	},
 };
 
@@ -219,6 +219,8 @@
 #define ZYNQMP_PL_STATUS_MASK	BIT(ZYNQMP_PL_STATUS_BIT)
 #define ZYNQMP_CSU_VERSION_MASK	~(ZYNQMP_PL_STATUS_MASK)
 
+#define SILICON_ID_XCK26       0x4724093
+
 static char *zynqmp_get_silicon_idcode_name(void)
 {
 	uint32_t id, ver, chipid[2];
@@ -236,7 +238,7 @@
 	chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
 #else
 	if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
-		return "UNKN";
+		return "XCZUUNKN";
 #endif
 
 	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
@@ -250,8 +252,13 @@
 			break;
 	}
 
-	if (i >= ARRAY_SIZE(zynqmp_devices))
-		return "UNKN";
+	if (i >= ARRAY_SIZE(zynqmp_devices)) {
+		if (chipid[0] == SILICON_ID_XCK26) {
+			return "XCK26";
+		} else {
+			return "XCZUUNKN";
+		}
+	}
 
 	if (!zynqmp_devices[i].evexists)
 		return zynqmp_devices[i].name;
@@ -327,7 +334,7 @@
 		break;
 	}
 
-	NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x\n",
+	NOTICE("TF-A running on %s/%s v%d/RTL%d.%d at 0x%x\n",
 	       zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(),
 	       (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE);
 }
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 2796840..143385d 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -36,7 +36,7 @@
  * little space for growth.
  */
 #ifndef ZYNQMP_ATF_MEM_BASE
-#if !DEBUG && defined(SPD_none)
+#if !DEBUG && defined(SPD_none) && !SDEI_SUPPORT
 # define BL31_BASE			0xfffea000
 # define BL31_LIMIT			0xffffffff
 #else
@@ -91,6 +91,13 @@
 #define CACHE_WRITEBACK_SHIFT   6
 #define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
 
+#define ZYNQMP_SDEI_SGI_PRIVATE		U(8)
+
+/* Platform macros to support exception handling framework */
+#define PLAT_PRI_BITS			U(3)
+#define PLAT_SDEI_CRITICAL_PRI		0x10
+#define PLAT_SDEI_NORMAL_PRI		0x20
+
 #define PLAT_ARM_GICD_BASE	BASE_GICD_BASE
 #define PLAT_ARM_GICC_BASE	BASE_GICC_BASE
 /*
@@ -102,8 +109,6 @@
 #define PLAT_ARM_G1S_IRQ_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_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
 	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, \
@@ -124,8 +129,6 @@
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(IRQ_TTC3_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
 	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, \
@@ -142,6 +145,8 @@
 			GIC_INTR_CFG_EDGE)
 #endif
 
-#define PLAT_ARM_G0_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,	grp, \
+			GIC_INTR_CFG_EDGE)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 99a4beb..5e69151 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -14,6 +14,8 @@
 override GICV2_G0_FOR_EL3 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
 
+EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
+
 # Do not enable SVE
 ENABLE_SVE_FOR_NS	:= 0
 
@@ -107,6 +109,11 @@
 				plat/xilinx/zynqmp/pm_service/pm_api_clock.c	\
 				plat/xilinx/zynqmp/pm_service/pm_client.c
 
+ifeq (${SDEI_SUPPORT},1)
+BL31_SOURCES		+=	plat/xilinx/zynqmp/zynqmp_ehf.c			\
+				plat/xilinx/zynqmp/zynqmp_sdei.c
+endif
+
 BL31_CPPFLAGS		+=	-fno-jump-tables
 
 ifneq (${RESET_TO_BL31},1)
diff --git a/plat/xilinx/zynqmp/zynqmp_ehf.c b/plat/xilinx/zynqmp/zynqmp_ehf.c
new file mode 100644
index 0000000..fbf1ed0
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_ehf.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) Siemens AG, 2020-2021
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+
+/*
+ * Enumeration of priority levels on ARM platforms.
+ */
+ehf_pri_desc_t zynqmp_exceptions[] = {
+	/* Critical priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+	/* Normal priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(zynqmp_exceptions, ARRAY_SIZE(zynqmp_exceptions), PLAT_PRI_BITS);
diff --git a/plat/xilinx/zynqmp/zynqmp_sdei.c b/plat/xilinx/zynqmp/zynqmp_sdei.c
new file mode 100644
index 0000000..7e92b58
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_sdei.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) Siemens AG, 2020-2021
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <services/sdei.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+int arm_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	return (entrypoint < BL31_BASE || entrypoint > BL31_LIMIT) ? 0 : -1;
+}
+
+/* Private event mappings */
+static sdei_ev_map_t zynqmp_sdei_private[] = {
+	SDEI_DEFINE_EVENT_0(ZYNQMP_SDEI_SGI_PRIVATE),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t zynqmp_sdei_shared[] = {
+};
+
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+
+/* Export ARM SDEI events */
+REGISTER_SDEI_MAP(zynqmp_sdei_private, zynqmp_sdei_shared);
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 06039f0..e18d94c 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -108,9 +108,10 @@
 	cm_set_context(&(spmc_ctx->cpu_ctx), SECURE);
 
 	/* Restore the context assigned above */
-	cm_el1_sysregs_context_restore(SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(SECURE);
+#else
+	cm_el1_sysregs_context_restore(SECURE);
 #endif
 	cm_set_next_eret_context(SECURE);
 
@@ -118,9 +119,10 @@
 	rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
 
 	/* Save secure state */
-	cm_el1_sysregs_context_save(SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(SECURE);
+#else
+	cm_el1_sysregs_context_save(SECURE);
 #endif
 
 	return rc;
@@ -346,15 +348,23 @@
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
 
 	/* Save incoming security state */
-	cm_el1_sysregs_context_save(secure_state_in);
 #if SPMD_SPM_AT_SEL2
+	if (secure_state_in == NON_SECURE) {
+		cm_el1_sysregs_context_save(secure_state_in);
+	}
 	cm_el2_sysregs_context_save(secure_state_in);
+#else
+	cm_el1_sysregs_context_save(secure_state_in);
 #endif
 
 	/* Restore outgoing security state */
-	cm_el1_sysregs_context_restore(secure_state_out);
 #if SPMD_SPM_AT_SEL2
+	if (secure_state_out == NON_SECURE) {
+		cm_el1_sysregs_context_restore(secure_state_out);
+	}
 	cm_el2_sysregs_context_restore(secure_state_out);
+#else
+	cm_el1_sysregs_context_restore(secure_state_out);
 #endif
 	cm_set_next_eret_context(secure_state_out);