Merge changes Iaf21883b,I523c5d57,I57164923 into integration

* changes:
  fix(ufs): read and write attribute based on spec
  fix(ufs): disables controller if enabled
  refactor(ufs): adds a function for fdeviceinit
diff --git a/.commitlintrc.js b/.commitlintrc.js
index ed971a3..cfafbed 100644
--- a/.commitlintrc.js
+++ b/.commitlintrc.js
@@ -68,7 +68,6 @@
         "type-enum": [2, "always", types], /* Error */
 
         "scope-case": [2, "always", "lower-case"], /* Error */
-        "scope-empty": [2, "never"], /* Error */
         "scope-enum": [1, "always", scopes] /* Warning */
     },
 };
diff --git a/.gitignore b/.gitignore
index f524658..b005fab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,7 @@
 tools/stm32image/*.o
 tools/stm32image/stm32image
 tools/stm32image/stm32image.exe
-tools/sptool/sptool
-tools/sptool/sptool.exe
+tools/sptool/__pycache__/
 
 # GNU GLOBAL files
 GPATH
diff --git a/Makefile b/Makefile
index da3e493..16c85bc 100644
--- a/Makefile
+++ b/Makefile
@@ -135,6 +135,10 @@
 ifneq (${ENABLE_PIE},0)
         $(error ENABLE_RME does not support PIE)
 endif
+# RME doesn't support BRBE
+ifneq (${ENABLE_BRBE_FOR_NS},0)
+        $(error ENABLE_RME does not support BRBE.)
+endif
 # RME requires AARCH64
 ifneq (${ARCH},aarch64)
         $(error ENABLE_RME requires AArch64)
@@ -263,24 +267,24 @@
 # Determine if FEAT_SB is supported
 ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
 
-ifneq ($(findstring armclang,$(notdir $(CC))),)
-TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi $(march32-directive)
-TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi $(march64-directive)
-LD			=	$(LINKER)
-AS			=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP			=	$(CC) -E $(TF_CFLAGS_$(ARCH))
-PP			=	$(CC) -E $(TF_CFLAGS_$(ARCH))
-else ifneq ($(findstring clang,$(notdir $(CC))),)
-CLANG_CCDIR		=	$(if $(filter-out ./,$(dir $(CC))),$(dir $(CC)),)
-TF_CFLAGS_aarch32	=	$(target32-directive) $(march32-directive)
-TF_CFLAGS_aarch64	=	-target aarch64-elf $(march64-directive)
-LD			=	$(CLANG_CCDIR)ld.lld
-ifeq (, $(shell which $(LD)))
-$(error "No $(LD) in PATH, make sure it is installed or set LD to a different linker")
-endif
-AS			=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP			=	$(CC) -E
-PP			=	$(CC) -E
+ifneq ($(findstring clang,$(notdir $(CC))),)
+	ifneq ($(findstring armclang,$(notdir $(CC))),)
+		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi $(march32-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march64-directive)
+		LD			:=	$(LINKER)
+	else
+		TF_CFLAGS_aarch32	:=	$(target32-directive) $(march32-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march64-directive)
+		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
+
+		AR			:=	$(shell $(CC) --print-prog-name llvm-ar)
+		OD			:=	$(shell $(CC) --print-prog-name llvm-objdump)
+		OC			:=	$(shell $(CC) --print-prog-name llvm-objcopy)
+	endif
+
+	CPP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
+	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
+	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring gcc,$(notdir $(CC))),)
 TF_CFLAGS_aarch32	=	$(march32-directive)
 TF_CFLAGS_aarch64	=	$(march64-directive)
@@ -523,6 +527,9 @@
             ifeq ($(CTX_INCLUDE_EL2_REGS),0)
                 $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option)
             endif
+	    ifeq ($(SPMC_AT_EL3),1)
+                $(error SPM cannot be enabled in both S-EL2 and EL3.)
+            endif
         endif
 
         ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
@@ -573,6 +580,9 @@
 ifneq (${ARCH},aarch64)
 	$(error ENABLE_RME requires AArch64)
 endif
+ifeq ($(SPMC_AT_EL3),1)
+	$(error SPMC_AT_EL3 and ENABLE_RME cannot both be enabled.)
+endif
 include services/std_svc/rmmd/rmmd.mk
 $(warning "RME is an experimental feature")
 endif
@@ -771,8 +781,10 @@
     endif
 endif
 
-# SME/SVE only supported on AArch64
+# Ensure that no Aarch64-only features are enabled in Aarch32 build
 ifeq (${ARCH},aarch32)
+
+    # SME/SVE only supported on AArch64
     ifeq (${ENABLE_SME_FOR_NS},1)
         $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
     endif
@@ -780,6 +792,12 @@
         # Warning instead of error due to CI dependency on this
         $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
     endif
+
+    # BRBE is not supported in Aarch32
+    ifeq (${ENABLE_BRBE_FOR_NS},1)
+        $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32")
+    endif
+
 endif
 
 # Ensure ENABLE_RME is not used with SME
@@ -912,7 +930,7 @@
 
 # Variables for use with sptool
 SPTOOLPATH		?=	tools/sptool
-SPTOOL			?=	${SPTOOLPATH}/sptool${BIN_EXT}
+SPTOOL			?=	${SPTOOLPATH}/sptool.py
 SP_MK_GEN		?=	${SPTOOLPATH}/sp_mk_generator.py
 
 # Variables for use with ROMLIB
@@ -996,12 +1014,14 @@
         PROGRAMMABLE_RESET_ADDRESS \
         PSCI_EXTENDED_STATE_ID \
         RESET_TO_BL31 \
+        RESET_TO_BL31_WITH_PARAMS \
         SAVE_KEYS \
         SEPARATE_CODE_AND_RODATA \
         SEPARATE_BL2_NOLOAD_REGION \
         SEPARATE_NOBITS_REGION \
         SPIN_ON_BL1_EXIT \
         SPM_MM \
+        SPMC_AT_EL3 \
         SPMD_SPM_AT_SEL2 \
         TRUSTED_BOARD_BOOT \
         CRYPTO_SUPPORT \
@@ -1024,6 +1044,7 @@
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         PSA_FWU_SUPPORT \
+        ENABLE_BRBE_FOR_NS \
         ENABLE_TRBE_FOR_NS \
         ENABLE_SYS_REG_TRACE_FOR_NS \
         ENABLE_MPMM \
@@ -1061,6 +1082,8 @@
         NR_OF_FW_BANKS \
         NR_OF_IMAGES_IN_FW_BANK \
         RAS_EXTENSION \
+        TWED_DELAY \
+        ENABLE_FEAT_TWED \
 )))
 
 ifdef KEY_SIZE
@@ -1127,6 +1150,7 @@
         PSCI_EXTENDED_STATE_ID \
         RAS_EXTENSION \
         RESET_TO_BL31 \
+        RESET_TO_BL31_WITH_PARAMS \
         SEPARATE_CODE_AND_RODATA \
         SEPARATE_BL2_NOLOAD_REGION \
         SEPARATE_NOBITS_REGION \
@@ -1134,6 +1158,7 @@
         SPD_${SPD} \
         SPIN_ON_BL1_EXIT \
         SPM_MM \
+        SPMC_AT_EL3 \
         SPMD_SPM_AT_SEL2 \
         TRUSTED_BOARD_BOOT \
         CRYPTO_SUPPORT \
@@ -1160,6 +1185,7 @@
         NR_OF_FW_BANKS \
         NR_OF_IMAGES_IN_FW_BANK \
         PSA_FWU_SUPPORT \
+        ENABLE_BRBE_FOR_NS \
         ENABLE_TRBE_FOR_NS \
         ENABLE_SYS_REG_TRACE_FOR_NS \
         ENABLE_TRF_FOR_NS \
@@ -1176,6 +1202,8 @@
         ENABLE_FEAT_CSV2_2 \
         ENABLE_FEAT_PAN \
         FEATURE_DETECTION \
+        TWED_DELAY \
+        ENABLE_FEAT_TWED \
 )))
 
 ifeq (${SANITIZE_UB},trap)
@@ -1322,8 +1350,7 @@
 ifeq (${NEED_SP_PKG},yes)
 $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
 	${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT}
-sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk
-	${Q}$(SPTOOL) $(SPTOOL_ARGS)
+sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
 	@${ECHO_BLANK_LINE}
 	@echo "Built SP Images successfully"
 	@${ECHO_BLANK_LINE}
@@ -1363,7 +1390,6 @@
 # to pass the gnumake flags to nmake.
 	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
 endif
-	${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
 	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
@@ -1457,10 +1483,6 @@
 	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
 endif
 
-sptool: ${SPTOOL}
-${SPTOOL}: FORCE
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH}
-
 romlib.bin: libraries FORCE
 	${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
 
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 6aa7afd..c95706c 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -17,12 +17,12 @@
     RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
 #else
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
 #if SEPARATE_BL2_NOLOAD_REGION
     RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
 #else
 #define RAM_NOLOAD RAM
 #endif
-#endif
 }
 
 #if !BL2_IN_XIP_MEM
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index ed05864..b0c46dc 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,6 +67,7 @@
 		_exception_vectors=runtime_exceptions		\
 		_pie_fixup_size=BL31_LIMIT - BL31_BASE
 
+#if !RESET_TO_BL31_WITH_PARAMS
 	/* ---------------------------------------------------------------------
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
 	 * there's no argument to relay from a previous bootloader. Zero the
@@ -77,6 +78,7 @@
 	mov	x21, 0
 	mov	x22, 0
 	mov	x23, 0
+#endif /* RESET_TO_BL31_WITH_PARAMS */
 #endif /* RESET_TO_BL31 */
 
 	/* --------------------------------------------------------------------
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 25c7964..3964469 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -18,12 +18,21 @@
     $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support)
   else
     $(info Including SPM Management Mode (MM) makefile)
-    include services/std_svc/spm_mm/spm_mm.mk
+    include services/std_svc/spm/common/spm.mk
+    include services/std_svc/spm/spm_mm/spm_mm.mk
   endif
 endif
 
 include lib/extensions/amu/amu.mk
 include lib/mpmm/mpmm.mk
+
+ifeq (${SPMC_AT_EL3},1)
+  $(warning "EL3 SPMC is an experimental feature")
+  $(info Including EL3 SPMC makefile)
+  include services/std_svc/spm/common/spm.mk
+  include services/std_svc/spm/el3_spmc/spmc.mk
+endif
+
 include lib/psci/psci_lib.mk
 
 BL31_SOURCES		+=	bl31/bl31_main.c				\
@@ -40,6 +49,8 @@
 				services/std_svc/std_svc_setup.c		\
 				${PSCI_LIB_SOURCES}				\
 				${SPMD_SOURCES}					\
+				${SPM_MM_SOURCES}				\
+				${SPMC_SOURCES}					\
 				${SPM_SOURCES}
 
 ifeq (${DISABLE_MTPMU},1)
@@ -104,6 +115,10 @@
 BL31_SOURCES		+=	lib/extensions/trbe/trbe.c
 endif
 
+ifeq (${ENABLE_BRBE_FOR_NS},1)
+BL31_SOURCES		+=	lib/extensions/brbe/brbe.c
+endif
+
 ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
 BL31_SOURCES		+=      lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
 endif
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 590b032..ab1287d 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -35,6 +35,10 @@
 ifeq (${WORKAROUND_CVE_2017_5715},1)
 BL32_SOURCES		+=	bl32/sp_min/wa_cve_2017_5715_bpiall.S	\
 				bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+else
+ifeq (${WORKAROUND_CVE_2022_23960},1)
+BL32_SOURCES		+=	bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+endif
 endif
 
 ifeq (${TRNG_SUPPORT},1)
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index de02b46..b1d628c 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -394,6 +394,110 @@
 	return offs;
 }
 
+/*******************************************************************************
+ * fdt_add_cpu_idle_states() - add PSCI CPU idle states to cpu nodes in the DT
+ * @dtb:	pointer to the device tree blob in memory
+ * @states:	array of idle state descriptions, ending with empty element
+ *
+ * Add information about CPU idle states to the devicetree. This function
+ * assumes that CPU idle states are not already present in the devicetree, and
+ * that all CPU states are equally applicable to all CPUs.
+ *
+ * See arm/idle-states.yaml and arm/psci.yaml in the (Linux kernel) DT binding
+ * documentation for more details.
+ *
+ * Return: 0 on success, a negative error value otherwise.
+ ******************************************************************************/
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state)
+{
+	int cpu_node, cpus_node, idle_states_node, ret;
+	uint32_t count, phandle;
+
+	ret = fdt_find_max_phandle(dtb, &phandle);
+	phandle++;
+	if (ret < 0) {
+		return ret;
+	}
+
+	cpus_node = fdt_path_offset(dtb, "/cpus");
+	if (cpus_node < 0) {
+		return cpus_node;
+	}
+
+	/* Create the idle-states node and its child nodes. */
+	idle_states_node = fdt_add_subnode(dtb, cpus_node, "idle-states");
+	if (idle_states_node < 0) {
+		return idle_states_node;
+	}
+
+	ret = fdt_setprop_string(dtb, idle_states_node, "entry-method", "psci");
+	if (ret < 0) {
+		return ret;
+	}
+
+	for (count = 0U; state->name != NULL; count++, phandle++, state++) {
+		int idle_state_node;
+
+		idle_state_node = fdt_add_subnode(dtb, idle_states_node,
+						  state->name);
+		if (idle_state_node < 0) {
+			return idle_state_node;
+		}
+
+		fdt_setprop_string(dtb, idle_state_node, "compatible",
+				   "arm,idle-state");
+		fdt_setprop_u32(dtb, idle_state_node, "arm,psci-suspend-param",
+				state->power_state);
+		if (state->local_timer_stop) {
+			fdt_setprop_empty(dtb, idle_state_node,
+					  "local-timer-stop");
+		}
+		fdt_setprop_u32(dtb, idle_state_node, "entry-latency-us",
+				state->entry_latency_us);
+		fdt_setprop_u32(dtb, idle_state_node, "exit-latency-us",
+				state->exit_latency_us);
+		fdt_setprop_u32(dtb, idle_state_node, "min-residency-us",
+				state->min_residency_us);
+		if (state->wakeup_latency_us) {
+			fdt_setprop_u32(dtb, idle_state_node,
+					"wakeup-latency-us",
+					state->wakeup_latency_us);
+		}
+		fdt_setprop_u32(dtb, idle_state_node, "phandle", phandle);
+	}
+
+	if (count == 0U) {
+		return 0;
+	}
+
+	/* Link each cpu node to the idle state nodes. */
+	fdt_for_each_subnode(cpu_node, dtb, cpus_node) {
+		const char *device_type;
+		fdt32_t *value;
+
+		/* Only process child nodes with device_type = "cpu". */
+		device_type = fdt_getprop(dtb, cpu_node, "device_type", NULL);
+		if (device_type == NULL || strcmp(device_type, "cpu") != 0) {
+			continue;
+		}
+
+		/* Allocate space for the list of phandles. */
+		ret = fdt_setprop_placeholder(dtb, cpu_node, "cpu-idle-states",
+					      count * sizeof(phandle),
+					      (void **)&value);
+		if (ret < 0) {
+			return ret;
+		}
+
+		/* Fill in the phandles of the idle state nodes. */
+		for (uint32_t i = 0U; i < count; ++i) {
+			value[i] = cpu_to_fdt32(phandle - count + i);
+		}
+	}
+
+	return 0;
+}
+
 /**
  * fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
  * @dtb: Pointer to the DT blob in memory
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 2a9673f..1b065b1 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -618,3 +618,24 @@
 
 	return ret;
 }
+
+/*
+ * Find a given node in device tree. If not present, add it.
+ * Returns offset of node found/added on success, and < 0 on error.
+ */
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+	int offset;
+
+	offset = fdt_subnode_offset(fdt, parentoffset, name);
+
+	if (offset == -FDT_ERR_NOTFOUND) {
+		offset = fdt_add_subnode(fdt, parentoffset, name);
+	}
+
+	if (offset < 0) {
+		ERROR("%s: %s: %s\n", __func__, name, fdt_strerror(offset));
+	}
+
+	return offset;
+}
diff --git a/common/feat_detect.c b/common/feat_detect.c
index ef09b86..8f98876 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -203,6 +203,16 @@
 #endif
 }
 
+/***********************************************************
+ * Feature : FEAT_TWED (Delayed Trapping of WFE Instruction)
+ **********************************************************/
+static void read_feat_twed(void)
+{
+#if (ENABLE_FEAT_TWED == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_6_twed_present(), "TWED");
+#endif
+}
+
 /******************************************************************
  * Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
  *****************************************************************/
@@ -279,6 +289,7 @@
 	read_feat_amuv1p1();
 	read_feat_fgt();
 	read_feat_ecv();
+	read_feat_twed();
 
 	/* v8.7 features */
 	read_feat_hcx();
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4440a37..4f482bd 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -47,10 +47,10 @@
 via their partner managers.
 
 .. _`issue tracker`: https://developer.trustedfirmware.org
-.. _`TF-A development`: https://lists.trustedfirmware.org/pipermail/tf-a/
-.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/pipermail/tf-a-tests/
-.. _`summary of all the lists`: https://lists.trustedfirmware.org
+.. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
+.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
+.. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index b58ea71..af8161a 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -315,9 +315,21 @@
 :|G|: `AlexeiFedorov`_
 :|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
 :|G|: `javieralso-arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
 :|F|: drivers/measured_boot
 :|F|: include/drivers/measured_boot
-:|F|: plat/arm/board/fvp/fvp_measured_boot.c
+:|F|: docs/components/measured_boot
+:|F|: plat/arm/board/fvp/fvp\*_measured_boot.c
+
+PSA Firmware Update
+^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|F|: drivers/fwu
+:|F|: include/drivers/fwu
 
 System Control and Management Interface (SCMI) Server
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -469,11 +481,11 @@
 
 Intel SocFPGA platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Tien Hock Loh <tien.hock.loh@intel.com>
-:|G|: `thloh85-intel`_
-:|M|: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
-:|G|: mabdulha
-:|F|: plat/intel/soc
+:|M|: Sieu Mun Tang <sieu.mun.tang@intel.com>
+:|G|: `sieumunt`_
+:|M|: Benjamin Jit Loon Lim <jit.loon.lim@intel.com>
+:|G|: `BenjaminLimJL`_
+:|F|: plat/intel/soc/
 :|F|: drivers/intel/soc/
 
 MediaTek platform ports
@@ -828,7 +840,8 @@
 .. _soby-mathew: https://github.com/soby-mathew
 .. _sreekare: https://github.com/sreekare
 .. _stephan-gh: https://github.com/stephan-gh
-.. _thloh85-intel: https://github.com/thloh85-intel
+.. _sieumunt: https://github.com/sieumunt
+.. _BenjaminLimJL: https://github.com/BenjaminLimJL
 .. _thomas-arm: https://github.com/thomas-arm
 .. _TonyXie06: https://github.com/TonyXie06
 .. _TravMurav: https://github.com/TravMurav
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 5c28a7a..20cc758 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -30,3 +30,10 @@
     - value type: <u32>
     - Image ID of the configuration.
 
+- ns-load-address [optional]
+    - value type: <u64>
+    - Physical loading base address of the configuration in the non-secure
+      memory.
+      Only needed by those configuration files which require being loaded
+      in secure memory (at load-address) as well as in non-secure memory
+      e.g. HW_CONFIG
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index af298e3..2eaae75 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -127,14 +127,18 @@
 
 This section explains the TF-A build options involved in building with
 support for an FF-A based SPM where the SPMD is located at EL3 and the
-SPMC located at S-EL1 or S-EL2:
+SPMC located at S-EL1, S-EL2 or EL3:
 
 - **SPD=spmd**: this option selects the SPMD component to relay the FF-A
   protocol from NWd to SWd back and forth. It is not possible to
   enable another Secure Payload Dispatcher when this option is chosen.
 - **SPMD_SPM_AT_SEL2**: this option adjusts the SPMC exception
-  level to being S-EL1 or S-EL2. It defaults to enabled (value 1) when
+  level to being at S-EL2. It defaults to enabled (value 1) when
   SPD=spmd is chosen.
+- **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
+  at EL3.
+- If neither **SPMD_SPM_AT_SEL2** or **SPMC_AT_EL3** are enabled the SPMC
+  exception level is set to S-EL1.
 - **CTX_INCLUDE_EL2_REGS**: this option permits saving (resp.
   restoring) the EL2 system register context before entering (resp.
   after leaving) the SPMC. It is mandatorily enabled when
@@ -146,14 +150,16 @@
   is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
   secure partitions are to be loaded on behalf of the SPMC.
 
-+---------------+----------------------+------------------+
-|               | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 |
-+---------------+----------------------+------------------+
-| SPMC at S-EL1 |         0            |        0         |
-+---------------+----------------------+------------------+
-| SPMC at S-EL2 |         1            | 1 (default when  |
-|               |                      |    SPD=spmd)     |
-+---------------+----------------------+------------------+
++---------------+----------------------+------------------+-------------+
+|               | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 | SPMC_AT_EL3 |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL1 |         0            |        0         |      0      |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL2 |         1            | 1 (default when  |      0      |
+|               |                      |    SPD=spmd)     |             |
++---------------+----------------------+------------------+-------------+
+| SPMC at EL3   |         0            |        0         |      1      |
++---------------+----------------------+------------------+-------------+
 
 Other combinations of such build options either break the build or are not
 supported.
@@ -229,6 +235,20 @@
     GENERATE_COT=1 \
     all fip
 
+Sample TF-A build command line when SPMC is located at EL3:
+
+.. code:: shell
+
+    make \
+    CROSS_COMPILE=aarch64-none-elf- \
+    SPD=spmd \
+    SPMD_SPM_AT_SEL2=0 \
+    SPMC_AT_EL3=1 \
+    BL32=<path-to-tee-binary> \
+    BL33=<path-to-bl33-binary> \
+    PLAT=fvp \
+    all fip
+
 FVP model invocation
 ====================
 
@@ -1280,7 +1300,7 @@
 
 .. _[8]:
 
-[8] https://lists.trustedfirmware.org/pipermail/tf-a/2020-February/000296.html
+[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
 
 .. _[9]:
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index af0e769..3029458 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -490,6 +490,10 @@
    Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
    r2p0 of the CPU, it is fixed in r2p1.
 
+-  ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to
+   Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
+   it is fixed in r2p1.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 0831dc0..71fdfcb 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -131,6 +131,9 @@
    -  For other BL3x images, if the firmware configuration file is loaded by
       BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
       then its address is passed in ``arg1``.
+   -  In case of the Arm FVP platform, FW_CONFIG address passed in ``arg1`` to
+      BL31/SP_MIN, and the SOC_FW_CONFIG and HW_CONFIG details are retrieved
+      from FW_CONFIG device tree.
 
 BL1
 ~~~
@@ -1757,12 +1760,20 @@
                    DRAM
     0xffffffff +----------+
                :          :
-               |----------|
+    0x82100000 |----------|
                |HW_CONFIG |
-    0x83000000 |----------|  (non-secure)
+    0x82000000 |----------|  (non-secure)
                |          |
     0x80000000 +----------+
 
+               Trusted DRAM
+    0x08000000 +----------+
+               |HW_CONFIG |
+    0x07f00000 |----------|
+               :          :
+               |          |
+    0x06000000 +----------+
+
                Trusted SRAM
     0x04040000 +----------+  loaded by BL2  +----------------+
                | BL1 (rw) |  <<<<<<<<<<<<<  |                |
@@ -1790,15 +1801,18 @@
                      DRAM
     0xffffffff +--------------+
                :              :
-               |--------------|
+    0x82100000 |--------------|
                |  HW_CONFIG   |
-    0x83000000 |--------------|  (non-secure)
+    0x82000000 |--------------|  (non-secure)
                |              |
     0x80000000 +--------------+
 
-                Trusted DRAM
+                 Trusted DRAM
     0x08000000 +--------------+
-               |     BL32     |
+               |  HW_CONFIG   |
+    0x07f00000 |--------------|
+               :              :
+               |    BL32      |
     0x06000000 +--------------+
 
                  Trusted SRAM
@@ -1829,12 +1843,20 @@
                |  BL32    |  (secure)
     0xff000000 +----------+
                |          |
-               |----------|
+    0x82100000 |----------|
                |HW_CONFIG |
-    0x83000000 |----------|  (non-secure)
+    0x82000000 |----------|  (non-secure)
                |          |
     0x80000000 +----------+
 
+               Trusted DRAM
+    0x08000000 +----------+
+               |HW_CONFIG |
+    0x7f000000 |----------|
+               :          :
+               |          |
+    0x06000000 +----------+
+
                Trusted SRAM
     0x04040000 +----------+  loaded by BL2  +----------------+
                | BL1 (rw) |  <<<<<<<<<<<<<  |                |
@@ -2729,7 +2751,7 @@
 
 --------------
 
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
 
 .. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/design/reset-design.rst b/docs/design/reset-design.rst
index 7b10c95..666ee4f 100644
--- a/docs/design/reset-design.rst
+++ b/docs/design/reset-design.rst
@@ -141,19 +141,26 @@
 Platform initialization
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-In this configuration, when the CPU resets to BL31 there are no parameters that
-can be passed in registers by previous boot stages. Instead, the platform code
-in BL31 needs to know, or be able to determine, the location of the BL32 (if
-required) and BL33 images and provide this information in response to the
+In this configuration, when the CPU resets to BL31 there should be no parameters
+that can be passed in registers by previous boot stages. Instead, the platform
+code in BL31 needs to know, or be able to determine, the location of the BL32
+(if required) and BL33 images and provide this information in response to the
 ``bl31_plat_get_next_image_ep_info()`` function.
 
+.. note::
+   Some platforms that configure ``RESET_TO_BL31`` might still be able to
+   receive parameters in registers depending on their actual boot sequence. On
+   those occasions, and in addition to ``RESET_TO_BL31``, these platforms should
+   set ``RESET_TO_BL31_WITH_PARAMS`` to avoid the input registers from being
+   zeroed before entering BL31.
+
 Additionally, platform software is responsible for carrying out any security
 initialisation, for example programming a TrustZone address space controller.
 This might be done by the Trusted Boot Firmware or by platform code in BL31.
 
 --------------
 
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
 
 .. |Default reset code flow| image:: ../resources/diagrams/default_reset_code.png
 .. |Reset code flow with programmable reset address| image:: ../resources/diagrams/reset_code_no_boot_type_check.png
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 4dbf5cb..d2cda4d 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -327,6 +327,14 @@
    This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
    mechanism. Default is ``0``.
 
+-  ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed
+   trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature
+   available on Arm v8.6. This flag can take values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. Default is ``0``.
+
+    When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets
+    delayed by the amount of value in ``TWED_DELAY``.
+
 -  ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization
    Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
    during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
@@ -709,6 +717,11 @@
    entrypoint) or 1 (CPU reset to BL31 entrypoint).
    The default value is 0.
 
+-  ``RESET_TO_BL31_WITH_PARAMS``: If ``RESET_TO_BL31`` has been enabled, setting
+   this additional option guarantees that the input registers are not cleared
+   therefore allowing parameters to be passed to the BL31 entrypoint.
+   The default value is 0.
+
 -  ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
    in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
@@ -780,13 +793,20 @@
    firmware images have been loaded in memory, and the MMU and caches are
    turned off. Refer to the "Debugging options" section for more details.
 
+-  ``SPMC_AT_EL3`` : This boolean option is used jointly with the SPM
+   Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
+   component runs at the EL3 exception level. The default value is ``0`` (
+   disabled). This configuration supports pre-Armv8.4 platforms (aka not
+   implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
+
 -  ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM
    Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
-   component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2
+   component runs at the S-EL2 exception level provided by the ``FEAT_SEL2``
    extension. This is the default when enabling the SPM Dispatcher. When
    disabled (0) it indicates the SPMC component runs at the S-EL1 execution
-   state. This latter configuration supports pre-Armv8.4 platforms (aka not
-   implementing the Armv8.4-SecEL2 extension).
+   state or at EL3 if ``SPMC_AT_EL3`` is enabled. The latter configurations
+   support pre-Armv8.4 platforms (aka not implementing the ``FEAT_SEL2``
+   extension).
 
 -  ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
    Partition Manager (SPM) implementation. The default value is ``0``
@@ -838,6 +858,12 @@
       When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
       must also be set to ``1``.
 
+-  ``TWED_DELAY``: Numeric value to be set in order to delay the trapping of
+   WFE instruction. ``ENABLE_FEAT_TWED`` build option must be enabled to set
+   this delay. It can take values in the range (0-15). Default value is ``0``
+   and based on this value, 2^(TWED_DELAY + 8) cycles will be delayed.
+   Platforms need to explicitly update this value based on their requirements.
+
 -  ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
    linker. When the ``LINKER`` build variable points to the armlink linker,
    this flag is enabled automatically. To enable support for armlink, platforms
@@ -947,6 +973,11 @@
   functions that wait for an arbitrary time length (udelay and mdelay). The
   default value is 0.
 
+- ``ENABLE_BRBE_FOR_NS``: This flag enables access to the branch record buffer
+  registers from NS ELs when FEAT_BRBE is implemented. BRBE is an optional
+  architectural feature for AArch64. The default is 0 and it is automatically
+  disabled when the target architecture is AArch32.
+
 - ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer
   control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
   but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index d4a8f01..62f1941 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -18,16 +18,12 @@
 
    It is possible to build TF-A using Clang or Arm Compiler 6. To do so
    ``CC`` needs to point to the clang or armclang binary, which will
-   also select the clang or armclang assembler. Be aware that for Arm Compiler,
-   the GNU linker is used by default. However for Clang LLVM linker (LLD)
-   is used by default. In case of being needed the linker can be overridden
-   using the ``LD`` variable. LLVM linker (LLD) version 9 is
-   known to work with TF-A.
-
-   In both cases ``CROSS_COMPILE`` should be set as described above.
-
-   Arm Compiler 6 will be selected when the base name of the path assigned
-   to ``CC`` matches the string 'armclang'.
+   also select the clang or armclang assembler. Arm Compiler 6 will be selected
+   when the base name of the path assigned to ``CC`` matches the string
+   'armclang'. GNU binutils are required since the TF-A build system doesn't
+   currently support Arm Scatter files. Meaning the GNU linker is used by
+   default for Arm Compiler 6. Because of this dependency, ``CROSS_COMPILE``
+   should be set as described above.
 
    For AArch64 using Arm Compiler 6:
 
@@ -36,6 +32,11 @@
        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
        make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
 
+   On the other hand, Clang uses LLVM linker (LLD) and other LLVM binutils by
+   default instead of GNU utilities (LLVM linker (LLD) 14.0.0 is known to
+   work with TF-A). ``CROSS_COMPILE`` need not be set for Clang. Please note,
+   that the default linker may be manually overridden using the ``LD`` variable.
+
    Clang will be selected when the base name of the path assigned to ``CC``
    contains the string 'clang'. This is to allow both clang and clang-X.Y
    to work.
@@ -44,7 +45,6 @@
 
    .. code:: shell
 
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
        make CC=<path-to-clang>/bin/clang PLAT=<platform> all
 
 -  Change to the root directory of the TF-A source tree and build.
@@ -115,4 +115,4 @@
 
 --------------
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 3d3b2e3..2c6a005 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2118,21 +2118,6 @@
 of the system counter, which is retrieved from the first entry in the frequency
 modes table.
 
-Function : plat_arm_set_twedel_scr_el3() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : uint32_t
-
-This function is used in v8.6+ systems to set the WFE trap delay value in
-SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this
-feature is not enabled.  The only hook provided is to set the TWED fields in
-SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust
-the WFE trap delays in lower ELs and these fields should be set by the
-appropriate EL2 or EL1 code depending on the platform configuration.
-
 #define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index ee30128..3a54e69 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,9 +26,9 @@
 |TF-A| can be built with any of the following *cross-compiler* toolchains that
 target the Armv7-A or Armv8-A architectures:
 
-- GCC >= 10.3-2021.07 (from the `Arm Developer website`_)
-- Clang >= 4.0
-- Arm Compiler >= 6.0
+- GCC >= 11.2-2022.02 (from the `Arm Developer website`_)
+- Clang >= 14.0.0
+- Arm Compiler >= 6.18
 
 In addition, a native compiler is required to build the supporting tools.
 
@@ -58,9 +58,10 @@
 
    Required to build the cert_create tool.
 
-The following libraries are required for Trusted Board Boot support:
+The following libraries are required for Trusted Board Boot and Measured Boot
+support:
 
-- mbed TLS == 2.26.0 (tag: ``mbedtls-2.26.0``)
+- mbed TLS == 2.28.0 (tag: ``mbedtls-2.28.0``)
 
 These tools are optional:
 
@@ -159,9 +160,9 @@
 
 --------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
 
-.. _Arm Developer website: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
+.. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
 .. _Gerrit Code Review: https://www.gerritcodereview.com/
 .. _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
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 2aaf195..9280f7b 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -392,7 +392,8 @@
 -  BL1 is loaded at the start of the Trusted ROM.
 -  The Firmware Image Package is loaded at the start of NOR FLASH0.
 -  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
-   is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
+   is specified via the ``load-address`` property in the ``hw-config`` node of
+   `FW_CONFIG for FVP`_.
 -  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
    and enable the GICv3 device in the model. Note that without this option,
    the Foundation FVP defaults to legacy (Versatile Express) memory map which
@@ -643,9 +644,9 @@
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
 
-.. _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
+.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
 .. _Arm's website: `FVP models`_
 .. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
 .. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index d65b048..91ad6f1 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -43,6 +43,8 @@
 
 *   `VERSAL_PLATFORM`: Select the platform. Options:
     -   `versal_virt`	: Versal Virtual platform
+    -   `spp_itr6`	: SPP ITR6
+    -   `emu_it6`	: EMU ITR6
 
 # PLM->TF-A Parameter Passing
 ------------------------------
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 79c2535..af1cb22 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -14,13 +14,13 @@
 
 .. code:: bash
 
-    make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp bl31
+    make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 bl31
 
 To build bl32 TSP you have to rebuild bl31 too:
 
 .. code:: bash
 
-    make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd bl31 bl32
+    make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd RESET_TO_BL31=1 bl31 bl32
 
 To build TF-A for JTAG DCC console:
 
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index f80389d..ef9ebd3 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -299,6 +299,6 @@
 .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io
 .. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
 .. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
-.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 .. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/
 .. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make
diff --git a/docs/process/platform-compatibility-policy.rst b/docs/process/platform-compatibility-policy.rst
index be1f9ba..a10236c 100644
--- a/docs/process/platform-compatibility-policy.rst
+++ b/docs/process/platform-compatibility-policy.rst
@@ -31,6 +31,6 @@
 
 --------------
 
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
 
-.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
diff --git a/docs/process/security.rst b/docs/process/security.rst
index a3b9971..e15783b 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -71,7 +71,7 @@
 +-----------+------------------------------------------------------------------+
 
 .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
-.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 
 .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
 .. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)`
@@ -86,4 +86,4 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index a082a81..45f6df9 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <drivers/arm/smmu_v3.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <arch_features.h>
 
 /* SMMU poll number of retries */
 #define SMMU_POLL_TIMEOUT_US	U(1000)
@@ -79,14 +80,74 @@
 	if (smmuv3_security_init(smmu_base) != 0)
 		return -1;
 
-	/* Check if the SMMU supports secure state */
-	if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
-				SMMU_S_IDR1_SECURE_IMPL) == 0U)
-		return 0;
+#if ENABLE_RME
+
+	if (get_armv9_2_feat_rme_support() != 0U) {
+		if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) &
+				  SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) {
+			WARN("Skip SMMU GPC configuration.\n");
+		} else {
+			uint64_t gpccr_el3 = read_gpccr_el3();
+			uint64_t gptbr_el3 = read_gptbr_el3();
+
+			/* SMMU_ROOT_GPT_BASE_CFG[16] is RES0. */
+			gpccr_el3 &= ~(1UL << 16);
+
+			/*
+			 * TODO: SMMU_ROOT_GPT_BASE_CFG is 64b in the spec,
+			 * but SMMU model only accepts 32b access.
+			 */
+			mmio_write_32(smmu_base + SMMU_ROOT_GPT_BASE_CFG,
+				      gpccr_el3);
+
+			/*
+			 * pa_gpt_table_base[51:12] maps to GPTBR_EL3[39:0]
+			 * whereas it maps to SMMU_ROOT_GPT_BASE[51:12]
+			 * hence needs a 12 bit left shit.
+			 */
+			mmio_write_64(smmu_base + SMMU_ROOT_GPT_BASE,
+				      gptbr_el3 << 12);
+
+			/*
+			 * ACCESSEN=1: SMMU- and client-originated accesses are
+			 *             not terminated by this mechanism.
+			 * GPCEN=1: All clients and SMMU-originated accesses,
+			 *          except GPT-walks, are subject to GPC.
+			 */
+			mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
+					SMMU_ROOT_CR0_GPCEN |
+					SMMU_ROOT_CR0_ACCESSEN);
+
+			/* Poll for ACCESSEN and GPCEN ack bits. */
+			if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
+					SMMU_ROOT_CR0_GPCEN |
+					SMMU_ROOT_CR0_ACCESSEN,
+					SMMU_ROOT_CR0_GPCEN |
+					SMMU_ROOT_CR0_ACCESSEN) != 0) {
+				WARN("Failed enabling SMMU GPC.\n");
+
+				/*
+				 * Do not return in error, but fall back to
+				 * invalidating all entries through the secure
+				 * register file.
+				 */
+			}
+		}
+	}
+
+#endif /* ENABLE_RME */
+
 	/*
 	 * Initiate invalidation of secure caches and TLBs if the SMMU
 	 * supports secure state. If not, it's implementation defined
 	 * as to how SMMU_S_INIT register is accessed.
+	 * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
+	 * specified to be accessible only in secure physical address space are
+	 * additionally accessible in root physical address space in an SMMU
+	 * with RME.
+	 * Section 3.3: as GPT information is permitted to be cached in a TLB,
+	 * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
+	 * cached in TLBs.
 	 */
 	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
 
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 0a4775d..3eb4161 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -48,6 +48,7 @@
 					rsa_internal.c				\
 					x509.c 					\
 					x509_crt.c 				\
+					constant_time.c 			\
 					)
 
 # The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index 355c9da..e1b6940 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -327,6 +327,9 @@
 	}
 
 	old_parent = _clk_stm32_get_parent(priv, clk);
+	if (old_parent < 0) {
+		return old_parent;
+	}
 	if (old_parent == clkp) {
 		return 0;
 	}
@@ -415,7 +418,7 @@
 		sel = clk_mux_get_parent(priv, mux_id);
 	}
 
-	if (sel < parent->num_parents) {
+	if ((sel >= 0) && (sel < parent->num_parents)) {
 		return parent->id_parents[sel];
 	}
 
@@ -488,6 +491,9 @@
 	}
 
 	parent = _clk_stm32_get_parent(priv, id);
+	if (parent < 0) {
+		return 0UL;
+	}
 
 	if (clk->ops->recalc_rate != NULL) {
 		unsigned long prate = 0UL;
@@ -517,6 +523,10 @@
 {
 	int parent_id = _clk_stm32_get_parent(priv, id);
 
+	if (parent_id < 0) {
+		return 0UL;
+	}
+
 	return _clk_stm32_get_rate(priv, parent_id);
 }
 
@@ -552,6 +562,9 @@
 
 	if (priv->gate_refcounts[id] == 0U) {
 		parent = _clk_stm32_get_parent(priv, id);
+		if (parent < 0) {
+			return parent;
+		}
 		if (parent != CLK_IS_ROOT) {
 			ret = _clk_stm32_enable_core(priv, parent);
 			if (ret) {
@@ -616,7 +629,7 @@
 	clk_stm32_disable_call_ops(priv, id);
 
 	parent = _clk_stm32_get_parent(priv, id);
-	if (parent != CLK_IS_ROOT) {
+	if ((parent >= 0) && (parent != CLK_IS_ROOT)) {
 		_clk_stm32_disable_core(priv, parent);
 	}
 }
@@ -1060,12 +1073,15 @@
 	uint32_t i;
 
 	cell = fdt_getprop(fdt, node, name, &len);
-	if (cell != NULL) {
-		for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
-			uint32_t val = fdt32_to_cpu(cell[i]);
+	if (cell == NULL) {
+		*nb = 0U;
+		return 0;
+	}
 
-			tab[i] = val;
-		}
+	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		uint32_t val = fdt32_to_cpu(cell[i]);
+
+		tab[i] = val;
 	}
 
 	*nb = (uint32_t)len / sizeof(uint32_t);
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index c71ff5a..7db6c0b 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -388,7 +388,6 @@
 		hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
 	}
 
-	flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
 	flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
 	return 0;
 }
@@ -447,7 +446,6 @@
 		assert(0);
 		break;
 	}
-	flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
 	flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
 	return 0;
 }
@@ -471,7 +469,6 @@
 
 	nop_out->trans_type = 0;
 	nop_out->task_tag = utrd->task_tag;
-	flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
 	flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
 }
 
@@ -505,7 +502,6 @@
 
 	hd = (utrd_header_t *)utrd->header;
 	resp = (resp_upiu_t *)utrd->resp_upiu;
-	inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
 	do {
 		data = mmio_read_32(ufs_params.reg_base + IS);
 		if ((data & ~(UFS_INT_UCCS | UFS_INT_UTRCS)) != 0)
@@ -515,6 +511,12 @@
 
 	data = mmio_read_32(ufs_params.reg_base + UTRLDBR);
 	assert((data & (1 << slot)) == 0);
+	/*
+	 * Invalidate the header after DMA read operation has
+	 * completed to avoid cpu referring to the prefetched
+	 * data brought in before DMA completion.
+	 */
+	inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
 	assert(hd->ocs == OCS_SUCCESS);
 	assert((resp->trans_type & TRANS_TYPE_CODE_MASK) == trans_type);
 	(void)resp;
@@ -690,7 +692,6 @@
 	sense_data_t *sense;
 	unsigned char data[CACHE_WRITEBACK_GRANULE << 1];
 	uintptr_t buf;
-	int result;
 	int retry;
 
 	assert((ufs_params.reg_base != 0) &&
@@ -702,8 +703,6 @@
 	buf = (uintptr_t)data;
 	buf = (buf + CACHE_WRITEBACK_GRANULE - 1) &
 	      ~(CACHE_WRITEBACK_GRANULE - 1);
-	memset((void *)buf, 0, CACHE_WRITEBACK_GRANULE);
-	flush_dcache_range(buf, CACHE_WRITEBACK_GRANULE);
 	do {
 		ufs_send_cmd(&utrd, CDBCMD_READ_CAPACITY_10, lun, 0,
 			    buf, READ_CAPACITY_LENGTH);
@@ -727,14 +726,12 @@
 		/* logical block length in bytes */
 		*size = be32toh(*(unsigned int *)(buf + 4));
 	} while (retry);
-	(void)result;
 }
 
 size_t ufs_read_blocks(int lun, int lba, uintptr_t buf, size_t size)
 {
 	utp_utrd_t utrd;
 	resp_upiu_t *resp;
-	int result;
 
 	assert((ufs_params.reg_base != 0) &&
 	       (ufs_params.desc_base != 0) &&
@@ -744,8 +741,12 @@
 #ifdef UFS_RESP_DEBUG
 	dump_upiu(&utrd);
 #endif
+	/*
+	 * Invalidate prefetched cache contents before cpu
+	 * accesses the buf.
+	 */
+	inv_dcache_range(buf, size);
 	resp = (resp_upiu_t *)utrd.resp_upiu;
-	(void)result;
 	return size - resp->res_trans_cnt;
 }
 
@@ -753,7 +754,6 @@
 {
 	utp_utrd_t utrd;
 	resp_upiu_t *resp;
-	int result;
 
 	assert((ufs_params.reg_base != 0) &&
 	       (ufs_params.desc_base != 0) &&
@@ -764,7 +764,6 @@
 	dump_upiu(&utrd);
 #endif
 	resp = (resp_upiu_t *)utrd.resp_upiu;
-	(void)result;
 	return size - resp->res_trans_cnt;
 }
 
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index dff1b33..adf7a91 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -26,26 +26,6 @@
 		};
 	};
 
-	nvmem_layout: nvmem_layout@0 {
-		compatible = "st,stm32-nvmem-layout";
-
-		nvmem-cells = <&cfg0_otp>,
-			      <&part_number_otp>,
-			      <&monotonic_otp>,
-			      <&nand_otp>,
-			      <&nand2_otp>,
-			      <&uid_otp>,
-			      <&hw2_otp>;
-
-		nvmem-cell-names = "cfg0_otp",
-				   "part_number_otp",
-				   "monotonic_otp",
-				   "nand_otp",
-				   "nand2_otp",
-				   "uid_otp",
-				   "hw2_otp";
-	};
-
 	clocks {
 		clk_csi: clk-csi {
 			#clock-cells = <0>;
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 0fa064b..6240381 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -175,28 +175,6 @@
 	status = "okay";
 };
 
-&nvmem_layout {
-	nvmem-cells = <&cfg0_otp>,
-		      <&part_number_otp>,
-		      <&monotonic_otp>,
-		      <&nand_otp>,
-		      <&nand2_otp>,
-		      <&uid_otp>,
-		      <&hw2_otp>,
-		      <&pkh_otp>,
-		      <&board_id>;
-
-	nvmem-cell-names = "cfg0_otp",
-			   "part_number_otp",
-			   "monotonic_otp",
-			   "nand_otp",
-			   "nand2_otp",
-			   "uid_otp",
-			   "hw2_otp",
-			   "pkh_otp",
-			   "board_id";
-};
-
 &pka {
 	secure-status = "okay";
 };
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 454e124..63cc917 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -24,26 +24,6 @@
 		};
 	};
 
-	nvmem_layout: nvmem_layout@0 {
-		compatible = "st,stm32-nvmem-layout";
-
-		nvmem-cells = <&cfg0_otp>,
-			      <&part_number_otp>,
-			      <&monotonic_otp>,
-			      <&nand_otp>,
-			      <&uid_otp>,
-			      <&package_otp>,
-			      <&hw2_otp>;
-
-		nvmem-cell-names = "cfg0_otp",
-				   "part_number_otp",
-				   "monotonic_otp",
-				   "nand_otp",
-				   "uid_otp",
-				   "package_otp",
-				   "hw2_otp";
-	};
-
 	psci {
 		compatible = "arm,psci-1.0";
 		method = "smc";
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 44c7016..659e8bf 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -195,26 +195,6 @@
 	status = "okay";
 };
 
-&nvmem_layout {
-	nvmem-cells = <&cfg0_otp>,
-		      <&part_number_otp>,
-		      <&monotonic_otp>,
-		      <&nand_otp>,
-		      <&uid_otp>,
-		      <&package_otp>,
-		      <&hw2_otp>,
-		      <&board_id>;
-
-	nvmem-cell-names = "cfg0_otp",
-			   "part_number_otp",
-			   "monotonic_otp",
-			   "nand_otp",
-			   "uid_otp",
-			   "package_otp",
-			   "hw2_otp",
-			   "board_id";
-};
-
 &pwr_regulators {
 	vdd-supply = <&vdd>;
 	vdd_3v3_usbfs-supply = <&vdd_usb>;
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 2eb3a57..05eb46a 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -183,26 +183,6 @@
 	secure-status = "okay";
 };
 
-&nvmem_layout {
-	nvmem-cells = <&cfg0_otp>,
-		      <&part_number_otp>,
-		      <&monotonic_otp>,
-		      <&nand_otp>,
-		      <&uid_otp>,
-		      <&package_otp>,
-		      <&hw2_otp>,
-		      <&board_id>;
-
-	nvmem-cell-names = "cfg0_otp",
-			   "part_number_otp",
-			   "monotonic_otp",
-			   "nand_otp",
-			   "uid_otp",
-			   "package_otp",
-			   "hw2_otp",
-			   "board_id";
-};
-
 &pwr_regulators {
 	vdd-supply = <&vdd>;
 	vdd_3v3_usbfs-supply = <&vdd_usb>;
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 7c0e842..2099229 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -261,6 +261,12 @@
 		arm,mhuv2-protocols = <0 1>;
 	};
 
+	cmn-pmu {
+		compatible = "arm,ci-700";
+		reg = <0x0 0x50000000 0x0 0x10000000>;
+		interrupts = <0x0 460 0x4>;
+	};
+
 	scmi {
 		compatible = "arm,scmi";
 		mbox-names = "tx", "rx";
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b4608ae..bbbc77a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -234,6 +234,11 @@
 #define ID_AA64DFR0_MTPMU_MASK		ULL(0xf)
 #define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
 
+/* ID_AA64DFR0_EL1.BRBE definitions */
+#define ID_AA64DFR0_BRBE_SHIFT		U(52)
+#define ID_AA64DFR0_BRBE_MASK		ULL(0xf)
+#define ID_AA64DFR0_BRBE_SUPPORTED	ULL(1)
+
 /* ID_AA64ISAR0_EL1 definitions */
 #define ID_AA64ISAR0_RNDR_SHIFT	U(60)
 #define ID_AA64ISAR0_RNDR_MASK	ULL(0xf)
@@ -512,6 +517,8 @@
 #define MDCR_EnPMSN_BIT		(ULL(1) << 36)
 #define MDCR_MPMX_BIT		(ULL(1) << 35)
 #define MDCR_MCCD_BIT		(ULL(1) << 34)
+#define MDCR_SBRBE_SHIFT	U(32)
+#define MDCR_SBRBE_MASK		ULL(0x3)
 #define MDCR_NSTB(x)		((x) << 24)
 #define MDCR_NSTB_EL1		ULL(0x3)
 #define MDCR_NSTBE		(ULL(1) << 26)
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 8cb4990..3a06cfb 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -81,6 +81,10 @@
 #define __RODATA_END__			Load$$__RODATA_EPILOGUE__$$Base
 #define __RT_SVC_DESCS_START__		Load$$__RT_SVC_DESCS__$$Base
 #define __RT_SVC_DESCS_END__		Load$$__RT_SVC_DESCS__$$Limit
+#if SPMC_AT_EL3
+#define __EL3_LP_DESCS_START__		Load$$__EL3_LP_DESCS__$$Base
+#define __EL3_LP_DESCS_END__		Load$$__EL3_LP_DESCS__$$Limit
+#endif
 #define __RW_START__			Load$$LR$$LR_RW_DATA$$Base
 #define __RW_END__			Load$$LR$$LR_END$$Base
 #define __SPM_SHIM_EXCEPTIONS_START__	Load$$__SPM_SHIM_EXCEPTIONS__$$Base
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 9888a3c..080e331 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -39,6 +39,16 @@
 	KEEP(*(rt_svc_descs))				\
 	__RT_SVC_DESCS_END__ = .;
 
+#if SPMC_AT_EL3
+#define EL3_LP_DESCS					\
+	. = ALIGN(STRUCT_ALIGN);			\
+	__EL3_LP_DESCS_START__ = .;			\
+	KEEP(*(el3_lp_descs))				\
+	__EL3_LP_DESCS_END__ = .;
+#else
+#define EL3_LP_DESCS
+#endif
+
 #define PMF_SVC_DESCS					\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__PMF_SVC_DESCS_START__ = .;			\
@@ -89,7 +99,8 @@
 	PARSER_LIB_DESCS				\
 	CPU_OPS						\
 	GOT						\
-	BASE_XLAT_TABLE_RO
+	BASE_XLAT_TABLE_RO				\
+	EL3_LP_DESCS
 
 /*
  * .data must be placed at a lower address than the stacks if the stack
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 7a590b2..c35e9be 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -7,14 +7,29 @@
 #ifndef FDT_FIXUP_H
 #define FDT_FIXUP_H
 
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
 #define INVALID_BASE_ADDR	((uintptr_t)~0UL)
 
+struct psci_cpu_idle_state {
+	const char *name;
+	uint32_t power_state;
+	bool local_timer_stop;
+	uint32_t entry_latency_us;
+	uint32_t exit_latency_us;
+	uint32_t min_residency_us;
+	uint32_t wakeup_latency_us;
+};
+
 int dt_add_psci_node(void *fdt);
 int dt_add_psci_cpu_enable_methods(void *fdt);
 int fdt_add_reserved_memory(void *dtb, const char *node_name,
 			    uintptr_t base, size_t size);
 int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
 		      unsigned int afflv1, unsigned int afflv2);
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state);
 int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
 			  unsigned int gicr_frame_size);
 
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 9c7180c..2929fc2 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,6 +44,8 @@
 int fdtw_for_each_cpu(const void *fdt,
 		      int (*callback)(const void *dtb, int node, uintptr_t mpidr));
 
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
+
 static inline uint32_t fdt_blob_size(const void *dtb)
 {
 	const uint32_t *dtb_header = dtb;
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index a820a44..e60c754 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 #include <lib/utils_def.h>
+#include <platform_def.h>
 
 /* SMMUv3 register offsets from device base */
 #define SMMU_GBPA	U(0x0044)
@@ -16,6 +17,26 @@
 #define SMMU_S_INIT	U(0x803c)
 #define SMMU_S_GBPA	U(0x8044)
 
+/*
+ * TODO: SMMU_ROOT_PAGE_OFFSET is platform specific.
+ * Currently defined as a command line model parameter.
+ */
+#if ENABLE_RME
+
+#define SMMU_ROOT_PAGE_OFFSET	(PLAT_ARM_SMMUV3_ROOT_REG_OFFSET)
+#define SMMU_ROOT_IDR0		U(SMMU_ROOT_PAGE_OFFSET + 0x0000)
+#define SMMU_ROOT_IIDR		U(SMMU_ROOT_PAGE_OFFSET + 0x0008)
+#define SMMU_ROOT_CR0		U(SMMU_ROOT_PAGE_OFFSET + 0x0020)
+#define SMMU_ROOT_CR0ACK	U(SMMU_ROOT_PAGE_OFFSET + 0x0024)
+#define SMMU_ROOT_GPT_BASE	U(SMMU_ROOT_PAGE_OFFSET + 0x0028)
+#define SMMU_ROOT_GPT_BASE_CFG	U(SMMU_ROOT_PAGE_OFFSET + 0x0030)
+#define SMMU_ROOT_GPF_FAR	U(SMMU_ROOT_PAGE_OFFSET + 0x0038)
+#define SMMU_ROOT_GPT_CFG_FAR	U(SMMU_ROOT_PAGE_OFFSET + 0x0040)
+#define SMMU_ROOT_TLBI		U(SMMU_ROOT_PAGE_OFFSET + 0x0050)
+#define SMMU_ROOT_TLBI_CTRL	U(SMMU_ROOT_PAGE_OFFSET + 0x0058)
+
+#endif /* ENABLE_RME */
+
 /* SMMU_GBPA register fields */
 #define SMMU_GBPA_UPDATE		(1UL << 31)
 #define SMMU_GBPA_ABORT			(1UL << 20)
@@ -30,6 +51,13 @@
 #define SMMU_S_GBPA_UPDATE		(1UL << 31)
 #define SMMU_S_GBPA_ABORT		(1UL << 20)
 
+/* SMMU_ROOT_IDR0 register fields */
+#define SMMU_ROOT_IDR0_ROOT_IMPL	(1UL << 0)
+
+/* SMMU_ROOT_CR0 register fields */
+#define SMMU_ROOT_CR0_GPCEN		(1UL << 1)
+#define SMMU_ROOT_CR0_ACCESSEN		(1UL << 0)
+
 int smmuv3_init(uintptr_t smmu_base);
 int smmuv3_security_init(uintptr_t smmu_base);
 
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 62530e2..92140b1 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -34,6 +34,12 @@
 #define CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT			U(1)
 
 /*******************************************************************************
+ * CPU Auxiliary Control Register definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR_EL1					S3_0_C15_C1_0
+#define CORTEX_X2_CPUACTLR_EL1_BIT_22				(ULL(1) << 22)
+
+/*******************************************************************************
  * CPU Auxiliary Control Register 5 definitions
  ******************************************************************************/
 #define CORTEX_X2_CPUACTLR5_EL1					S3_0_C15_C8_0
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
new file mode 100644
index 0000000..aac1ace
--- /dev/null
+++ b/include/lib/extensions/brbe.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BRBE_H
+#define BRBE_H
+
+void brbe_enable(void);
+
+#endif /* BRBE_H */
diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h
deleted file mode 100644
index eac4aa3..0000000
--- a/include/lib/extensions/twed.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TWED_H
-#define TWED_H
-
-#include <stdint.h>
-
-#define TWED_DISABLED U(0xFFFFFFFF)
-
-uint32_t plat_arm_set_twedel_scr_el3(void);
-
-#endif /* TWEDE_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index ff51c6c..43f298e 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,13 @@
 	uintptr_t config_addr;
 	uint32_t config_max_size;
 	unsigned int config_id;
+	/*
+	 * Load address in non-secure memory. Only needed by those
+	 * configuration files which require being loaded in secure
+	 * memory (at config_addr) as well as in non-secure memory
+	 * - e.g. HW_CONFIG
+	 */
+	uintptr_t ns_config_addr;
 };
 
 unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -25,7 +32,8 @@
 int fconf_populate_dtb_registry(uintptr_t config);
 
 /* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
-			unsigned int config_id);
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+		     uint32_t config_max_size,
+		     unsigned int config_id);
 
 #endif /* FCONF_DYN_CFG_GETTER_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 2af8c11..a8211bd 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -284,12 +284,10 @@
 					ARM_EL3_TZC_DRAM1_SIZE,		\
 					MT_MEMORY | MT_RW | EL3_PAS)
 
-#if defined(SPD_spmd)
 #define ARM_MAP_TRUSTED_DRAM	MAP_REGION_FLAT(			\
 					PLAT_ARM_TRUSTED_DRAM_BASE,	\
 					PLAT_ARM_TRUSTED_DRAM_SIZE,	\
 					MT_MEMORY | MT_RW | MT_SECURE)
-#endif
 
 #if ENABLE_RME
 #define ARM_MAP_RMM_DRAM	MAP_REGION_FLAT(			\
@@ -620,7 +618,7 @@
  * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
  * controller.
  */
-# if SPM_MM
+# if SPM_MM || SPMC_AT_EL3
 #  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
 #  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
 #  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
@@ -666,12 +664,13 @@
 
 /*
  * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
- * SPD and no SPM-MM, as they are the only ones that can be used as BL32.
+ * SPD and no SPM-MM and no SPMC-AT-EL3, as they are the only ones that can be
+ * used as BL32.
  */
 #if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
-# if defined(SPD_none) && !SPM_MM
+# if defined(SPD_none) && !SPM_MM && !SPMC_AT_EL3
 #  undef BL32_BASE
-# endif /* defined(SPD_none) && !SPM_MM */
+# endif /* defined(SPD_none) && !SPM_MM || !SPMC_AT_EL3 */
 #endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
 
 /*******************************************************************************
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
new file mode 100644
index 0000000..7ec9958
--- /dev/null
+++ b/include/services/el3_spmc_logical_sp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef EL3_SP_H
+#define EL3_SP_H
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+
+/*******************************************************************************
+ * Structure definition, typedefs & constants for the Logical SPs.
+ ******************************************************************************/
+
+typedef uint64_t (*direct_msg_handler)(uint32_t smc_fid, bool secure_origin,
+				       uint64_t x1, uint64_t x2, uint64_t x3,
+				       uint64_t x4, void *cookie, void *handle,
+				       uint64_t flags);
+
+/* Prototype for logical partition initializing function. */
+typedef int32_t (*ffa_partition_init_t)(void);
+
+/* Logical Partition Descriptor. */
+struct el3_lp_desc {
+	ffa_partition_init_t init;
+	uint16_t sp_id;
+	uint32_t properties;
+	uint32_t uuid[4];  /* Little Endian. */
+	direct_msg_handler direct_req;
+	const char *debug_name;
+};
+
+/* Convenience macro to declare a logical partition descriptor. */
+#define DECLARE_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties, \
+				  _direct_req)				    \
+	static const struct el3_lp_desc __partition_desc_ ## _name	    \
+		__section("el3_lp_descs") __used = {			    \
+			.debug_name = #_name,				    \
+			.init = (_init),				    \
+			.sp_id = (_sp_id),				    \
+			.uuid = _uuid,					    \
+			.properties = (_properties),			    \
+			.direct_req = (_direct_req),			    \
+		}
+
+
+/*******************************************************************************
+ * Function & variable prototypes.
+ ******************************************************************************/
+int el3_sp_desc_validate(void);
+uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle,
+						unsigned int flags);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__,	EL3_LP_DESCS_START);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__,	EL3_LP_DESCS_END);
+
+#define EL3_LP_DESCS_COUNT ((EL3_LP_DESCS_END - EL3_LP_DESCS_START) \
+			  / sizeof(struct el3_lp_desc))
+
+#endif /* EL3_SP_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 9a7c489..2b4a377 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #ifndef FFA_SVC_H
 #define FFA_SVC_H
 
+#include <stdbool.h>
+
 #include <lib/smccc.h>
 #include <lib/utils_def.h>
 #include <tools_share/uuid.h>
@@ -107,6 +109,7 @@
 #define FFA_VERSION		FFA_FID(SMC_32, FFA_FNUM_VERSION)
 #define FFA_FEATURES		FFA_FID(SMC_32, FFA_FNUM_FEATURES)
 #define FFA_RX_RELEASE		FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
+#define FFA_RX_ACQUIRE		FFA_FID(SMC_32, FFA_FNUM_RX_ACQUIRE)
 #define FFA_RXTX_MAP_SMC32	FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
 #define FFA_RXTX_UNMAP		FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
 #define FFA_PARTITION_INFO_GET	FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
@@ -161,6 +164,13 @@
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
 
 /*
+ * FF-A partition properties values.
+ */
+#define FFA_PARTITION_DIRECT_REQ_RECV	U(1 << 0)
+#define FFA_PARTITION_DIRECT_REQ_SEND	U(1 << 1)
+#define FFA_PARTITION_INDIRECT_MSG	U(1 << 2)
+
+/*
  * Reserve a special value for traffic targeted to the Hypervisor or SPM.
  */
 #define FFA_TARGET_INFO_MBZ		U(0x0)
@@ -176,6 +186,15 @@
 #define FFA_ENDPOINT_ID_MAX			U(1 << 16)
 
 /*
+ * Reserve endpoint id for the SPMD.
+ */
+#define SPMD_DIRECT_MSG_ENDPOINT_ID		U(FFA_ENDPOINT_ID_MAX - 1)
+
+/* Mask and shift to check valid secure FF-A Endpoint ID. */
+#define SPMC_SECURE_ID_MASK			U(1)
+#define SPMC_SECURE_ID_SHIFT			U(15)
+
+/*
  * Mask for source and destination endpoint id in
  * a direct message request/response.
  */
@@ -209,4 +228,24 @@
 		FFA_DIRECT_MSG_ENDPOINT_ID_MASK;
 }
 
+/******************************************************************************
+ * FF-A helper functions to determine partition ID world.
+ *****************************************************************************/
+
+/*
+ * Determine if provided ID is in the secure world.
+ */
+static inline bool ffa_is_secure_world_id(uint16_t id)
+{
+	return ((id >> SPMC_SECURE_ID_SHIFT) & SPMC_SECURE_ID_MASK) == 1;
+}
+
+/*
+ * Determine if provided ID is in the normal world.
+ */
+static inline bool ffa_is_normal_world_id(uint16_t id)
+{
+	return !ffa_is_secure_world_id(id);
+}
+
 #endif /* FFA_SVC_H */
diff --git a/include/services/spmc_svc.h b/include/services/spmc_svc.h
new file mode 100644
index 0000000..8ee61e9
--- /dev/null
+++ b/include/services/spmc_svc.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_SVC_H
+#define SPMC_SVC_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+#include <services/ffa_svc.h>
+#include <services/spm_core_manifest.h>
+
+int spmc_setup(void);
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs);
+void *spmc_get_config_addr(void);
+
+void spmc_set_config_addr(uintptr_t soc_fw_config);
+
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+			  bool secure_origin,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags);
+
+static inline bool is_spmc_at_el3(void)
+{
+	return SPMC_AT_EL3 == 1;
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMC_SVC_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index 1e7e6aa..29dfdad 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,14 @@
 #include <stdint.h>
 
 int spmd_setup(void);
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+			      uint64_t x1,
+			      uint64_t x2,
+			      uint64_t x3,
+			      uint64_t x4,
+			      void *cookie,
+			      void *handle,
+			      uint64_t flags);
 uint64_t spmd_smc_handler(uint32_t smc_fid,
 			  uint64_t x1,
 			  uint64_t x2,
@@ -20,6 +28,13 @@
 			  void *cookie,
 			  void *handle,
 			  uint64_t flags);
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+			       bool secure_origin,
+			       uint64_t x1,
+			       uint64_t x2,
+			       uint64_t x3,
+			       uint64_t x4,
+			       void *handle);
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_SVC_H */
diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h
deleted file mode 100644
index 53668e0..0000000
--- a/include/tools_share/sptool.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPTOOL_H
-#define SPTOOL_H
-
-#include <stdint.h>
-
-/* 4 Byte magic name "SPKG" */
-#define SECURE_PARTITION_MAGIC		0x474B5053
-
-/* Header for a secure partition package. */
-struct sp_pkg_header {
-	uint32_t magic;
-	uint32_t version;
-	uint32_t pm_offset;
-	uint32_t pm_size;
-	uint32_t img_offset;
-	uint32_t img_size;
-};
-
-#endif /* SPTOOL_H */
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index ab136ad..1143e9b 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -100,6 +100,15 @@
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	r0, #ERRATA_APPLIES
+#else
+	mov	r0, #ERRATA_MISSING
+#endif
+	bx	lr
+endfunc check_errata_cve_2022_23960
+
 #if REPORT_ERRATA
 /*
  * Errata printing function for Cortex A15. Must follow AAPCS.
@@ -117,6 +126,7 @@
 	report_errata ERRATA_A15_816470, cortex_a15, 816470
 	report_errata ERRATA_A15_827671, cortex_a15, 827671
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a15, cve_2017_5715
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a15, cve_2022_23960
 
 	pop	{r12, lr}
 	bx	lr
@@ -131,11 +141,11 @@
 	bl	errata_a15_827671_wa
 #endif
 
-#if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
+#if IMAGE_BL32 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
 	ldcopr	r0, ACTLR
 	orr	r0, #CORTEX_A15_ACTLR_INV_BTB_BIT
 	stcopr	r0, ACTLR
-	ldr	r0, =workaround_icache_inv_runtime_exceptions
+	ldr	r0, =wa_cve_2017_5715_icache_inv_vbar
 	stcopr	r0, VBAR
 	stcopr	r0, MVBAR
 	/* isb will be applied in the course of the reset func */
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 9586a5b..90a906b 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -237,6 +237,36 @@
 	ret
 endfunc check_errata_cve_2022_23960
 
+	/* ---------------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Errata 2147715.
+	 * This applies only to revisions r2p0 and is fixed in r2p1.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0, x1, x17
+	 * ---------------------------------------------------------
+	 */
+func errata_x2_2147715_wa
+	/* Compare x0 against revision r2p0 */
+	mov     x17, x30
+	bl      check_errata_2147715
+	cbz     x0, 1f
+
+	/* Apply the workaround by setting bit 22 in CPUACTLR_EL1. */
+	mrs     x1, CORTEX_X2_CPUACTLR_EL1
+	orr     x1, x1, CORTEX_X2_CPUACTLR_EL1_BIT_22
+	msr     CORTEX_X2_CPUACTLR_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_x2_2147715_wa
+
+func check_errata_2147715
+	/* Applies to r2p0 */
+	mov	x1, #0x20
+	mov	x2, #0x20
+	b	cpu_rev_var_range
+endfunc check_errata_2147715
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -268,10 +298,11 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_X2_2002765, cortex_x2, 2002765
-	report_errata ERRATA_X2_2058056, cortex_x2, 2058056
-	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
 	report_errata ERRATA_X2_2017096, cortex_x2, 2017096
+	report_errata ERRATA_X2_2058056, cortex_x2, 2058056
 	report_errata ERRATA_X2_2081180, cortex_x2, 2081180
+	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
+	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
 	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
 
@@ -321,6 +352,11 @@
 	bl	errata_x2_2216384_wa
 #endif
 
+#if ERRATA_X2_2147715
+	mov	x0, x18
+	bl	errata_x2_2147715_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Cortex-X2 generic vectors are overridden to apply errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 8840f8e..462ca9d 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -547,6 +547,10 @@
 # r2p1.
 ERRATA_X2_2216384	?=0
 
+# Flag to apply erratum 2147715 workaround during reset. This erratum applies
+# only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
+ERRATA_X2_2147715	?=0
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 ERRATA_A510_1922240	?=0
@@ -1046,6 +1050,10 @@
 $(eval $(call assert_boolean,ERRATA_X2_2216384))
 $(eval $(call add_define,ERRATA_X2_2216384))
 
+# Process ERRATA_X2_2147715 flag
+$(eval $(call assert_boolean,ERRATA_X2_2147715))
+$(eval $(call add_define,ERRATA_X2_2147715))
+
 # Process ERRATA_A510_1922240 flag
 $(eval $(call assert_boolean,ERRATA_A510_1922240))
 $(eval $(call add_define,ERRATA_A510_1922240))
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 459ca2c..449f120 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -20,6 +20,7 @@
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
+#include <lib/extensions/brbe.h>
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
@@ -27,11 +28,14 @@
 #include <lib/extensions/sys_reg_trace.h>
 #include <lib/extensions/trbe.h>
 #include <lib/extensions/trf.h>
-#include <lib/extensions/twed.h>
 #include <lib/utils.h>
 
-static void manage_extensions_secure(cpu_context_t *ctx);
+#if ENABLE_FEAT_TWED
+/* Make sure delay value fits within the range(0-15) */
+CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
+#endif /* ENABLE_FEAT_TWED */
 
+static void manage_extensions_secure(cpu_context_t *ctx);
 /******************************************************************************
  * This function performs initializations that are specific to SECURE state
  * and updates the cpu context specified by 'ctx'.
@@ -329,23 +333,16 @@
 	sctlr_elx |= SCTLR_IESB_BIT;
 #endif
 
+#if ENABLE_FEAT_TWED
 	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
-	if (is_armv8_6_twed_present()) {
-		uint32_t delay = plat_arm_set_twedel_scr_el3();
+	/* Set delay in SCR_EL3 */
+	scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+	scr_el3 |= ((TWED_DELAY & SCR_TWEDEL_MASK)
+			<< SCR_TWEDEL_SHIFT);
 
-		if (delay != TWED_DISABLED) {
-			/* Make sure delay value fits */
-			assert((delay & ~SCR_TWEDEL_MASK) == 0U);
-
-			/* Set delay in SCR_EL3 */
-			scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
-			scr_el3 |= ((delay & SCR_TWEDEL_MASK)
-					<< SCR_TWEDEL_SHIFT);
-
-			/* Enable WFE delay */
-			scr_el3 |= SCR_TWEDEn_BIT;
-		}
-	}
+	/* Enable WFE delay */
+	scr_el3 |= SCR_TWEDEn_BIT;
+#endif /* ENABLE_FEAT_TWED */
 
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
@@ -473,6 +470,10 @@
 	trbe_enable();
 #endif /* ENABLE_TRBE_FOR_NS */
 
+#if ENABLE_BRBE_FOR_NS
+	brbe_enable();
+#endif /* ENABLE_BRBE_FOR_NS */
+
 #if ENABLE_SYS_REG_TRACE_FOR_NS
 	sys_reg_trace_enable(ctx);
 #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
new file mode 100644
index 0000000..6975b04
--- /dev/null
+++ b/lib/extensions/brbe/brbe.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+
+static bool brbe_supported(void)
+{
+	uint64_t features;
+
+	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT;
+	return ((features & ID_AA64DFR0_BRBE_MASK) ==
+		ID_AA64DFR0_BRBE_SUPPORTED);
+}
+
+void brbe_enable(void)
+{
+	uint64_t val;
+
+	if (brbe_supported()) {
+		/*
+		 * MDCR_EL3.SBRBE = 0b01
+		 *
+		 * Allows BRBE usage in non-secure world and prohibited in
+		 * secure world.
+		 */
+		val = read_mdcr_el3();
+		val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+		val |= (0x1UL << MDCR_SBRBE_SHIFT);
+		write_mdcr_el3(val);
+	}
+}
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 34623fb..3038c09 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,13 +29,15 @@
  * This function is used to alloc memory for config information from
  * global pool and set the configuration information.
  */
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
-			unsigned int config_id)
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+		     uint32_t config_max_size,
+		     unsigned int config_id)
 {
 	struct dyn_cfg_dtb_info_t *dtb_info;
 
 	dtb_info = pool_alloc(&dtb_info_pool);
 	dtb_info->config_addr = config_addr;
+	dtb_info->ns_config_addr = ns_config_addr;
 	dtb_info->config_max_size = config_max_size;
 	dtb_info->config_id = config_id;
 }
@@ -88,7 +90,7 @@
 	 */
 	if (dtb_infos[0].config_id == 0U) {
 		uint32_t config_max_size = fdt_totalsize(dtb);
-		set_config_info(config, config_max_size, FW_CONFIG_ID);
+		set_config_info(config, ~0UL, config_max_size, FW_CONFIG_ID);
 	}
 
 	/* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */
@@ -102,6 +104,7 @@
 	fdt_for_each_subnode(child, dtb, node) {
 		uint32_t config_max_size, config_id;
 		uintptr_t config_addr;
+		uintptr_t ns_config_addr = ~0UL;
 		uint64_t val64;
 
 		/* Read configuration dtb information */
@@ -129,7 +132,14 @@
 		VERBOSE("\tmax-size = 0x%x\n", config_max_size);
 		VERBOSE("\tconfig-id = %u\n", config_id);
 
-		set_config_info(config_addr, config_max_size, config_id);
+		rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+		if (rc == 0) {
+			ns_config_addr = (uintptr_t)val64;
+			VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+		}
+
+		set_config_info(config_addr, ns_config_addr, config_max_size,
+				config_id);
 	}
 
 	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index 7d35dea..faea6c5 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -83,7 +83,7 @@
 }
 
 /* Helper function to check if the lock is acquired */
-static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info,
+static inline __unused bool is_lock_acquired(const bakery_info_t *my_bakery_info,
 				    bool is_cached)
 {
 	/*
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
index 7991e1a..fb8a426 100644
--- a/lib/xlat_tables_v2/ro_xlat_tables.mk
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2020-2022, ARM Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -34,4 +34,8 @@
                  attributes, which is not possible once the translation tables \
                  have been made read-only.")
     endif
+    ifeq (${SPMC_AT_EL3},1)
+        $(error "EL3 SPMC requires functionality from the dynamic translation \
+                 library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+    endif
 endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 12aaee6..a58caf5 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -489,6 +489,10 @@
 $(ELF): romlib.bin
 endif
 
+# MODULE_OBJS can be assigned by vendors with different compiled
+# object file path, and prebuilt object file path.
+$(eval OBJS += $(MODULE_OBJS))
+
 $(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
 	$$(ECHO) "  LD      $$@"
 ifdef MAKE_BUILD_STRINGS
@@ -507,7 +511,7 @@
 		$(BUILD_DIR)/build_message.o $(OBJS)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
-		-Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \
+		-Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 99f44a4..6e57237 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -169,6 +169,9 @@
 # Flag to enable Virtualization Host Extensions
 ENABLE_FEAT_VHE 		:= 0
 
+# Flag to enable delayed trapping of WFE instruction (FEAT_TWED)
+ENABLE_FEAT_TWED		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -254,6 +257,9 @@
 # By default, BL1 acts as the reset handler, not BL31
 RESET_TO_BL31			:= 0
 
+# By default, clear the input registers when RESET_TO_BL31 is enabled
+RESET_TO_BL31_WITH_PARAMS	:= 0
+
 # For Chain of Trust
 SAVE_KEYS			:= 0
 
@@ -288,6 +294,9 @@
 # Enable the Management Mode (MM)-based Secure Partition Manager implementation
 SPM_MM				:= 0
 
+# Use the FF-A SPMC implementation in EL3.
+SPMC_AT_EL3			:= 0
+
 # Use SPM at S-EL2 as a default config for SPMD
 SPMD_SPM_AT_SEL2		:= 1
 
@@ -431,6 +440,11 @@
 	override ENABLE_TRBE_FOR_NS	:= 0
 endif
 
+# By default, disable access to branch record buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_BRBE is implemented.
+ENABLE_BRBE_FOR_NS		:= 0
+
 # By default, disable access of trace system registers from NS lower
 # ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
 # system register trace is implemented.
@@ -440,3 +454,9 @@
 # lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
 # if FEAT_TRF is implemented.
 ENABLE_TRF_FOR_NS		:= 0
+
+# In v8.6+ platforms with delayed trapping of WFE being supported
+# via FEAT_TWED, this flag takes the delay value to be set in the
+# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
+# By default it takes 0, and need to be updated by the platforms.
+TWED_DELAY			:= 0
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 34fdaf6..61c1dbe 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -27,6 +27,7 @@
 				plat/common/plat_gicv2.c		\
 				plat/common/plat_psci_common.c		\
 				${AW_PLAT}/common/sunxi_bl31_setup.c	\
+				${AW_PLAT}/${PLAT}/sunxi_idle_states.c	\
 				${AW_PLAT}/common/sunxi_pm.c		\
 				${AW_PLAT}/${PLAT}/sunxi_power.c	\
 				${AW_PLAT}/common/sunxi_security.c	\
@@ -65,6 +66,23 @@
 $(eval $(call assert_boolean,SUNXI_SETUP_REGULATORS))
 $(eval $(call add_define,SUNXI_SETUP_REGULATORS))
 
+SUNXI_BL31_IN_DRAM	?=	0
+$(eval $(call assert_boolean,SUNXI_BL31_IN_DRAM))
+
+ifeq (${SUNXI_BL31_IN_DRAM},1)
+SUNXI_AMEND_DTB		:=	1
+$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
+endif
+
+SUNXI_AMEND_DTB		?=	0
+$(eval $(call assert_boolean,SUNXI_AMEND_DTB))
+$(eval $(call add_define,SUNXI_AMEND_DTB))
+
+ifeq (${SUNXI_AMEND_DTB},1)
+BL31_SOURCES		+=	common/fdt_fixup.c			\
+				${AW_PLAT}/common/sunxi_prepare_dtb.c
+endif
+
 # The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
 COLD_BOOT_SINGLE_CPU		:=	1
 
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 49951e0..c9d075a 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -57,9 +57,10 @@
 #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
 	(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
 
-#define PLAT_MAX_PWR_LVL_STATES		U(2)
+/* These states are used directly for SCPI communication. */
+#define PLAT_MAX_PWR_LVL_STATES		U(3)
 #define PLAT_MAX_RET_STATE		U(1)
-#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_OFF_STATE		U(3)
 
 #define PLAT_MAX_PWR_LVL		U(2)
 #define PLAT_NUM_PWR_DOMAINS		(U(1) + \
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index ec50887..c17ef95 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,4 +20,7 @@
 #define SUNXI_SOC_H616			0x1823
 #define SUNXI_SOC_R329			0x1851
 
+#define JEDEC_ALLWINNER_BKID		9U
+#define JEDEC_ALLWINNER_MFID		0x9eU
+
 #endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6cf4670..6a38657 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -7,8 +7,12 @@
 #ifndef SUNXI_PRIVATE_H
 #define SUNXI_PRIVATE_H
 
+#include <common/fdt_fixup.h>
+
 #include <lib/psci/psci.h>
 
+extern const struct psci_cpu_idle_state sunxi_idle_states[];
+
 void sunxi_configure_mmu_el3(int flags);
 
 void sunxi_cpu_on(u_register_t mpidr);
@@ -24,8 +28,13 @@
 }
 #endif
 #if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void);
 int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops);
 #else
+static inline bool sunxi_psci_is_scpi(void)
+{
+	return false;
+}
 static inline int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops)
 {
 	return -1;
@@ -41,7 +50,7 @@
 int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
 void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
 
-#ifdef SUNXI_BL31_IN_DRAM
+#if SUNXI_AMEND_DTB
 void sunxi_prepare_dtb(void *fdt);
 #else
 static inline void sunxi_prepare_dtb(void *fdt)
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 14049e8..a32124a 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,8 @@
 
 static console_t console;
 
+static void *fdt;
+
 static const gicv2_driver_data_t sunxi_gic_data = {
 	.gicd_base = SUNXI_GICD_BASE,
 	.gicc_base = SUNXI_GICC_BASE,
@@ -49,7 +51,7 @@
  * entry point to find the load address, which should be followed by the
  * size. Adding those together gives us the address of the DTB.
  */
-static void *sunxi_find_dtb(void)
+static void sunxi_find_dtb(void)
 {
 	uint64_t *u_boot_base;
 	int i;
@@ -57,7 +59,7 @@
 	u_boot_base = (void *)SUNXI_BL33_VIRT_BASE;
 
 	for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
-		uint32_t *dtb_base;
+		void *dtb_base;
 
 		if (u_boot_base[i] != PRELOADED_BL33_BASE)
 			continue;
@@ -67,15 +69,13 @@
 			continue;
 
 		/* end of the image: base address + size */
-		dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
-
-		if (fdt_check_header(dtb_base) != 0)
-			continue;
+		dtb_base = (char *)u_boot_base + u_boot_base[i + 1];
 
-		return dtb_base;
+		if (fdt_check_header(dtb_base) == 0) {
+			fdt = dtb_base;
+			return;
+		}
 	}
-
-	return NULL;
 }
 
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
@@ -113,7 +113,6 @@
 {
 	const char *soc_name;
 	uint16_t soc_id = sunxi_read_soc_id();
-	void *fdt;
 
 	switch (soc_id) {
 	case SUNXI_SOC_A64:
@@ -139,7 +138,7 @@
 
 	generic_delay_timer_init();
 
-	fdt = sunxi_find_dtb();
+	sunxi_find_dtb();
 	if (fdt) {
 		const char *model;
 		int length;
@@ -180,9 +179,15 @@
 
 	sunxi_pmic_setup(soc_id, fdt);
 
+	INFO("BL31: Platform setup done\n");
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	/* Change the DTB if the configuration requires so. */
 	sunxi_prepare_dtb(fdt);
 
-	INFO("BL31: Platform setup done\n");
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 82410b1..092659c 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -8,7 +8,9 @@
 
 #include <common/debug.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/arm_arch_svc.h>
 
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
@@ -157,3 +159,29 @@
 
 	return 0;
 }
+
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+}
+
+int32_t plat_get_soc_version(void)
+{
+	int32_t ret;
+
+	ret = SOC_ID_SET_JEP_106(JEDEC_ALLWINNER_BKID, JEDEC_ALLWINNER_MFID);
+
+	return ret | (sunxi_read_soc_id() & SOC_ID_IMPL_DEF_MASK);
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	uint32_t reg = mmio_read_32(SRAM_VER_REG);
+
+	return reg & GENMASK_32(7, 0);
+}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index eb1b7e7..3772b4a 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -9,12 +9,22 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
+#include <common/fdt_fixup.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 
 #include <sunxi_cpucfg.h>
 #include <sunxi_private.h>
 
+static bool psci_is_scpi;
+
+#if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void)
+{
+	return psci_is_scpi;
+}
+#endif
+
 int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
 {
 	/* The non-secure entry point must be in DRAM */
@@ -40,6 +50,7 @@
 
 	if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
 		INFO("PSCI: Suspend is available via SCPI\n");
+		psci_is_scpi = true;
 	} else {
 		INFO("PSCI: Suspend is unavailable\n");
 		sunxi_set_native_psci_ops(psci_ops);
diff --git a/plat/allwinner/sun50i_h616/prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
similarity index 69%
rename from plat/allwinner/sun50i_h616/prepare_dtb.c
rename to plat/allwinner/common/sunxi_prepare_dtb.c
index e94b0b4..66af35a 100644
--- a/plat/allwinner/sun50i_h616/prepare_dtb.c
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -19,25 +19,34 @@
 	if (fdt == NULL || fdt_check_header(fdt) != 0) {
 		return;
 	}
-	ret = fdt_open_into(fdt, fdt, 0x100000);
+
+	ret = fdt_open_into(fdt, fdt, 0x10000);
 	if (ret < 0) {
 		ERROR("Preparing devicetree at %p: error %d\n", fdt, ret);
 		return;
 	}
 
+#ifdef SUNXI_BL31_IN_DRAM
 	/* Reserve memory used by Trusted Firmware. */
 	if (fdt_add_reserved_memory(fdt, "tf-a@40000000", BL31_BASE,
 				    BL31_LIMIT - BL31_BASE)) {
 		WARN("Failed to add reserved memory nodes to DT.\n");
-		return;
 	}
+#endif
+
+	if (sunxi_psci_is_scpi()) {
+		ret = fdt_add_cpu_idle_states(fdt, sunxi_idle_states);
+		if (ret < 0) {
+			WARN("Failed to add idle states to DT: %d\n", ret);
+		}
+	}
 
 	ret = fdt_pack(fdt);
 	if (ret < 0) {
 		ERROR("Failed to pack devicetree at %p: error %d\n",
 		      fdt, ret);
-	} else {
-		clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
-		INFO("Changed devicetree to reserve BL31 memory.\n");
 	}
+
+	clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+	INFO("Changed devicetree.\n");
 }
diff --git a/plat/allwinner/common/sunxi_scpi_pm.c b/plat/allwinner/common/sunxi_scpi_pm.c
index eb37daa..41dc563 100644
--- a/plat/allwinner/common/sunxi_scpi_pm.c
+++ b/plat/allwinner/common/sunxi_scpi_pm.c
@@ -33,6 +33,9 @@
  */
 #define SCP_FIRMWARE_MAGIC		0xb4400012
 
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
 #define CPU_PWR_LVL			MPIDR_AFFLVL0
 #define CLUSTER_PWR_LVL			MPIDR_AFFLVL1
 #define SYSTEM_PWR_LVL			MPIDR_AFFLVL2
@@ -44,17 +47,6 @@
 #define SYSTEM_PWR_STATE(state) \
 	((state)->pwr_domain_state[SYSTEM_PWR_LVL])
 
-static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
-{
-	if (is_local_state_run(psci_state)) {
-		return scpi_power_on;
-	}
-	if (is_local_state_retn(psci_state)) {
-		return scpi_power_retention;
-	}
-	return scpi_power_off;
-}
-
 static void sunxi_cpu_standby(plat_local_state_t cpu_state)
 {
 	u_register_t scr = read_scr_el3();
@@ -87,9 +79,9 @@
 	}
 
 	scpi_set_css_power_state(read_mpidr(),
-				 scpi_map_state(cpu_pwr_state),
-				 scpi_map_state(cluster_pwr_state),
-				 scpi_map_state(system_pwr_state));
+				 cpu_pwr_state,
+				 cluster_pwr_state,
+				 system_pwr_state);
 }
 
 static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -137,7 +129,9 @@
 				      psci_power_state_t *req_state)
 {
 	unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+	unsigned int state_id = psci_get_pstate_id(power_state);
 	unsigned int type = psci_get_pstate_type(power_state);
+	unsigned int i;
 
 	assert(req_state != NULL);
 
@@ -146,28 +140,19 @@
 	}
 
 	if (type == PSTATE_TYPE_STANDBY) {
-		/* Only one retention power state is supported. */
-		if (psci_get_pstate_id(power_state) > 0) {
-			return PSCI_E_INVALID_PARAMS;
-		}
-		/* The SoC cannot be suspended without losing state */
-		if (power_level == SYSTEM_PWR_LVL) {
-			return PSCI_E_INVALID_PARAMS;
-		}
-		for (unsigned int i = 0; i <= power_level; ++i) {
-			req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
-		}
-	} else {
-		/* Only one off power state is supported. */
-		if (psci_get_pstate_id(power_state) > 0) {
-			return PSCI_E_INVALID_PARAMS;
-		}
-		for (unsigned int i = 0; i <= power_level; ++i) {
-			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
-		}
+		return PSCI_E_INVALID_PARAMS;
 	}
+
+	/* Pass through the requested PSCI state as-is. */
+	for (i = 0; i <= power_level; ++i) {
+		unsigned int local_pstate = state_id & PLAT_LOCAL_PSTATE_MASK;
+
+		req_state->pwr_domain_state[i] = local_pstate;
+		state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+	}
+
 	/* Higher power domain levels should all remain running */
-	for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i) {
+	for (; i <= PLAT_MAX_PWR_LVL; ++i) {
 		req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
 	}
 
diff --git a/plat/allwinner/sun50i_a64/sunxi_idle_states.c b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
new file mode 100644
index 0000000..2918bb7
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+	{
+		.name			= "cpu-sleep",
+		.power_state		= 0x00010003,
+		.local_timer_stop	= true,
+		.entry_latency_us	= 800,
+		.exit_latency_us	= 1500,
+		.min_residency_us	= 25000
+	},
+	{
+		.name			= "cluster-sleep",
+		.power_state		= 0x01010013,
+		.local_timer_stop	= true,
+		.entry_latency_us	= 850,
+		.exit_latency_us	= 1500,
+		.min_residency_us	= 50000
+	},
+	{}
+};
diff --git a/plat/allwinner/sun50i_h6/sunxi_idle_states.c b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+	{}
+};
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
index fc09af7..de494a2 100644
--- a/plat/allwinner/sun50i_h616/platform.mk
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+SUNXI_BL31_IN_DRAM	:=	1
+
 # Without a management processor there is no SCPI support.
 SUNXI_PSCI_USE_SCPI	:=	0
 SUNXI_PSCI_USE_NATIVE	:=	1
@@ -18,7 +20,3 @@
 
 BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
 				drivers/allwinner/sunxi_rsb.c		\
-				common/fdt_fixup.c			\
-				${AW_PLAT}/${PLAT}/prepare_dtb.c
-
-$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
diff --git a/plat/allwinner/sun50i_h616/sunxi_idle_states.c b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+	{}
+};
diff --git a/plat/allwinner/sun50i_r329/sunxi_idle_states.c b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+	{}
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index c26b519..577ac74 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,10 @@
 		};
 
 		hw-config {
-			load-address = <0x0 0x82000000>;
-			max-size = <0x01000000>;
+			load-address = <0x0 0x07f00000>;
+			max-size = <0x00100000>;
 			id = <HW_CONFIG_ID>;
+			ns-load-address = <0x0 0x82000000>;
 		};
 
 		/*
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index b803340..27f4724 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -22,7 +22,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x6280000>;
-	entrypoint-offset = <0x1000>;
+	entrypoint-offset = <0x4000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <0x3>; /* Direct request/response supported. */
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 5a17a0d..74e5d72 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,17 +40,23 @@
 struct bl_params *plat_get_next_bl_params(void)
 {
 	struct bl_params *arm_bl_params;
+	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+	bl_mem_params_node_t *param_node __unused;
 
 	arm_bl_params = arm_get_next_bl_params();
 
-#if __aarch64__ && !BL2_AT_EL3
+#if !BL2_AT_EL3 && !EL3_PAYLOAD_BASE
 	const struct dyn_cfg_dtb_info_t *fw_config_info;
-	bl_mem_params_node_t *param_node;
-	uintptr_t fw_config_base = 0U;
+	uintptr_t fw_config_base = 0UL;
 	entry_point_info_t *ep_info;
 
+#if __aarch64__
 	/* Get BL31 image node */
 	param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+#else /* aarch32 */
+	/* Get SP_MIN image node */
+	param_node = get_bl_mem_params_node(BL32_IMAGE_ID);
+#endif /* __aarch64__ */
 	assert(param_node != NULL);
 
 	/* get fw_config load address */
@@ -58,15 +64,42 @@
 	assert(fw_config_info != NULL);
 
 	fw_config_base = fw_config_info->config_addr;
-	assert(fw_config_base != 0U);
+	assert(fw_config_base != 0UL);
 
 	/*
-	 * Get the entry point info of BL31 image and override
+	 * Get the entry point info of next executable image and override
 	 * arg1 of entry point info with fw_config base address
 	 */
 	ep_info = &param_node->ep_info;
 	ep_info->args.arg1 = (uint32_t)fw_config_base;
-#endif /* __aarch64__ && !BL2_AT_EL3 */
+
+	/* grab NS HW config address */
+	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+	assert(hw_config_info != NULL);
+
+	/* To retrieve actual size of the HW_CONFIG */
+	param_node = get_bl_mem_params_node(HW_CONFIG_ID);
+	assert(param_node != NULL);
+
+	/* Copy HW config from Secure address to NS address */
+	memcpy((void *)hw_config_info->ns_config_addr,
+	       (void *)hw_config_info->config_addr,
+	       (size_t)param_node->image_info.image_size);
+
+	/*
+	 * Ensure HW-config device tree committed to memory, as there is
+	 * a possibility to use HW-config without cache and MMU enabled
+	 * at BL33
+	 */
+	flush_dcache_range(hw_config_info->ns_config_addr,
+			   param_node->image_info.image_size);
+
+	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
+	assert(param_node != NULL);
+
+	/* Update BL33's ep info with NS HW config address  */
+	param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
+#endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
 }
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index a94a4f4..dd90965 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -17,6 +17,8 @@
 
 #include "fvp_private.h"
 
+static const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+
 void __init bl31_early_platform_setup2(u_register_t arg0,
 		u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
@@ -34,6 +36,17 @@
 	if (soc_fw_config_info != NULL) {
 		arg1 = soc_fw_config_info->config_addr;
 	}
+
+	/*
+	 * arg2 is currently holding the 'secure' address of HW_CONFIG.
+	 * But arm_bl31_early_platform_setup() below expects the 'non-secure'
+	 * address of HW_CONFIG (which it will pass to BL33).
+	 * This why we need to override arg2 here.
+	 */
+	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+	assert(hw_config_info != NULL);
+	assert(hw_config_info->ns_config_addr != 0UL);
+	arg2 = hw_config_info->ns_config_addr;
 #endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
 
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
@@ -66,22 +79,57 @@
 
 void __init bl31_plat_arch_setup(void)
 {
+	int rc __unused;
+	uintptr_t hw_config_base_align __unused;
+	size_t mapped_size_align __unused;
+
 	arm_bl31_plat_arch_setup();
 
 	/*
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
 	 * So there is no BL2 to load the HW_CONFIG dtb into memory before
-	 * control is passed to BL31.
+	 * control is passed to BL31. The code below relies on dynamic mapping
+	 * capability, which is not supported by xlat tables lib V1.
+	 * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+	 * gets deprecated.
 	 */
-#if !RESET_TO_BL31 && !BL2_AT_EL3
-	/* HW_CONFIG was also loaded by BL2 */
-	const struct dyn_cfg_dtb_info_t *hw_config_info;
-
-	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+#if !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
 	assert(hw_config_info != NULL);
+	assert(hw_config_info->config_addr != 0UL);
 
+	/* Page aligned address and size if necessary */
+	hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+	mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+	if ((hw_config_info->config_addr != hw_config_base_align) &&
+	    (hw_config_info->config_max_size == mapped_size_align)) {
+		mapped_size_align += PAGE_SIZE;
+	}
+
+	/*
+	 * map dynamically HW config region with its aligned base address and
+	 * size
+	 */
+	rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+				     hw_config_base_align,
+				     mapped_size_align,
+				     MT_RO_DATA);
+	if (rc != 0) {
+		ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+		panic();
+	}
+
+	/* Populate HW_CONFIG device tree with the mapped address */
 	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
-#endif
+
+	/* unmap the HW_CONFIG memory region */
+	rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+	if (rc != 0) {
+		ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+		      rc);
+		panic();
+	}
+#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
 }
 
 unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index d8d19de..a7028f6 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -104,9 +104,10 @@
 #ifdef __aarch64__
 	ARM_MAP_DRAM2,
 #endif
-#if defined(SPD_spmd)
+	/*
+	 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
+	 */
 	ARM_MAP_TRUSTED_DRAM,
-#endif
 #if ENABLE_RME
 	ARM_MAP_RMM_DRAM,
 	ARM_MAP_GPT_L1_DRAM,
@@ -126,7 +127,7 @@
 	 */
 	ARM_MAP_BL1_RW,
 #endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */
-#if SPM_MM
+#if SPM_MM || SPMC_AT_EL3
 	ARM_SP_IMAGE_MMAP,
 #endif
 #if ARM_BL31_IN_DRAM
@@ -166,8 +167,6 @@
 #if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
-	/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
-	ARM_DTB_DRAM_NS,
 #if ENABLE_RME
 	ARM_MAP_GPT_L1_DRAM,
 #endif
@@ -197,8 +196,6 @@
 	V2M_MAP_IOFPGA,
 	MAP_DEVICE0,
 	MAP_DEVICE1,
-	/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
-	ARM_DTB_DRAM_NS,
 	{0}
 };
 #endif
diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
new file mode 100644
index 0000000..b9e4f86
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <smccc_helpers.h>
+
+#define LP_PARTITION_ID 0xC001
+#define LP_UUID {0x47a3bf57, 0xe98e43ad, 0xb7db524f, 0x1588f4e3}
+
+/* Our Logical SP currently only supports receipt of direct messaging. */
+#define PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_RECV
+
+static int32_t sp_init(void)
+{
+	INFO("LSP: Init function called.\n");
+	return 0;
+}
+
+static uint64_t handle_ffa_direct_request(uint32_t smc_fid,  bool secure_origin,
+					  uint64_t x1, uint64_t x2, uint64_t x3,
+					  uint64_t x4, void *cookie,
+					  void *handle, uint64_t flags)
+{
+	uint64_t ret;
+
+	/* Determine if we have a 64 or 32 direct request. */
+	if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
+		ret = FFA_MSG_SEND_DIRECT_RESP_SMC32;
+	} else if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
+		ret = FFA_MSG_SEND_DIRECT_RESP_SMC64;
+	} else {
+		panic(); /* Unknown SMC. */
+	}
+	/*
+	 * Handle the incoming request. For testing purposes we echo the
+	 * incoming message.
+	 */
+	INFO("Logical Partition: Received Direct Request from %s world!\n",
+	     secure_origin ? "Secure" : "Normal");
+
+	/*
+	 * Logical SP's must always send a direct response so we can populate
+	 * our response directly.
+	 */
+	SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+}
+
+/* Register logical partition  */
+DECLARE_LOGICAL_PARTITION(
+	my_logical_partition,
+	sp_init,			/* Init Function */
+	LP_PARTITION_ID,		/* FF-A Partition ID */
+	LP_UUID,			/* UUID */
+	PARTITION_PROPERTIES,		/* Partition Properties. */
+	handle_ffa_direct_request	/* Callback for direct requests. */
+);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 5e5ddce..82bd7c8 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -90,6 +90,31 @@
 					FVP_DTB_DRAM_MAP_START,		\
 					FVP_DTB_DRAM_MAP_SIZE,		\
 					MT_MEMORY | MT_RO | MT_NS)
+
+#if SPMC_AT_EL3
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * secure partitions.
+ */
+#define SECURE_PARTITION_COUNT		1
+
+/*
+ * Number of Normal World Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * NWd partitions.
+ */
+#define NS_PARTITION_COUNT		1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT		1
+
+#endif /* SPMC_AT_EL3 */
+
 /*
  * Load address of BL33 for this platform port
  */
@@ -106,9 +131,12 @@
 #   define MAX_XLAT_TABLES		11
 #  else
 #   define MAX_XLAT_TABLES		9
-# endif
+#  endif
 #  define PLAT_SP_IMAGE_MMAP_REGIONS	30
 #  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
+# elif SPMC_AT_EL3
+#  define PLAT_ARM_MMAP_ENTRIES		13
+#  define MAX_XLAT_TABLES		11
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		9
 #  if USE_DEBUGFS
@@ -126,8 +154,13 @@
 #  endif
 # endif
 #elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES		9
-# define MAX_XLAT_TABLES		6
+# if SPMC_AT_EL3
+#  define PLAT_ARM_MMAP_ENTRIES		270
+#  define MAX_XLAT_TABLES		10
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		9
+#  define MAX_XLAT_TABLES		6
+# endif
 #elif !USE_ROMLIB
 # define PLAT_ARM_MMAP_ENTRIES		11
 # define MAX_XLAT_TABLES		5
@@ -261,6 +294,7 @@
 #define PLAT_ARM_TRP_UART_CLK_IN_HZ	V2M_IOFPGA_UART3_CLK_IN_HZ
 
 #define PLAT_FVP_SMMUV3_BASE		UL(0x2b400000)
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET UL(0x20000)
 
 /* CCI related constants */
 #define PLAT_FVP_CCI400_BASE		UL(0x2c090000)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index b72bdab..85e6e3a 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -35,6 +35,8 @@
 fdt     fdt_get_name
 fdt     fdt_get_alias
 fdt     fdt_node_offset_by_phandle
+fdt     fdt_subnode_offset
+fdt     fdt_add_subnode
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
 mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c9f5551..d89e91f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -333,15 +333,10 @@
 endif
 
 # Enable the dynamic translation tables library.
-ifeq (${ARCH},aarch32)
-    ifeq (${RESET_TO_SP_MIN},1)
+ifeq ($(filter 1,${BL2_AT_EL3} ${ARM_XLAT_TABLES_LIB_V1}),)
+    ifeq (${ARCH},aarch32)
         BL32_CPPFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC
-    endif
-else # AArch64
-    ifeq (${RESET_TO_BL31},1)
-        BL31_CPPFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC
-    endif
-    ifeq (${SPD},trusty)
+    else # AArch64
         BL31_CPPFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC
     endif
 endif
@@ -394,6 +389,15 @@
 # enable trace buffer control registers access to NS by default
 ENABLE_TRBE_FOR_NS		:= 1
 
+# enable branch record buffer control registers access in NS by default
+# only enable for aarch64
+# do not enable when ENABLE_RME=1
+ifeq (${ARCH}, aarch64)
+ifeq (${ENABLE_RME},0)
+	ENABLE_BRBE_FOR_NS		:= 1
+endif
+endif
+
 # enable trace system registers access to NS by default
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 1
 
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 763b42a..9ab36a6 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,15 +9,31 @@
 #include <bl32/sp_min/platform_sp_min.h>
 #include <common/debug.h>
 #include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
 
 #include "../fvp_private.h"
 
-uintptr_t hw_config_dtb;
-
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
+	const struct dyn_cfg_dtb_info_t *tos_fw_config_info __unused;
+
+	/* Initialize the console to provide early debug support */
+	arm_console_boot_init();
+
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+
+	INFO("SP_MIN FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
+	/* Fill the properties struct with the info from the config dtb */
+	fconf_populate("FW_CONFIG", arg1);
+
+	tos_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+	if (tos_fw_config_info != NULL) {
+		arg1 = tos_fw_config_info->config_addr;
+	}
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 */
+
 	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 
 	/* Initialize the platform config for future decision making */
@@ -37,12 +53,15 @@
 	 * FVP PSCI code will enable coherency for other clusters.
 	 */
 	fvp_interconnect_enable();
-
-	hw_config_dtb = arg2;
 }
 
 void sp_min_plat_arch_setup(void)
 {
+	int rc __unused;
+	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+	uintptr_t hw_config_base_align __unused;
+	size_t mapped_size_align __unused;
+
 	arm_sp_min_plat_arch_setup();
 
 	/*
@@ -50,11 +69,53 @@
 	 * to run. So there is no BL2 to load the HW_CONFIG dtb into memory
 	 * before control is passed to SP_MIN.
 	 * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
+	 * The code below relies on dynamic mapping capability, which is not
+	 * supported by xlat tables lib V1.
+	 * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+	 * gets deprecated.
 	 */
-#if !RESET_TO_SP_MIN && !BL2_AT_EL3
-	assert(hw_config_dtb != 0U);
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
+	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+	assert(hw_config_info != NULL);
+	assert(hw_config_info->config_addr != 0UL);
+
+	INFO("SP_MIN FCONF: HW_CONFIG address = %p\n",
+	     (void *)hw_config_info->config_addr);
+
+	/*
+	 * Preferrably we expect this address and size are page aligned,
+	 * but if they are not then align it.
+	 */
+	hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+	mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+	if ((hw_config_info->config_addr != hw_config_base_align) &&
+	    (hw_config_info->config_max_size == mapped_size_align)) {
+		mapped_size_align += PAGE_SIZE;
+	}
+
+	/*
+	 * map dynamically HW config region with its aligned base address and
+	 * size
+	 */
+	rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+				     hw_config_base_align,
+				     mapped_size_align,
+				     MT_RO_DATA);
+	if (rc != 0) {
+		ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+		panic();
+	}
+
+	/* Populate HW_CONFIG device tree with the mapped address */
+	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
 
-	INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
-	fconf_populate("HW_CONFIG", hw_config_dtb);
-#endif
+	/* unmap the HW_CONFIG memory region */
+	rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+	if (rc != 0) {
+		ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+		      rc);
+		panic();
+	}
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
 }
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 0d8cca5..183d802 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,7 +25,8 @@
 # Added separately from the above list for better readability
 ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),)
 BL32_SOURCES		+=	lib/fconf/fconf.c				\
-				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+				lib/fconf/fconf_dyn_cfg_getter.c		\
+				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c \
 
 BL32_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 68872c1..1ac0a9c 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -154,7 +154,8 @@
 
 	/* Set global DTB info for fixed fw_config information */
 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
-	set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+	set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size,
+			FW_CONFIG_ID);
 
 	assert(bl1_plat_get_image_desc(BL33_IMAGE_ID) != NULL);
 
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 393a648..8932aa0 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -34,6 +34,8 @@
 fdt     fdt_get_name
 fdt     fdt_get_alias
 fdt     fdt_node_offset_by_phandle
+fdt     fdt_subnode_offset
+fdt     fdt_add_subnode
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
 mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
deleted file mode 100644
index 5d478e9..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/tbbr/tbbr_img_def.h>
-
-/dts-v1/;
-
-/ {
-	dtb-registry {
-		compatible = "fconf,dyn_cfg-dtb_registry";
-
-		tb_fw-config {
-			load-address = <0x0 0x4001300>;
-			max-size = <0x200>;
-			id = <TB_FW_CONFIG_ID>;
-		};
-	};
-};
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
deleted file mode 100644
index 49eda27..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
-	tb_fw-config {
-		compatible = "arm,tb_fw";
-
-		/* Disable authentication for development */
-		disable_auth = <0x0>;
-
-		/*
-		 * The following two entries are placeholders for Mbed TLS
-		 * heap information. The default values don't matter since
-		 * they will be overwritten by BL1.
-		 * In case of having shared Mbed TLS heap between BL1 and BL2,
-		 * BL1 will populate these two properties with the respective
-		 * info about the shared heap. This info will be available for
-		 * BL2 in order to locate and re-use the heap.
-		 */
-		mbedtls_heap_addr = <0x0 0x0>;
-		mbedtls_heap_size = <0x0>;
-	};
-};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
deleted file mode 100644
index e83cd57..0000000
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <sgm_base_platform_def.h>
-
-#define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
-#define PLAT_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000)
-#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 36)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
deleted file mode 100644
index f8df1a7..0000000
--- a/plat/arm/board/sgm775/platform.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
-
-include plat/arm/css/sgm/sgm-common.mk
-
-SGM775_BASE= plat/arm/board/sgm775
-
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES		+=      ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts
-FW_CONFIG		:=      ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-TB_FW_CONFIG		:=      ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
-
-# Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
-
-PLAT_INCLUDES +=-I${SGM775_BASE}/include/
-
-BL1_SOURCES		+=	${SGM775_BASE}/sgm775_err.c
-
-BL2_SOURCES		+=	lib/utils/mem_region.c                  \
-				${SGM775_BASE}/sgm775_err.c		\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-BL31_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c		\
-				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES		+=	${SGM775_BASE}/sgm775_trusted_boot.c
-BL2_SOURCES		+=	${SGM775_BASE}/sgm775_trusted_boot.c
-endif
diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/sgm775/sgm775_err.c
deleted file mode 100644
index dc114f0..0000000
--- a/plat/arm/board/sgm775/sgm775_err.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * sgm775 error handler
- */
-void __dead2 plat_arm_error_handler(int err)
-{
-	while (true) {
-		wfi();
-	}
-}
diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/sgm775/sgm775_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk b/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
deleted file mode 100644
index 129b586..0000000
--- a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-include plat/arm/css/sgm/tsp/tsp-sgm.mk
\ No newline at end of file
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 73338cb..7a9e04d 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -166,7 +166,7 @@
 
 	/* Set global DTB info for fixed fw_config information */
 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
-	set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+	set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size, FW_CONFIG_ID);
 
 	/* Fill the device tree information struct with the info from the config dtb */
 	err = fconf_load_config(FW_CONFIG_ID);
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
deleted file mode 100644
index 32ca1bb..0000000
--- a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-#include <cortex_a75.h>
-#include <cortex_a55.h>
-#include <cpu_macros.S>
-
-	.globl	plat_arm_calc_core_pos
-	.globl	plat_reset_handler
-
-	/* ---------------------------------------------------------------------
-	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
-	 *
-	 * Function to calculate the core position on FVP.
-	 *
-	 * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
-	 * (CPUId * MAX_PE_PER_CPU) +
-	 * ThreadId
-	 *
-	 * which can be simplified as:
-	 *
-	 * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
-	 * + ThreadId
-	 * ---------------------------------------------------------------------
-	 */
-func plat_arm_calc_core_pos
-	/*
-	 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
-	 * look as if in a multi-threaded implementation.
-	 */
-	tst	x0, #MPIDR_MT_MASK
-	lsr	x3, x0, #MPIDR_AFFINITY_BITS
-	csel	x3, x3, x0, eq
-
-	/* Extract individual affinity fields from MPIDR */
-	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
-
-	/* Compute linear position */
-	mov	x4, #PLAT_MAX_CPUS_PER_CLUSTER
-	madd	x1, x2, x4, x1
-	mov	x5, #PLAT_MAX_PE_PER_CPU
-	madd	x0, x1, x5, x0
-	ret
-endfunc plat_arm_calc_core_pos
-
-	/* -----------------------------------------------------
-	 * void plat_reset_handler(void);
-	 *
-	 * Determine the CPU MIDR and disable power down bit for
-	 * that CPU.
-	 * -----------------------------------------------------
-	 */
-func plat_reset_handler
-	jump_if_cpu_midr CORTEX_A75_MIDR, A75
-	jump_if_cpu_midr CORTEX_A55_MIDR, A55
-	ret
-
-	/* -----------------------------------------------------
-	 * Disable CPU power down bit in power control register
-	 * -----------------------------------------------------
-	 */
-A75:
-	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
-	bic	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-A55:
-	mrs	x0, CORTEX_A55_CPUPWRCTLR_EL1
-	bic	x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A55_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
deleted file mode 100644
index 54b2423..0000000
--- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
-	/* Platform Config */
-	tb_fw-config {
-		compatible = "arm,tb_fw";
-		hw_config_addr = <0x0 0x83000000>;
-		hw_config_max_size = <0x01000000>;
-		/*
-		 * The following two entries are placeholders for Mbed TLS
-		 * heap information. The default values don't matter since
-		 * they will be overwritten by BL1.
-		 * In case of having shared Mbed TLS heap between BL1 and BL2,
-		 * BL1 will populate these two properties with the respective
-		 * info about the shared heap. This info will be available for
-		 * BL2 in order to locate and re-use the heap.
-		 */
-		mbedtls_heap_addr = <0x0 0x0>;
-		mbedtls_heap_size = <0x0>;
-	};
-};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
deleted file mode 100644
index 715ded2..0000000
--- a/plat/arm/css/sgm/include/plat_macros.S
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef PLAT_MACROS_S
-#define PLAT_MACROS_S
-
-#include <cci_macros.S>
-#include <css_macros.S>
-
-/* ---------------------------------------------
- * The below required platform porting macro
- * prints out relevant platform registers
- * whenever an unhandled exception is taken in
- * BL31.
- * ---------------------------------------------
- */
-.macro plat_crash_print_regs
-css_print_gic_regs
-print_cci_regs
-.endm
-
-#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
deleted file mode 100644
index 2d8e677..0000000
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_BASE_PLATFORM_DEF_H
-#define SGM_BASE_PLATFORM_DEF_H
-
-#include <drivers/arm/tzc400.h>
-#include <drivers/arm/tzc_common.h>
-#include <plat/arm/board/common/board_css_def.h>
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/common/arm_def.h>
-#include <plat/arm/css/common/css_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <plat/common/common_def.h>
-
-/* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT		U(1)
-#define PLAT_ARM_CLUSTER_CORE_COUNT	U(8)
-#define PLATFORM_CORE_COUNT		PLAT_ARM_CLUSTER_CORE_COUNT
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
-#define PLAT_NUM_PWR_DOMAINS		(ARM_SYSTEM_COUNT + \
-					PLAT_ARM_CLUSTER_COUNT + \
-					PLATFORM_CORE_COUNT)
-
-/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
- */
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
-			CSS_G1S_IRQ_PROPS(grp), \
-			ARM_G1S_IRQ_PROPS(grp)
-
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		0x30000000
-#define PLAT_ARM_GICR_BASE		0x300C0000
-#define PLAT_ARM_GICC_BASE		0x2c000000
-
-#define CSS_GIC_SIZE			0x00200000
-
-#define CSS_MAP_GIC_DEVICE		MAP_REGION_FLAT(	\
-					PLAT_ARM_GICD_BASE,	\
-					CSS_GIC_SIZE,		\
-					MT_DEVICE | MT_RW | MT_SECURE)
-
-/* Platform ID address */
-#define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
-#ifndef __ASSEMBLER__
-/* SSC_VERSION related accessors */
-/* Returns the part number of the platform */
-#define GET_PLAT_PART_NUM                                       \
-		GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
-/* Returns the configuration number of the platform */
-#define GET_PLAT_CONFIG_NUM                                     \
-		GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
-#endif /* __ASSEMBLER__ */
-
-
-/*************************************************************************
- * Definitions common to all SGM CSS based platforms
- *************************************************************************/
-
-/* TZC-400 related constants */
-#define PLAT_ARM_TZC_BASE		0x2a500000
-#define TZC_NSAID_ALL_AP		0  /* Note: Same as default NSAID!! */
-#define TZC_NSAID_HDLCD0		2
-#define TZC_NSAID_HDLCD1		3
-#define TZC_NSAID_GPU			9
-#define TZC_NSAID_VIDEO			10
-#define TZC_NSAID_DISP0			11
-#define TZC_NSAID_DISP1			12
-
-
-/*************************************************************************
- * Required platform porting definitions common to all SGM CSS based
- * platforms
- *************************************************************************/
-
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00040000	/* 256 KB */
-
-/* MHU related constants */
-#define PLAT_CSS_MHU_BASE		0x2b1f0000
-
-#define PLAT_ARM_TRUSTED_ROM_BASE	0x00000000
-#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000
-
-#define PLAT_ARM_CCI_BASE		0x2a000000
-
-/* Cluster to CCI slave mapping */
-#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	6
-#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	5
-
-/* System timer related constants */
-#define PLAT_ARM_NSTIMER_FRAME_ID	0
-
-/* TZC related constants */
-#define PLAT_ARM_TZC_NS_DEV_ACCESS	(				\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0)	|	\
-		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
-
-/* Display Processor register definitions to setup the NSAIDs */
-#define MALI_DP_BASE           0x2cc00000
-#define DP_NPROT_NSAID_OFFSET     0x1000c
-#define W_NPROT_NSAID_SHIFT            24
-#define LS_NPORT_NSAID_SHIFT           12
-
-/*
- * Base address of the first memory region used for communication between AP
- * and SCP. Used by the BootOverMHU and SCPI protocols.
- */
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
- * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
- * means the SCP/AP configuration data gets overwritten when the AP initiates
- * communication with the SCP. The configuration data is expected to be a
- * 32-bit word on all CSS platforms. Part of this configuration is
- * which CPU is the primary, according to the shift and mask definitions below.
- */
-#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	(ARM_TRUSTED_SRAM_BASE + 0x80)
-#define PLAT_CSS_PRIMARY_CPU_SHIFT		8
-#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH		4
-#endif
-
-/*
- * SCP_BL2 uses up whatever remaining space is available as it is loaded before
- * anything else in this memory region and is handed over to the SCP before
- * BL31 is loaded over the top.
- */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE \
-	((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
-
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	PLAT_CSS_MAX_SCP_BL2_SIZE
-
-/*
- * Most platform porting definitions provided by included headers
- */
-
-/*
- * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
- * plat_arm_mmap array defined for each BL stage.
- */
-#if defined(IMAGE_BL31)
-# define PLAT_ARM_MMAP_ENTRIES		8
-# define MAX_XLAT_TABLES		5
-#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES		8
-# define MAX_XLAT_TABLES		5
-#elif !USE_ROMLIB
-# define PLAT_ARM_MMAP_ENTRIES		11
-# define MAX_XLAT_TABLES		5
-#else
-# define PLAT_ARM_MMAP_ENTRIES		12
-# define MAX_XLAT_TABLES		6
-#endif
-
-/*
- * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
- * plus a little space for growth.
- */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	0xB000
-
-/*
- * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
- */
-
-#if USE_ROMLIB
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0x1000
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0xe000
-#else
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0
-#endif
-
-/*
- * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth.
- */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
-#else
-# define PLAT_ARM_MAX_BL2_SIZE		0x12000
-#endif
-
-/*
- * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
- */
-#define PLAT_ARM_MAX_BL31_SIZE		0x3B000
-
-/*
- * Size of cacheable stacks
- */
-#if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x440
-# endif
-#elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE 0x440
-#endif
-
-/*******************************************************************************
- * Memprotect definitions
- ******************************************************************************/
-/* PSCI memory protect definitions:
- * This variable is stored in a non-secure flash because some ARM reference
- * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
- * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
- */
-#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
-					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-
-/* Number of SCMI channels on the platform */
-#define PLAT_ARM_SCMI_CHANNEL_COUNT	U(1)
-
-#endif /* SGM_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
deleted file mode 100644
index 29b98d4..0000000
--- a/plat/arm/css/sgm/include/sgm_plat_config.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_PLAT_CONFIG_H
-#define SGM_PLAT_CONFIG_H
-
-#include <drivers/arm/ccn.h>
-#include <drivers/arm/gicv3.h>
-
-/* The type of interconnect */
-typedef enum {
-	ARM_CCI = 0,
-	ARM_CCN,
-	ARM_CMN
-} css_inteconn_type_t;
-
-typedef ccn_desc_t inteconn_desc_t;
-
-/* Interconnect configurations */
-typedef struct css_inteconn_config {
-	css_inteconn_type_t ip_type;
-	const inteconn_desc_t *plat_inteconn_desc;
-} css_inteconn_config_t;
-
-/* Topology configurations */
-typedef struct css_topology {
-	const unsigned char *power_tree;
-	unsigned int plat_cluster_core_count;
-} css_topology_t;
-
-typedef struct css_plat_config {
-	const gicv3_driver_data_t *gic_data;
-	const css_inteconn_config_t *inteconn;
-	const css_topology_t *topology;
-} css_plat_config_t;
-
-void plat_config_init(void);
-css_plat_config_t *get_plat_config(void);
-
-#endif /* SGM_PLAT_CONFIG_H */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
deleted file mode 100644
index 859ddb5..0000000
--- a/plat/arm/css/sgm/include/sgm_variant.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_VARIANT_H
-#define SGM_VARIANT_H
-
-/* SSC_VERSION values for sgm */
-#define SGM775_SSC_VER_PART_NUM		0x0790
-
-/* DMC configuration for sgm */
-#define SGM_DMC_SIZE			0x40000
-#define SGM775_DMC_COUNT		4
-
-#endif /* SGM_VARIANT_H */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
deleted file mode 100644
index 5b954f8..0000000
--- a/plat/arm/css/sgm/sgm-common.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-CSS_USE_SCMI_SDS_DRIVER	:=	1
-
-CSS_SGM_BASE		:=	plat/arm/css/sgm
-
-PLAT_INCLUDES		:=	-I${CSS_SGM_BASE}/include
-
-PLAT_BL_COMMON_SOURCES	:=	${CSS_SGM_BASE}/sgm_mmap_config.c	\
-				${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
-
-SECURITY_SOURCES	:=	drivers/arm/tzc/tzc_dmc500.c		\
-				plat/arm/common/arm_tzc_dmc500.c	\
-				${CSS_SGM_BASE}/sgm_security.c
-
-SGM_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a55.S		\
-				lib/cpus/aarch64/cortex_a75.S
-
-INTERCONNECT_SOURCES	:=	${CSS_SGM_BASE}/sgm_interconnect.c
-
-# GIC-600 configuration
-GICV3_SUPPORT_GIC600	:=	1
-
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-SGM_GIC_SOURCES		:=	${GICV3_SOURCES}			\
-				plat/common/plat_gicv3.c		\
-				plat/arm/common/arm_gicv3.c
-
-BL1_SOURCES		+=	$(SGM_CPU_SOURCES)			\
-				${INTERCONNECT_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_bl1_setup.c		\
-				${CSS_SGM_BASE}/sgm_plat_config.c	\
-				drivers/arm/sp805/sp805.c
-
-BL2_SOURCES		+=	${SECURITY_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_plat_config.c
-
-BL2U_SOURCES		+=	${SECURITY_SOURCES}
-
-BL31_SOURCES		+=	$(SGM_CPU_SOURCES)			\
-				${INTERCONNECT_SOURCES}			\
-				${SECURITY_SOURCES}			\
-				${SGM_GIC_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_topology.c		\
-				${CSS_SGM_BASE}/sgm_bl31_setup.c	\
-				${CSS_SGM_BASE}/sgm_plat_config.c
-
-ifneq (${RESET_TO_BL31},0)
-  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
-  Please set RESET_TO_BL31 to 0.")
-endif
-
-# sgm uses CCI-500 as Cache Coherent Interconnect
-ARM_CCI_PRODUCT_ID	:=	500
-
-# System coherency is managed in hardware
-HW_ASSISTED_COHERENCY	:=	1
-
-# When building for systems with hardware-assisted coherency, there's no need to
-# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
-USE_COHERENT_MEM	:=	0
-
-override ARM_PLAT_MT	:=	1
-
-$(eval $(call add_define,SGM_PLAT))
-
-include plat/arm/common/arm_common.mk
-include plat/arm/board/common/board_common.mk
-include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
deleted file mode 100644
index 5fd9655..0000000
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-#include <plat/arm/common/arm_def.h>
-#include <drivers/arm/sp805.h>
-#include <sgm_plat_config.h>
-
-void bl1_early_platform_setup(void)
-{
-
-	/* Initialize the console before anything else */
-	arm_bl1_early_platform_setup();
-
-	/* Initialize the platform configuration structure */
-	plat_config_init();
-
-#if !HW_ASSISTED_COHERENCY
-	/*
-	 * Initialize Interconnect for this cluster during cold boot.
-	 * No need for locks as no other CPU is active.
-	 */
-	plat_arm_interconnect_init();
-	/*
-	 * Enable Interconnect coherency for the primary CPU's cluster.
-	 */
-	plat_arm_interconnect_enter_coherency();
-#endif
-}
-
-void plat_arm_secure_wdt_start(void)
-{
-	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
-}
-
-void plat_arm_secure_wdt_stop(void)
-{
-	sp805_stop(ARM_SP805_TWDG_BASE);
-}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
deleted file mode 100644
index 907e9fd..0000000
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/css/css_mhu_doorbell.h>
-#include <drivers/arm/css/scmi.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhu_ring_doorbell,
-};
-
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
-{
-	return &sgm775_scmi_plat_info;
-}
-
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
-				u_register_t arg2, u_register_t arg3)
-{
-	uint32_t plat_version;
-	bl_params_node_t *bl_params;
-
-	bl_params = ((bl_params_t *)arg0)->head;
-
-	/* Initialize the platform configuration structure */
-	plat_config_init();
-
-	while (bl_params) {
-		if (bl_params->image_id == BL33_IMAGE_ID) {
-			plat_version = mmio_read_32(SSC_VERSION);
-			bl_params->ep_info->args.arg2 = plat_version;
-			break;
-		}
-
-		bl_params = bl_params->next_params_info;
-	}
-
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-}
-
-const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
-{
-	return css_scmi_override_pm_ops(ops);
-}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
deleted file mode 100644
index 5b45341..0000000
--- a/plat/arm/css/sgm/sgm_interconnect.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <cdefs.h>
-
-/*
- * As the SGM platform supports FCM (with automatic interconnect
- * enter/exit), we should not do anything in these interface functions.
- * They are used to override the weak functions in cci drivers.
- */
-
-/******************************************************************************
- * Helper function to initialize ARM interconnect driver.
- *****************************************************************************/
-void __init plat_arm_interconnect_init(void)
-{
-}
-
-/******************************************************************************
- * Helper function to place current master into coherency
- *****************************************************************************/
-void plat_arm_interconnect_enter_coherency(void)
-{
-}
-
-/******************************************************************************
- * Helper function to remove current master from coherency
- *****************************************************************************/
-void plat_arm_interconnect_exit_coherency(void)
-{
-}
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
deleted file mode 100644
index e5b4b03..0000000
--- a/plat/arm/css/sgm/sgm_mmap_config.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_variant.h>
-
-/*
- * Table of regions for different BL stages to map using the MMU.
- * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
- * arm_configure_mmu_elx() will give the available subset of that.
- */
-#if IMAGE_BL1
-const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	V2M_MAP_FLASH0_RO,
-	V2M_MAP_IOFPGA,
-	CSS_MAP_DEVICE,
-	CSS_MAP_GIC_DEVICE,
-	SOC_CSS_MAP_DEVICE,
-#if TRUSTED_BOARD_BOOT
-	ARM_MAP_NS_DRAM1,
-#endif
-	{0}
-};
-#endif
-#if IMAGE_BL2
-const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	V2M_MAP_FLASH0_RO,
-	V2M_MAP_IOFPGA,
-	CSS_MAP_DEVICE,
-	CSS_MAP_GIC_DEVICE,
-	SOC_CSS_MAP_DEVICE,
-	ARM_MAP_NS_DRAM1,
-#ifdef SPD_tspd
-	ARM_MAP_TSP_SEC_MEM,
-#endif
-#ifdef SPD_opteed
-	ARM_OPTEE_PAGEABLE_LOAD_MEM,
-#endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
-	ARM_MAP_BL1_RW,
-#endif
-	{0}
-};
-#endif
-#if IMAGE_BL2U
-const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	CSS_MAP_DEVICE,
-	CSS_MAP_GIC_DEVICE,
-	SOC_CSS_MAP_DEVICE,
-	{0}
-};
-#endif
-#if IMAGE_BL31
-const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	V2M_MAP_IOFPGA,
-	CSS_MAP_DEVICE,
-	CSS_MAP_GIC_DEVICE,
-	SOC_CSS_MAP_DEVICE,
-	{0}
-};
-#endif
-#if IMAGE_BL32
-const mmap_region_t plat_arm_mmap[] = {
-	V2M_MAP_IOFPGA,
-	CSS_MAP_DEVICE,
-	CSS_MAP_GIC_DEVICE,
-	SOC_CSS_MAP_DEVICE,
-	{0}
-};
-#endif
-
-ARM_CASSERT_MMAP
-
-const mmap_region_t *plat_arm_get_mmap(void)
-{
-	return plat_arm_mmap;
-}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
deleted file mode 100644
index eed3631..0000000
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-#include <sgm_variant.h>
-
-static css_plat_config_t *css_plat_info;
-
-/* Interconnect */
-const css_inteconn_config_t sgm_inteconn = {
-	.ip_type = ARM_CCI,
-	.plat_inteconn_desc = NULL
-};
-
-/* Special definition for SGM775 */
-/* Topology configuration for SGM775 */
-const unsigned char sgm775_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	ARM_SYSTEM_COUNT,
-	/* No of children for the root node */
-	PLAT_ARM_CLUSTER_COUNT,
-	/* No of children for the first cluster node */
-	PLAT_ARM_CLUSTER_CORE_COUNT,
-};
-
-const css_topology_t sgm775_topology = {
-	.power_tree = sgm775_power_domain_tree_desc,
-	.plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
-};
-
-/* Configuration structure for SGM775 */
-css_plat_config_t sgm775_config = {
-	.inteconn = &sgm_inteconn,
-	.topology = &sgm775_topology
-};
-
-/*******************************************************************************
- * This function initializes the platform structure.
- ******************************************************************************/
-void plat_config_init(void)
-{
-	/* Get the platform configurations */
-	switch (GET_PLAT_PART_NUM) {
-	case SGM775_SSC_VER_PART_NUM:
-		css_plat_info = &sgm775_config;
-
-		break;
-	default:
-		ERROR("Not a valid sgm variant!\n");
-		panic();
-	}
-}
-
-/*******************************************************************************
- * This function returns the platform structure pointer.
- ******************************************************************************/
-css_plat_config_t *get_plat_config(void)
-{
-	assert(css_plat_info != NULL);
-	return css_plat_info;
-}
-
-#if TRUSTED_BOARD_BOOT
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
-	return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
-#endif
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
deleted file mode 100644
index 21d5306..0000000
--- a/plat/arm/css/sgm/sgm_security.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <drivers/arm/tzc_dmc500.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-
-#include <sgm_variant.h>
-
-/* Is populated with the DMC-500 controllers base addresses */
-static tzc_dmc500_driver_data_t plat_driver_data;
-
-void plat_sgm_dp_security_setup(void)
-{
-	unsigned int nprot_nsaid;
-
-	/*
-	 * At reset the Mali display processors start with NSAIDs set to zero
-	 * so the firmware must set them up to the expected values for ARM sgm
-	 * platforms.
-	 */
-
-	nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
-	nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
-			(0xF << LS_NPORT_NSAID_SHIFT));
-	nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
-			(TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
-	mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
-}
-
-void plat_arm_security_setup(void)
-{
-	unsigned int i;
-	unsigned int part_num = GET_PLAT_PART_NUM;
-
-	INFO("part_num: 0x%x\n", part_num);
-
-	/*
-	 * Initialise plat_driver_data with platform specific DMC_BASE
-	 * addresses
-	 */
-	switch (part_num) {
-	case SGM775_SSC_VER_PART_NUM:
-		for (i = 0; i < SGM775_DMC_COUNT; i++)
-			plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
-					+ SGM_DMC_SIZE * i;
-		plat_driver_data.dmc_count = SGM775_DMC_COUNT;
-		break;
-	default:
-		/* Unexpected platform */
-		ERROR("Unexpected platform\n");
-		panic();
-	}
-	/* Initialize the TrustZone Controller in DMC-500 */
-	arm_tzc_dmc500_setup(&plat_driver_data, NULL);
-
-	/* Do DP NSAID setup */
-	plat_sgm_dp_security_setup();
-	/* Do ARM CSS SoC security setup */
-	soc_css_security_setup();
-}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
deleted file mode 100644
index 2d9552d..0000000
--- a/plat/arm/css/sgm/sgm_topology.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-/*******************************************************************************
- * This function returns the topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return get_plat_config()->topology->power_tree;
-}
-
-/*******************************************************************************
- * This function returns the core count within the cluster corresponding to
- * `mpidr`.
- ******************************************************************************/
-unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
-{
-	return get_plat_config()->topology->plat_cluster_core_count;
-}
-
-/*
- * The array mapping platform core position (implemented by plat_my_core_pos())
- * to the SCMI power domain ID implemented by SCP.
- */
-const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
-			0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
deleted file mode 100644
index 5f40c4c..0000000
--- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-void tsp_early_platform_setup(void)
-{
-	/* Initialize the platform configuration structure */
-	plat_config_init();
-
-	arm_tsp_early_platform_setup();
-}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
deleted file mode 100644
index de5e5b7..0000000
--- a/plat/arm/css/sgm/tsp/tsp-sgm.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-BL32_SOURCES		+= 	${SGM_GIC_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_plat_config.c	\
-				plat/arm/css/sgm/tsp/sgm_tsp_setup.c
-
-include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 38a5786..e807660 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,6 @@
 #if RAS_EXTENSION
 #include <lib/extensions/ras.h>
 #endif
-#include <lib/extensions/twed.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
@@ -23,7 +22,6 @@
  * platforms but may also be overridden by a platform if required.
  */
 #pragma weak bl31_plat_runtime_setup
-#pragma weak plat_arm_set_twedel_scr_el3
 
 #if SDEI_SUPPORT
 #pragma weak plat_sdei_handle_masked_trigger
@@ -105,16 +103,3 @@
 #endif
 	panic();
 }
-
-/*******************************************************************************
- * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
- * is a weak function definition so can be overridden depending on the
- * requirements of a platform.  The only hook provided is for the TWED fields
- * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
- * configured as needed in lower exception levels.
- ******************************************************************************/
-
-uint32_t plat_arm_set_twedel_scr_el3(void)
-{
-	return TWED_DISABLED;
-}
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 6e67502..03adcf3 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -71,8 +71,8 @@
 
 	watchdog_init(get_wdt_clk());
 
-	console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
-		&console);
+	console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+		PLAT_BAUDRATE, &console);
 
 	socfpga_delay_timer_init();
 	init_ncore_ccu();
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 168236b..b1b9514 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
 
+#include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 
@@ -41,8 +42,8 @@
 
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
 
-	console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
-		&console);
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+		PLAT_BAUDRATE, &console);
 	/*
 	 * Check params passed from BL31 should not be NULL,
 	 */
@@ -114,6 +115,8 @@
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+	ncore_enable_ocram_firewall();
 }
 
 const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/agilex/include/agilex_noc.h b/plat/intel/soc/agilex/include/agilex_noc.h
index 22db3e2..9aba3c3 100644
--- a/plat/intel/soc/agilex/include/agilex_noc.h
+++ b/plat/intel/soc/agilex/include/agilex_noc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9c87e45..6a5cf9b 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -19,6 +19,8 @@
 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE		0x2000000
 
 /* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
+
 #define SOCFPGA_MMC_REG_BASE			0xff808000
 
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 10a3eec..89df46a 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -26,6 +26,7 @@
 			lib/xlat_tables/xlat_tables_common.c 		\
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S	\
+			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
 BL2_SOURCES     +=	\
@@ -48,13 +49,12 @@
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_storage.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
+		plat/intel/soc/common/soc/socfpga_firewall.c	\
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
-		plat/intel/soc/common/soc/socfpga_system_manager.c	\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
-		plat/intel/soc/common/drivers/wdt/watchdog.c		\
-		plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+		plat/intel/soc/common/drivers/wdt/watchdog.c
 
 BL31_SOURCES	+=	\
 		drivers/arm/cci/cci.c					\
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 5cb9b69..213fd3c 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -102,7 +102,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	mov_imm	x0, PLAT_UART0_BASE
+	mov_imm	x0, CRASH_CONSOLE_BASE
 	mov_imm	x1, PLAT_UART_CLOCK
 	mov_imm	x2, PLAT_BAUDRATE
 	b	console_16550_core_init
@@ -116,7 +116,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov_imm x1, PLAT_UART0_BASE
+	mov_imm x1, CRASH_CONSOLE_BASE
 	b	console_16550_core_putc
 endfunc plat_crash_console_putc
 
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index d4716cf..d9a238e 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -118,6 +118,7 @@
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
+
 uint32_t init_ncore_ccu(void)
 {
 	uint32_t status;
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 7859493..d37904b 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -168,6 +168,7 @@
 #define PLAT_UART1_BASE		(0xFFC02100)
 
 #define CRASH_CONSOLE_BASE	PLAT_UART0_BASE
+#define PLAT_INTEL_UART_BASE	PLAT_UART0_BASE
 
 #ifndef SIMICS_BUILD
 #define PLAT_BAUDRATE		(115200)
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index ff10d36..d3b7141 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -11,9 +11,11 @@
 
 #define FCS_RANDOM_WORD_SIZE		8U
 #define FCS_PROV_DATA_WORD_SIZE		44U
+#define FCS_SHA384_WORD_SIZE		12U
 
 #define FCS_RANDOM_BYTE_SIZE		(FCS_RANDOM_WORD_SIZE * 4U)
 #define FCS_PROV_DATA_BYTE_SIZE		(FCS_PROV_DATA_WORD_SIZE * 4U)
+#define FCS_SHA384_BYTE_SIZE		(FCS_SHA384_WORD_SIZE * 4U)
 
 #define FCS_CRYPTION_DATA_0		0x10100
 
@@ -38,4 +40,7 @@
 			uint32_t src_size, uint32_t dst_addr,
 			uint32_t dst_size, uint32_t *send_id);
 
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+				uint32_t *mbox_error);
+
 #endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 6b7e0fc..b260a62 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -42,6 +42,7 @@
 #define MBOX_CMD_CANCEL			0x03
 #define MBOX_CMD_VAB_SRC_CERT		0x0B
 #define MBOX_CMD_GET_IDCODE		0x10
+#define MBOX_CMD_GET_USERCODE		0x13
 #define MBOX_CMD_REBOOT_HPS		0x47
 
 /* Reconfiguration Commands */
@@ -50,6 +51,11 @@
 #define MBOX_RECONFIG_DATA		0x08
 #define MBOX_RECONFIG_STATUS		0x09
 
+/* HWMON Commands */
+#define MBOX_HWMON_READVOLT		0x18
+#define MBOX_HWMON_READTEMP		0x19
+
+
 /* QSPI Commands */
 #define MBOX_CMD_QSPI_OPEN		0x32
 #define MBOX_CMD_QSPI_CLOSE		0x33
@@ -67,6 +73,8 @@
 #define MBOX_FCS_ENCRYPT_REQ			0x7E
 #define MBOX_FCS_DECRYPT_REQ			0x7F
 #define MBOX_FCS_RANDOM_GEN			0x80
+/* Miscellaneous commands */
+#define MBOX_GET_ROM_PATCH_SHA384	0x1B0
 
 /* Mailbox Definitions */
 
@@ -143,6 +151,10 @@
 #define RSU_VERSION_ACMF		BIT(8)
 #define RSU_VERSION_ACMF_MASK		0xff00
 
+/* Config Status Macros */
+#define CONFIG_STATUS_WORD_SIZE		16U
+#define CONFIG_STATUS_FW_VER_OFFSET	1
+#define CONFIG_STATUS_FW_VER_MASK	0x00FFFFFF
 
 /* Mailbox Function Definitions */
 
@@ -171,5 +183,7 @@
 int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_update(uint32_t *flash_offset);
 int mailbox_hps_stage_notify(uint32_t execution_stage);
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
 
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
new file mode 100644
index 0000000..e3c0f73
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_NOC_H
+#define SOCFPGA_NOC_H
+
+/* Macros */
+#define SCR_AXI_AP_MASK					BIT(24)
+#define SCR_FPGA2SOC_MASK				BIT(16)
+#define SCR_MPU_MASK					BIT(0)
+#define DISABLE_L4_FIREWALL		(SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
+						| SCR_MPU_MASK)
+#define DISABLE_BRIDGE_FIREWALL				0x0ffe0101
+
+#define SOCFPGA_CCU_NOC(_ctrl, _dev)	(SOCFPGA_CCU_NOC_REG_BASE \
+					+ (SOCFPGA_CCU_NOC_##_ctrl##_##_dev))
+
+#define SOCFPGA_L4_PER_SCR(_reg)	(SOCFPGA_L4_PER_SCR_REG_BASE \
+					+ (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
+
+#define SOCFPGA_L4_SYS_SCR(_reg)	(SOCFPGA_L4_SYS_SCR_REG_BASE \
+					+ (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
+
+/* L3 Interconnect Register Map */
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER			0x0000
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA			0x0004
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER			0x000c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER			0x0010
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0			0x001c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1			0x0020
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0			0x0024
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1			0x0028
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0				0x002c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1				0x0030
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2				0x0034
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC				0x0040
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0				0x0044
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1				0x0048
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0				0x0050
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1				0x0054
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2				0x0058
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3				0x005c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4				0x0060
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0			0x0064
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1			0x0068
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0				0x006c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1				0x0070
+
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC			0x0008
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC			0x000c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC			0x0010
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC			0x0014
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC			0x0018
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC			0x001c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC			0x0020
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC			0x002c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC			0x0030
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC		0x0034
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC			0x0038
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC			0x0040
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC			0x0044
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC			0x0048
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR			0x004c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR			0x0054
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR			0x0058
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR			0x005c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER			0x0060
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER			0x0064
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0			0x0068
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1			0x006c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2			0x0070
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3			0x0074
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP				0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES			0x0090
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS			0x0094
+
+/* CCU NOC Register Map */
+
+#define SOCFPGA_CCU_NOC_CPU0_RAM0				0x04688
+#define SOCFPGA_CCU_NOC_IOM_RAM0				0x18628
+
+#define SOCFPGA_CCU_NOC_ADMASK_P_MASK				BIT(0)
+#define SOCFPGA_CCU_NOC_ADMASK_NS_MASK				BIT(1)
+
+/* Function Definitions */
+
+void enable_ns_peripheral_access(void);
+void enable_ns_bridge_access(void);
+void enable_ns_ocram_access(void);
+void enable_ocram_firewall(void);
+
+#endif
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0db71e2..43f3dc4 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -27,6 +27,12 @@
 #define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE		0xC2000004
 #define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM		0xC2000005
 
+/* FPGA Bitstream Flag */
+#define FLAG_PARTIAL_CONFIG				BIT(0)
+#define FLAG_AUTHENTICATION				BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type)			(((flag) & FLAG_##_type) \
+							== FLAG_##_type)
+
 /* Secure Register Access */
 #define INTEL_SIP_SMC_REG_READ				0xC2000007
 #define INTEL_SIP_SMC_REG_WRITE				0xC2000008
@@ -39,31 +45,50 @@
 #define INTEL_SIP_SMC_RSU_RETRY_COUNTER			0xC200000F
 #define INTEL_SIP_SMC_RSU_DCMF_VERSION			0xC2000010
 #define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION		0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY			0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY		0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS			0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS		0xC2000015
 
+/* Hardware monitor */
+#define INTEL_SIP_SMC_HWMON_READTEMP			0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT			0xC2000021
+#define TEMP_CHANNEL_MAX				(1 << 15)
+#define VOLT_CHANNEL_MAX				(1 << 15)
 
 /* ECC */
 #define INTEL_SIP_SMC_ECC_DBE				0xC200000D
 
+/* Generic Command */
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384		0xC2000040
+
 /* Send Mailbox Command */
 #define INTEL_SIP_SMC_MBOX_SEND_CMD			0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION			0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES			0xC2000032
 
+/* Mailbox Command */
+#define INTEL_SIP_SMC_GET_USERCODE			0xC200003D
 
 /* SiP Definitions */
 
 /* ECC DBE */
 #define WARM_RESET_WFI_FLAG				BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK		(SYSMGR_ECC_OCRAM_MASK |\
+#define SYSMGR_ECC_DBE_COLD_RST_MASK			(SYSMGR_ECC_OCRAM_MASK |\
 							SYSMGR_ECC_DDR0_MASK |\
 							SYSMGR_ECC_DDR1_MASK)
 
+/* Non-mailbox SMC Call */
+#define INTEL_SIP_SMC_SVC_VERSION			0xC2000200
+
 /* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT	0x8200ff00
-#define SIP_SVC_UID		0x8200ff01
-#define SIP_SVC_VERSION		0x8200ff03
+#define SIP_SVC_CALL_COUNT				0x8200ff00
+#define SIP_SVC_UID					0x8200ff01
+#define SIP_SVC_VERSION					0x8200ff03
 
 /* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR	0
-#define SIP_SVC_VERSION_MINOR	1
+#define SIP_SVC_VERSION_MAJOR				1
+#define SIP_SVC_VERSION_MINOR				0
 
 
 /* Structure Definitions */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 2b13f1f..a77734d 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -42,13 +42,6 @@
 #define IDLE_DATA_SOC2FPGA				BIT(4)
 #define IDLE_DATA_MASK		(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
 
-#define SCR_AXI_AP_MASK					BIT(24)
-#define SCR_FPGA2SOC_MASK				BIT(16)
-#define SCR_MPU_MASK					BIT(0)
-#define DISABLE_L4_FIREWALL	(SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
-					| SCR_MPU_MASK)
-#define DISABLE_BRIDGE_FIREWALL				0x0ffe0101
-
 #define SYSMGR_ECC_OCRAM_MASK				BIT(1)
 #define SYSMGR_ECC_DDR0_MASK				BIT(16)
 #define SYSMGR_ECC_DDR1_MASK				BIT(17)
@@ -58,69 +51,4 @@
 #define SOCFPGA_SYSMGR(_reg)		(SOCFPGA_SYSMGR_REG_BASE \
 						+ (SOCFPGA_SYSMGR_##_reg))
 
-#define SOCFPGA_L4_PER_SCR(_reg)	(SOCFPGA_L4_PER_SCR_REG_BASE \
-					+ (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
-
-#define SOCFPGA_L4_SYS_SCR(_reg)	(SOCFPGA_L4_SYS_SCR_REG_BASE \
-					+ (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
-
-/* L3 Interconnect Register Map */
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER			0x0000
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA			0x0004
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER			0x000c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER			0x0010
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0			0x001c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1			0x0020
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0			0x0024
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1			0x0028
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0				0x002c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1				0x0030
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2				0x0034
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC				0x0040
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0				0x0044
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1				0x0048
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0				0x0050
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1				0x0054
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2				0x0058
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3				0x005c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4				0x0060
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0			0x0064
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1			0x0068
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0				0x006c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1				0x0070
-
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC			0x0008
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC			0x000c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC			0x0010
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC			0x0014
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC			0x0018
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC			0x001c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC			0x0020
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC			0x002c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC			0x0030
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC		0x0034
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC			0x0038
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC			0x0040
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC			0x0044
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC			0x0048
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR			0x004c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR			0x0054
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR			0x0058
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR			0x005c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER			0x0060
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER			0x0064
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0			0x0068
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1			0x006c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2			0x0070
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3			0x0074
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP				0x0078
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES			0x0090
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS			0x0094
-
-#define SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0			0xf7004688
-#define SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0				0xf7018628
-
-void enable_ns_peripheral_access(void);
-void enable_ns_bridge_access(void);
-
 #endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index fe5461b..85551a4 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -11,6 +11,15 @@
 #include "socfpga_mailbox.h"
 #include "socfpga_sip_svc.h"
 
+static bool is_size_4_bytes_aligned(uint32_t size)
+{
+	if ((size % MBOX_WORD_BYTE) != 0U) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
 					uint32_t *mbox_error)
 {
@@ -57,6 +66,10 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	if (!is_size_4_bytes_aligned(size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
 				CMD_DIRECT);
@@ -89,11 +102,6 @@
 	int status;
 	uint32_t cmd;
 
-	if (!is_address_in_ddr_range(src_addr, src_size) ||
-		!is_address_in_ddr_range(dst_addr, dst_size)) {
-		return INTEL_SIP_SMC_STATUS_REJECTED;
-	}
-
 	fcs_crypt_payload payload = {
 		FCS_CRYPTION_DATA_0,
 		src_addr,
@@ -101,6 +109,15 @@
 		dst_addr,
 		dst_size };
 
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_size_4_bytes_aligned(sizeof(fcs_crypt_payload))) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (mode != 0U) {
 		cmd = MBOX_FCS_ENCRYPT_REQ;
 	} else {
@@ -118,3 +135,33 @@
 
 	return INTEL_SIP_SMC_STATUS_OK;
 }
+
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+					uint32_t *mbox_error)
+{
+	int status;
+	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
+
+	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
+			CMD_CASUAL, (uint32_t *) addr, &resp_len);
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (resp_len != FCS_SHA384_WORD_SIZE) {
+		*mbox_error = GENERIC_RESPONSE_ERROR;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*ret_size = FCS_SHA384_BYTE_SIZE;
+
+	flush_dcache_range(addr, *ret_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_firewall.c
similarity index 84%
rename from plat/intel/soc/common/soc/socfpga_system_manager.c
rename to plat/intel/soc/common/soc/socfpga_firewall.c
index a64053c..515784b 100644
--- a/plat/intel/soc/common/soc/socfpga_system_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
 
+#include "socfpga_noc.h"
+#include "socfpga_plat_def.h"
 #include "socfpga_system_manager.h"
 
 void enable_nonsecure_access(void)
@@ -92,12 +94,18 @@
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
-	mmio_clrbits_32(SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0, 0x03);
-	mmio_clrbits_32(SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0, 0x03);
-
+	enable_ns_ocram_access();
 	mmio_write_32(SOCFPGA_SYSMGR(SDMMC), SYSMGR_SDMMC_DRVSEL(3));
 #endif
 
+}
+
+void enable_ns_ocram_access(void)
+{
+	mmio_clrbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+		SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+	mmio_clrbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+		SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
 }
 
 void enable_ns_bridge_access(void)
@@ -105,3 +113,11 @@
 	mmio_write_32(SOCFPGA_SOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
 	mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
 }
+
+void enable_ocram_firewall(void)
+{
+	mmio_setbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+		SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+	mmio_setbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+		SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index be900c9..8ecd6db 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -507,11 +507,13 @@
 		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
 	}
 
-	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U)
+	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
 		return MBOX_CFGSTAT_STATE_CONFIG;
+	}
 
-	if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U)
+	if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
 		return MBOX_CFGSTAT_STATE_CONFIG;
+	}
 
 	return MBOX_RET_OK;
 }
@@ -527,3 +529,22 @@
 
 	return ret;
 }
+
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
+{
+	unsigned int resp_len = sizeof(resp_buf);
+
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
+				CMD_CASUAL, resp_buf,
+				&resp_len);
+
+}
+
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
+{
+	unsigned int resp_len = sizeof(resp_buf);
+
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
+				CMD_CASUAL, resp_buf,
+				&resp_len);
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 14cd9e0..f22c2ee 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -20,10 +20,17 @@
 #define FPGA_CONFIG_BUFFER_SIZE 4
 
 static int current_block, current_buffer;
-static int read_block, max_blocks, is_partial_reconfig;
+static int read_block, max_blocks;
 static uint32_t send_id, rcv_id;
 static uint32_t bytes_per_block, blocks_submitted;
+static bool bridge_disable;
 
+/* RSU static variables */
+static uint32_t rsu_dcmf_ver[4] = {0};
+
+/* RSU Max Retry */
+static uint32_t rsu_max_retry;
+static uint16_t rsu_dcmf_stat[4] = {0};
 
 /*  SiP Service UUID */
 DEFINE_SVC_UUID2(intl_svc_uid,
@@ -83,22 +90,23 @@
 {
 	uint32_t ret;
 
-	if (query_type == 1)
+	if (query_type == 1U) {
 		ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS, false);
-	else
+	} else {
 		ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+	}
 
-	if (ret) {
-		if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+	if (ret != 0U) {
+		if (ret == MBOX_CFGSTAT_STATE_CONFIG) {
 			return INTEL_SIP_SMC_STATUS_BUSY;
-		else
+		} else {
 			return INTEL_SIP_SMC_STATUS_ERROR;
+		}
 	}
 
-	if (query_type != 1) {
-		/* full reconfiguration */
-		if (!is_partial_reconfig)
-			socfpga_bridges_enable();	/* Enable bridge */
+	if (bridge_disable) {
+		socfpga_bridges_enable();	/* Enable bridge */
+		bridge_disable = false;
 	}
 
 	return INTEL_SIP_SMC_STATUS_OK;
@@ -184,7 +192,7 @@
 	return status;
 }
 
-static int intel_fpga_config_start(uint32_t config_type)
+static int intel_fpga_config_start(uint32_t flag)
 {
 	uint32_t argument = 0x1;
 	uint32_t response[3];
@@ -192,7 +200,14 @@
 	unsigned int size = 0;
 	unsigned int resp_len = ARRAY_SIZE(response);
 
+	if (!CONFIG_TEST_FLAG(flag, PARTIAL_CONFIG)) {
+		bridge_disable = true;
+	}
+
-	is_partial_reconfig = config_type;
+	if (CONFIG_TEST_FLAG(flag, AUTHENTICATION)) {
+		size = 1;
+		bridge_disable = false;
+	}
 
 	mailbox_clear_response();
 
@@ -202,8 +217,10 @@
 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RECONFIG, &argument, size,
 			CMD_CASUAL, response, &resp_len);
 
-	if (status < 0)
-		return status;
+	if (status < 0) {
+		bridge_disable = false;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
 
 	max_blocks = response[0];
 	bytes_per_block = response[1];
@@ -222,13 +239,12 @@
 	read_block = 0;
 	current_buffer = 0;
 
-	/* full reconfiguration */
-	if (!is_partial_reconfig) {
-		/* Disable bridge */
+	/* Disable bridge on full reconfiguration */
+	if (bridge_disable) {
 		socfpga_bridges_disable();
 	}
 
-	return 0;
+	return INTEL_SIP_SMC_STATUS_OK;
 }
 
 static bool is_fpga_config_buffer_full(void)
@@ -261,8 +277,9 @@
 	intel_fpga_sdm_write_all();
 
 	if (!is_address_in_ddr_range(mem, size) ||
-		is_fpga_config_buffer_full())
+		is_fpga_config_buffer_full()) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
 
 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
 		int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
@@ -279,14 +296,19 @@
 		}
 	}
 
-	if (is_fpga_config_buffer_full())
+	if (is_fpga_config_buffer_full()) {
 		return INTEL_SIP_SMC_STATUS_BUSY;
+	}
 
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
 static int is_out_of_sec_range(uint64_t reg_addr)
 {
+#if DEBUG
+	return 0;
+#endif
+
 	switch (reg_addr) {
 	case(0xF8011100):	/* ECCCTRL1 */
 	case(0xF8011104):	/* ECCCTRL2 */
@@ -393,7 +415,77 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+static uint32_t intel_rsu_copy_dcmf_version(uint64_t dcmf_ver_1_0,
+					    uint64_t dcmf_ver_3_2)
+{
+	rsu_dcmf_ver[0] = dcmf_ver_1_0;
+	rsu_dcmf_ver[1] = dcmf_ver_1_0 >> 32;
+	rsu_dcmf_ver[2] = dcmf_ver_3_2;
+	rsu_dcmf_ver[3] = dcmf_ver_3_2 >> 32;
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_copy_dcmf_status(uint64_t dcmf_stat)
+{
+	rsu_dcmf_stat[0] = 0xFFFF & (dcmf_stat >> (0 * 16));
+	rsu_dcmf_stat[1] = 0xFFFF & (dcmf_stat >> (1 * 16));
+	rsu_dcmf_stat[2] = 0xFFFF & (dcmf_stat >> (2 * 16));
+	rsu_dcmf_stat[3] = 0xFFFF & (dcmf_stat >> (3 * 16));
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Intel HWMON services */
+static uint32_t intel_hwmon_readtemp(uint32_t chan, uint32_t *retval)
+{
+	if (chan > TEMP_CHANNEL_MAX) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (mailbox_hwmon_readtemp(chan, retval) < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_hwmon_readvolt(uint32_t chan, uint32_t *retval)
+{
+	if (chan > VOLT_CHANNEL_MAX) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (mailbox_hwmon_readvolt(chan, retval) < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /* Mailbox services */
+static uint32_t intel_smc_fw_version(uint32_t *fw_version)
+{
+	int status;
+	unsigned int resp_len = CONFIG_STATUS_WORD_SIZE;
+	uint32_t resp_data[CONFIG_STATUS_WORD_SIZE] = {0U};
+
+	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CONFIG_STATUS, NULL, 0U,
+			CMD_CASUAL, resp_data, &resp_len);
+
+	if (status < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (resp_len <= CONFIG_STATUS_FW_VER_OFFSET) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*fw_version = resp_data[CONFIG_STATUS_FW_VER_OFFSET] & CONFIG_STATUS_FW_VER_MASK;
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args,
 				unsigned int len,
 				uint32_t urgent, uint32_t *response,
@@ -419,6 +511,33 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+static int intel_smc_get_usercode(uint32_t *user_code)
+{
+	int status;
+	unsigned int resp_len = sizeof(user_code) / MBOX_WORD_BYTE;
+
+	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_USERCODE, NULL,
+				0U, CMD_CASUAL, user_code, &resp_len);
+
+	if (status < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Miscellaneous HPS services */
+static uint32_t intel_hps_set_bridges(uint64_t enable)
+{
+	if (enable != 0U) {
+		socfpga_bridges_enable();
+	} else {
+		socfpga_bridges_disable();
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -433,8 +552,9 @@
 			 u_register_t flags)
 {
 	uint32_t retval = 0;
+	uint32_t mbox_error = 0;
 	uint32_t completed_addr[3];
-	uint64_t rsu_respbuf[9];
+	uint64_t retval64, rsu_respbuf[9];
 	int status = INTEL_SIP_SMC_STATUS_OK;
 	int mbox_status;
 	unsigned int len_in_resp;
@@ -530,10 +650,41 @@
 			SMC_RET2(handle, status, retval);
 		}
 
+	case INTEL_SIP_SMC_RSU_DCMF_VERSION:
+		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+			 ((uint64_t)rsu_dcmf_ver[1] << 32) | rsu_dcmf_ver[0],
+			 ((uint64_t)rsu_dcmf_ver[3] << 32) | rsu_dcmf_ver[2]);
+
+	case INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION:
+		status = intel_rsu_copy_dcmf_version(x1, x2);
+		SMC_RET1(handle, status);
+
+	case INTEL_SIP_SMC_RSU_DCMF_STATUS:
+		SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK,
+			 ((uint64_t)rsu_dcmf_stat[3] << 48) |
+			 ((uint64_t)rsu_dcmf_stat[2] << 32) |
+			 ((uint64_t)rsu_dcmf_stat[1] << 16) |
+			 rsu_dcmf_stat[0]);
+
+	case INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS:
+		status = intel_rsu_copy_dcmf_status(x1);
+		SMC_RET1(handle, status);
+
+	case INTEL_SIP_SMC_RSU_MAX_RETRY:
+		SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK, rsu_max_retry);
+
+	case INTEL_SIP_SMC_RSU_COPY_MAX_RETRY:
+		rsu_max_retry = x1;
+		SMC_RET1(handle, INTEL_SIP_SMC_STATUS_OK);
+
 	case INTEL_SIP_SMC_ECC_DBE:
 		status = intel_ecc_dbe_notification(x1);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_FIRMWARE_VERSION:
+		status = intel_smc_fw_version(&retval);
+		SMC_RET2(handle, status, retval);
+
 	case INTEL_SIP_SMC_MBOX_SEND_CMD:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
@@ -542,6 +693,32 @@
 					     &len_in_resp);
 		SMC_RET3(handle, status, mbox_status, len_in_resp);
 
+	case INTEL_SIP_SMC_GET_USERCODE:
+		status = intel_smc_get_usercode(&retval);
+		SMC_RET2(handle, status, retval);
+
+	case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
+		status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
+							&mbox_error);
+		SMC_RET4(handle, status, mbox_error, x1, retval64);
+
+	case INTEL_SIP_SMC_SVC_VERSION:
+		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+					SIP_SVC_VERSION_MAJOR,
+					SIP_SVC_VERSION_MINOR);
+
+	case INTEL_SIP_SMC_HPS_SET_BRIDGES:
+		status = intel_hps_set_bridges(x1);
+		SMC_RET1(handle, status);
+
+	case INTEL_SIP_SMC_HWMON_READTEMP:
+		status = intel_hwmon_readtemp(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
+	case INTEL_SIP_SMC_HWMON_READVOLT:
+		status = intel_hwmon_readvolt(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index 2a8daa6..5ca1a71 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -42,8 +42,8 @@
 
 	mmio_write_64(PLAT_SEC_ENTRY, 0);
 
-	console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
-		&console);
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+		PLAT_BAUDRATE, &console);
 	/*
 	 * Check params passed from BL31 should not be NULL,
 	 */
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index a8026ea..faff898 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -69,8 +69,8 @@
 
 	watchdog_init(get_wdt_clk());
 
-	console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
-		&console);
+	console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+		PLAT_BAUDRATE, &console);
 
 	socfpga_emac_init();
 	socfpga_delay_timer_init();
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 128a808..be0fae5 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 #include <platform_def.h>
 
 #include "socfpga_mailbox.h"
+#include "socfpga_noc.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
@@ -49,8 +50,8 @@
 
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
 
-	console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
-		&console);
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+		PLAT_BAUDRATE, &console);
 	/*
 	 * Check params passed from BL31 should not be NULL,
 	 */
@@ -122,6 +123,8 @@
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+	enable_ocram_firewall();
 }
 
 const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index b84a567..2defeb9 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +18,8 @@
 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE		0x1000000
 
 /* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
+
 #define SOCFPGA_MMC_REG_BASE                    0xff808000
 
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index d9d88d4..b7808ae 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -26,7 +26,8 @@
 			lib/xlat_tables/xlat_tables_common.c 		\
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S	\
-			plat/intel/soc/common/socfpga_delay_timer.c
+			plat/intel/soc/common/socfpga_delay_timer.c	\
+			plat/intel/soc/common/soc/socfpga_firewall.c
 
 BL2_SOURCES     +=	\
 		common/desc_image_load.c				\
@@ -50,7 +51,6 @@
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
-		plat/intel/soc/common/soc/socfpga_system_manager.c	\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
 		plat/intel/soc/common/drivers/wdt/watchdog.c
 
diff --git a/plat/mediatek/build_helpers/conditional_eval_options.mk b/plat/mediatek/build_helpers/conditional_eval_options.mk
new file mode 100644
index 0000000..6bb3b4e
--- /dev/null
+++ b/plat/mediatek/build_helpers/conditional_eval_options.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Conditional makefile variable assignment
+
+# Options depend on BUILD_TYPE variable
+ifeq ($(BUILD_TYPE),release)
+MTK_DEBUGSYS_LOCK := 1
+MTK_GET_PERM_DIS := 1
+ERRATA_KLEIN_2218950 := 0
+ERRATA_KLEIN_2184257 := 0
+ERRATA_KLEIN_BOOKER := 0
+ERRATA_MTH_BOOKER := 0
+ERRATA_MTHELP_BOOKER := 0
+CRASH_REPORTING := 1
+CONFIG_MTK_BL31_RAMDUMP := 0
+endif
+
+ifeq ($(BUILD_TYPE),debug)
+MTK_PTP3_PROC_DEBUG := 1
+MTK_SRAMRC_DEBUG := 1
+MTK_IOMMU_DEBUG := 1
+MTK_DCM_DEBUG := 1
+MTK_EMI_MPU_DEBUG := 1
+endif
+
+ifeq (${SPD},none)
+SPD_NONE:=1
+$(eval $(call add_define,SPD_NONE))
+endif
+
+# TEE OS config
+ifeq ($(SPD), tbase)
+CONFIG_TBASE := y
+endif
+
+# MICROTRUST OS config
+ifeq ($(SPD), teeid)
+CONFIG_MICROTRUST_TEEI := y
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V8_2},y)
+ARCH_VERSION := armv8_2
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V9},y)
+ARCH_VERSION := armv9
+endif
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
new file mode 100644
index 0000000..47d96fa
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -0,0 +1,139 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Get local directory path
+define GET_LOCAL_DIR
+$(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
+endef
+
+# Clear module source variable
+define CLEAR_LOCAL_SRCS
+$(eval $(1) :=)
+endef
+
+define EXPAND_SUB_MAKEFILE
+include $(S)
+endef
+
+# Expand sub rules.mk
+define INCLUDE_MAKEFILE
+$(eval MODULES_SUB_MAKEFILE := $(patsubst %,%/rules.mk,$(1)))
+$(foreach S,$(MODULES_SUB_MAKEFILE),$(eval $(EXPAND_SUB_MAKEFILE)))
+endef
+
+# Determine option variable is defined or not then define it
+define add_defined_option
+ifdef $(1)
+ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
+else
+ifeq ($(strip $(value $(1))),y)
+DEFINES += -D$(1)$(if $(value $(1)),=1,)
+endif
+endif
+endif
+endef
+
+define EXPAND_RULES_MAKEFILE
+LOCAL_SRCS-y :=
+MODULE :=
+SUB_RULES-y :=
+include $(S)
+endef
+
+# INCLUDE_MODULES macro expand included modules rules.mk
+# Arguments:
+#   $(1) = MODULES variables
+define INCLUDE_MODULES
+$(eval MODULES_TEMP := $(1))
+$(eval MODULES_MAKEFILE := $(patsubst %,%/rules.mk,$(MODULES_TEMP)))
+$(foreach S,$(MODULES_MAKEFILE),$(eval $(EXPAND_RULES_MAKEFILE)))
+endef
+
+# MAKE_LOCALS expand module source file variable to BL${BL}_SOURCES
+# Arguments:
+#   $(1) = source file
+#   $(2) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LOCALS
+$(eval $(call uppercase,$(2))_SOURCES += $(1))
+endef
+
+# MAKE_LINKERFILE change linker script source file name to
+# target linker script
+#   $(1) = linker script source file
+#   $(2) = BL stage
+define MAKE_LINKERFILE
+$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
+endef
+
+# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
+#   $(1) = linker script source file
+#   $(2) = BL stage
+define MAKE_LINKERFILE_ITER
+$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
+endef
+
+# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
+#   $(1) = output linker script
+#   $(2) = input template
+#   $(3) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LD_ITER
+$(eval index_list=$(shell seq $(words $(1))))
+$(eval $(foreach i, $(index_list), \
+$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
+endef
+
+# MAKE_MODULE reference MAKE_OBJS.
+# Create module folder under out/bl$(BL)/$(module)
+# Arguments:
+#   $(1) = module name
+#   $(2) = source file
+#   $(3) = BL stage
+define MAKE_MODULE
+        $(eval MODULE := $(strip $(1)))
+        $(eval BUILD_DIR  := ${BUILD_PLAT}/${3})
+        $(eval SOURCES    := $(2))
+        $(eval OBJS_TEMP  := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+        $(eval MODULE_OBJS += $(OBJS_TEMP))
+        # We use sort only to get a list of unique object directory names.
+        # ordering is not relevant but sort removes duplicates.
+        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS_TEMP} ${LINKERFILE})))
+        # The $(dir ) function leaves a trailing / on the directory names
+        # Rip off the / to match directory names with make rule targets.
+        $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
+
+$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+${3}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
+
+libraries: $(OBJS_TEMP)
+endef
+
+# Include MTK configuration files
+
+# MTK makefile variables
+MTK_PLAT      := plat/mediatek
+MTK_PLAT_SOC  := ${MTK_PLAT}/${MTK_SOC}
+MTK_COMMON_CFG := $(MTK_PLAT)/common/common_config.mk
+MTK_PLAT_CFG := $(MTK_PLAT_SOC)/plat_config.mk
+MTK_PROJECT_CFG := $(MTK_PLAT)/project/$(PLAT)/project_config.mk
+MTK_OPTIONS := $(MTK_PLAT)/build_helpers/options.mk
+MTK_COND_EVAL := $(MTK_PLAT)/build_helpers/conditional_eval_options.mk
+
+# Indicate which BL should be built in command line
+ifeq (${NEED_BL31},yes)
+MTK_BL := bl31
+endif
+ifeq (${NEED_BL32},yes)
+MTK_BL := bl32
+endif
+# Include common, platform, board level config
+include $(MTK_COMMON_CFG)
+include $(MTK_PLAT_CFG)
+-include $(MTK_PROJECT_CFG)
+include $(MTK_COND_EVAL)
+include $(MTK_OPTIONS)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
new file mode 100644
index 0000000..22a546c
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Expand include modules
+$(eval $(call INCLUDE_MODULES,$(MODULES-y)))
+
+# Make next section align to page size
+ifneq ($(MTK_EXTRA_LINKERFILE),)
+$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
+
+# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
+# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
+# function call
+EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
+
+# Expand derived linker script as build target
+$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
+
+# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
+
+# bl31.ld should depend on EXTRA_LINKERFILE
+$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
+EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
+else
+EXTRA_LINKERFILE :=
+endif
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
new file mode 100644
index 0000000..394a605
--- /dev/null
+++ b/plat/mediatek/build_helpers/options.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# call add_defined_option to evaluate MTK defined value
+$(eval $(call add_defined_option,MTK_SIP_KERNEL_BOOT_ENABLE))
+$(eval $(call add_defined_option,PLAT_EXTRA_LD_SCRIPT))
+$(eval $(call add_defined_option,MTK_EXTRA_LINKERFILE))
+$(eval $(call add_defined_option,MTK_BL31_AS_BL2))
+$(eval $(call add_defined_option,MTK_BL33_IS_64BIT))
+$(eval $(call add_defined_option,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_defined_option,MTK_ADAPTED))
+$(eval $(call add_defined_option,MTK_SOC))
+$(eval $(call add_defined_option,UART_CLOCK))
+$(eval $(call add_defined_option,UART_BAUDRATE))
diff --git a/plat/mediatek/mt6795/aarch64/plat_helpers.S b/plat/mediatek/mt6795/aarch64/plat_helpers.S
deleted file mode 100644
index aaddb2b..0000000
--- a/plat/mediatek/mt6795/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-
-	.globl	plat_secondary_cold_boot_setup
-	.globl	plat_report_exception
-	.globl	platform_is_primary_cpu
-	.globl	plat_crash_console_init
-	.globl	plat_crash_console_putc
-	.globl	plat_crash_console_flush
-	.globl	platform_mem_init
-
-
-	.macro crash_ram_log
-	 /*
-	 * Check teearg->atf_log_buf_size.
-	 * Exit if atf_log_buf_size equals 0
-	 */
-	adr	x2, ptr_atf_crash_flag
-	ldr	x2, [x2]
-	/* exit if ptr_atf_crash_flag equals NULL */
-	cbz x2, exit_putc
-
-	/*
-	 * set atf crash magic number
-	 */
-1:
-	adr	x2, ptr_atf_crash_flag
-	ldr	x2, [x2]
-	mov_imm x1, 0xdead1abf
-	/* p_atf_log_ctrl->atf_crash_flag = 0xdead1abf */
-	str	w1, [x2]
-	/* can't use w3 return addr, w4, start of buffer addr */
-	ldr	w2, [x2]
-	cmp	w2, w1
-	b.ne	1b
-
-	/*
-	 * get cpu id
-	 */
-	mrs	x1, mpidr_el1
-	/* refer to platform_get_core_pos */
-	and	x2, x1, #MPIDR_CPU_MASK
-	and	x1, x1, #MPIDR_CLUSTER_MASK
-	/* x1 = cpu id (cpu id = aff0 + aff1*4 ) */
-	add	x1, x2, x1, LSR #6
-
-	adr	x2, ptr_atf_except_write_pos_per_cpu
-	ldr	x2, [x2]
-	/*
-	 * plus (cpu_id * 8)-->
-	 * &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]
-	 * x2 = &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id];
-	 */
-	add x2, x2, x1, LSL # 3
-	/* log write */
-	/* w1 = p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] */
-	ldr	x1, [x2]
-	/* *x1 = w0-->
-	 *  *(p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]) = c)
-	 */
-	strb	w0, [x1]
-	/* w1++ */
-	add	x1, x1, #1
-	/* p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] = w1 */
-	str	x1, [x2]
-exit_putc:
-	.endm
-
-	/* -----------------------------------------------------
-	 * void plat_secondary_cold_boot_setup (void);
-	 *
-	 * This function performs any platform specific actions
-	 * needed for a secondary cpu after a cold reset e.g
-	 * mark the cpu's presence, mechanism to place it in a
-	 * holding pen etc.
-	 * -----------------------------------------------------
-	 */
-func plat_secondary_cold_boot_setup
-	/* Do not do cold boot for secondary CPU */
-cb_panic:
-	b	cb_panic
-endfunc plat_secondary_cold_boot_setup
-
-func platform_is_primary_cpu
-	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-	cmp	x0, #PLAT_PRIMARY_CPU
-	cset	x0, eq
-	ret
-endfunc platform_is_primary_cpu
-
-	/* ---------------------------------------------
-	 * int plat_crash_console_init(void)
-	 * Function to initialize the crash console
-	 * without a C Runtime to print crash report.
-	 * Clobber list : x0, x1, x2
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_init
-	mov_imm	x0, UART0_BASE
-	mov_imm	x1, UART_CLOCK
-	mov_imm	x2, UART_BAUDRATE
-	b	console_init
-	ret
-endfunc plat_crash_console_init
-
-	/* ---------------------------------------------
-	 * int plat_crash_console_putc(void)
-	 * Function to print a character on the crash
-	 * console without a C Runtime.
-	 * Clobber list : x1, x2
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_putc
-	mov_imm x1, UART0_BASE
-	b	console_core_putc
-	ret
-endfunc plat_crash_console_putc
-
-	/* ---------------------------------------------
-	 * void plat_crash_console_flush(int c)
-	 * Function to force a write of all buffered
-	 * data that hasn't been output.
-	 * Out : void.
-	 * Clobber list : x0, x1
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_flush
-	mov_imm	x0, UART0_BASE
-	b	console_core_flush
-endfunc plat_crash_console_flush
-
-	/* --------------------------------------------------------
-	 * void platform_mem_init (void);
-	 *
-	 * Any memory init, relocation to be done before the
-	 * platform boots. Called very early in the boot process.
-	 * --------------------------------------------------------
-	 */
-func platform_mem_init
-	ret
-endfunc platform_mem_init
-
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
deleted file mode 100644
index 3d881fc..0000000
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.ld.h>
-#include <lib/xlat_tables/xlat_tables_defs.h>
-
-OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
-OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
-ENTRY(bl31_entrypoint)
-
-
-MEMORY {
-	RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_TZRAM_SIZE
-	RAM2 (rwx): ORIGIN = TZRAM2_BASE, LENGTH = TZRAM2_SIZE
-}
-
-
-SECTIONS
-{
-    . = BL31_BASE;
-
-    ASSERT(. == ALIGN(2048),
-           "vector base is not aligned on a 2K boundary.")
-
-    __RO_START__ = .;
-    vector . : {
-        *(.vectors)
-    } >RAM
-
-    ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31_BASE address is not aligned on a page boundary.")
-
-    ro . : {
-        *bl31_entrypoint.o(.text*)
-        *(.text*)
-        *(.rodata*)
-
-	RODATA_COMMON
-
-        __RO_END_UNALIGNED__ = .;
-        /*
-         * Memory page(s) mapped to this section will be marked as read-only,
-         * executable.  No RW data from the next section must creep in.
-         * Ensure the rest of the current memory page is unused.
-         */
-        . = ALIGN(PAGE_SIZE);
-        __RO_END__ = .;
-    } >RAM
-
-    ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
-
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
-
-    DATA_SECTION >RAM
-
-#ifdef BL31_PROGBITS_LIMIT
-    ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.")
-#endif
-
-    STACK_SECTION >RAM
-    BSS_SECTION >RAM
-    __RW_END__ = __BSS_END__;
-
-    ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
-
-    XLAT_TABLE_SECTION >RAM2
-
-#if USE_COHERENT_MEM
-    /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
-     */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
-        __COHERENT_RAM_START__ = .;
-        /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
-         */
-        *(bakery_lock)
-        *(tzfw_coherent_mem)
-        __COHERENT_RAM_END_UNALIGNED__ = .;
-        /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
-         */
-        . = ALIGN(PAGE_SIZE);
-        __COHERENT_RAM_END__ = .;
-    } >RAM2
-#endif
-
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
-    __BL31_END__ = .;
-
-    __BSS_SIZE__ = SIZEOF(.bss);
-#if USE_COHERENT_MEM
-    __COHERENT_RAM_UNALIGNED_SIZE__ =
-        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
-
-    ASSERT(. <= TZRAM2_LIMIT, "TZRAM2 image has exceeded its limit.")
-}
diff --git a/plat/mediatek/mt6795/bl31_plat_setup.c b/plat/mediatek/mt6795/bl31_plat_setup.c
deleted file mode 100644
index 2051fe7..0000000
--- a/plat/mediatek/mt6795/bl31_plat_setup.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-
-#include <mcucfg.h>
-#include <mt_cpuxgpt.h>
-#include <mtk_plat_common.h>
-#include <mtk_sip_svc.h>
-#include <plat_private.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will help us find the layout
- * of trusted SRAM
- ******************************************************************************/
-/*
- * The next 2 constants identify the extents of the code & RO data region.
- * These addresses are used by the MMU setup code and therefore they must be
- * page-aligned.  It is the responsibility of the linker script to ensure that
- * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
- */
-IMPORT_SYM(unsigned long, __RO_START__,	BL31_RO_BASE);
-IMPORT_SYM(unsigned long, __RO_END__,	BL31_RO_LIMIT);
-
-/*
- * Placeholder variables for copying the arguments that have been passed to
- * BL3-1 from BL2.
- */
-static entry_point_info_t bl32_image_ep_info;
-static entry_point_info_t bl33_image_ep_info;
-
-static const int cci_map[] = {
-	PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX,
-	PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX
-};
-
-static uint32_t cci_map_length = ARRAY_SIZE(cci_map);
-
-/* Table of regions to map using the MMU.  */
-static const mmap_region_t plat_mmap[] = {
-	/* for TF text, RO, RW */
-	MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(RAM_CONSOLE_BASE & ~(PAGE_SIZE_MASK), RAM_CONSOLE_SIZE,
-						MT_DEVICE | MT_RW | MT_NS),
-	{ 0 }
-
-};
-
-/*******************************************************************************
- * Macro generating the code for the function setting up the pagetables as per
- * the platform memory map & initialize the mmu, for the given exception level
- ******************************************************************************/
-#define DEFINE_CONFIGURE_MMU_EL(_el)					\
-	void plat_configure_mmu_el ## _el(unsigned long total_base,	\
-				unsigned long total_size,	\
-				unsigned long ro_start,	\
-				unsigned long ro_limit,	\
-				unsigned long coh_start,	\
-				unsigned long coh_limit)	\
-	{								\
-		mmap_add_region(total_base, total_base,			\
-				total_size,				\
-				MT_MEMORY | MT_RW | MT_SECURE);		\
-		mmap_add_region(ro_start, ro_start,			\
-				ro_limit - ro_start,			\
-				MT_MEMORY | MT_RO | MT_SECURE);		\
-		mmap_add_region(coh_start, coh_start,			\
-				coh_limit - coh_start,			\
-				MT_DEVICE | MT_RW | MT_SECURE);		\
-		mmap_add(plat_mmap);					\
-		init_xlat_tables();					\
-									\
-		enable_mmu_el ## _el(0);				\
-	}
-
-/* Define EL3 variants of the function initialising the MMU */
-DEFINE_CONFIGURE_MMU_EL(3)
-
-unsigned int plat_get_syscnt_freq2(void)
-{
-	return SYS_COUNTER_FREQ_IN_TICKS;
-}
-
-void plat_cci_init(void)
-{
-	/* Initialize CCI driver */
-	cci_init(PLAT_MT_CCI_BASE, cci_map, cci_map_length);
-}
-
-void plat_cci_enable(void)
-{
-	/*
-	 * Enable CCI coherency for this cluster.
-	 * No need for locks as no other cpu is active at the moment.
-	 */
-	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-void plat_cci_disable(void)
-{
-	cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-
-static void platform_setup_cpu(void)
-{
-	/* setup big cores */
-	mmio_write_32((uintptr_t)&mt6795_mcucfg->mp1_config_res,
-		MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK |
-		MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK |
-		MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK |
-		MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK |
-		MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK);
-	mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg, MP1_AINACTS);
-	mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_clkenm_div,
-		MP1_SW_CG_GEN);
-	mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_rst_ctl,
-		MP1_L2RSTDISABLE);
-
-	/* set big cores arm64 boot mode */
-	mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_cpucfg,
-		MP1_CPUCFG_64BIT);
-
-	/* set LITTLE cores arm64 boot mode */
-	mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_rv_addr[0].rv_addr_hw,
-		MP0_CPUCFG_64BIT);
-}
-
-/*******************************************************************************
- * Return a pointer to the 'entry_point_info' structure of the next image for
- * the security state specified. BL33 corresponds to the non-secure image type
- * while BL32 corresponds to the secure image type. A NULL pointer is returned
- * if the image does not exist.
- ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
-{
-	entry_point_info_t *next_image_info;
-
-	next_image_info = (type == NON_SECURE) ?
-			&bl33_image_ep_info : &bl32_image_ep_info;
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc)
-		return next_image_info;
-	else
-		return NULL;
-}
-
-/*******************************************************************************
- * Perform any BL3-1 early platform setup. Here is an opportunity to copy
- * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before they
- * are lost (potentially). This needs to be done before the MMU is initialized
- * so that the memory layout can be used while creating page tables.
- * BL2 has flushed this information to memory, so we are guaranteed to pick up
- * good data.
- ******************************************************************************/
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
-				u_register_t arg2, u_register_t arg3)
-{
-	struct mtk_bl_param_t *pmtk_bl_param = (struct mtk_bl_param_t *)arg0;
-	struct atf_arg_t *teearg;
-	unsigned long long normal_base;
-	unsigned long long atf_base;
-
-	assert(pmtk_bl_param != NULL);
-	/*
-	 * Mediatek preloader(i.e, BL2) is in 32 bit state, high 32bits
-	 * of 64 bit GP registers are UNKNOWN if CPU warm reset from 32 bit
-	 * to 64 bit state. So we need to clear high 32bit,
-	 * which may be random value.
-	 */
-	pmtk_bl_param =
-	(struct mtk_bl_param_t *)((uint64_t)pmtk_bl_param & 0x00000000ffffffff);
-
-	teearg  = (struct atf_arg_t *)pmtk_bl_param->tee_info_addr;
-
-	console_init(teearg->atf_log_port, UART_CLOCK, UART_BAUDRATE);
-	memcpy((void *)&gteearg, (void *)teearg, sizeof(struct atf_arg_t));
-
-	normal_base = 0;
-    /* in ATF boot time, timer for cntpct_el0 is not initialized
-     * so it will not count now.
-     */
-	atf_base = read_cntpct_el0();
-	sched_clock_init(normal_base, atf_base);
-
-	VERBOSE("bl31_setup\n");
-
-	/* Populate entry point information for BL3-2 and BL3-3 */
-	SET_PARAM_HEAD(&bl32_image_ep_info,
-				PARAM_EP,
-				VERSION_1,
-				0);
-	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
-	bl32_image_ep_info.pc = BL32_BASE;
-
-	SET_PARAM_HEAD(&bl33_image_ep_info,
-				PARAM_EP,
-				VERSION_1,
-				0);
-	/*
-	 * Tell BL3-1 where the non-trusted software image
-	 * is located and the entry state information
-	 */
-	/* BL33_START_ADDRESS */
-	bl33_image_ep_info.pc = pmtk_bl_param->bl33_start_addr;
-	bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
-	bl33_image_ep_info.args.arg4 =  pmtk_bl_param->bootarg_loc;
-	bl33_image_ep_info.args.arg5 =  pmtk_bl_param->bootarg_size;
-	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-}
-/*******************************************************************************
- * Perform any BL3-1 platform setup code
- ******************************************************************************/
-
-void bl31_platform_setup(void)
-{
-	platform_setup_cpu();
-
-	generic_delay_timer_init();
-
-	plat_mt_gic_driver_init();
-	/* Initialize the gic cpu and distributor interfaces */
-	plat_mt_gic_init();
-
-	/* Topologies are best known to the platform. */
-	mt_setup_topology();
-}
-/*******************************************************************************
- * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
- * Init MTK propiartary log buffer control field.
- ******************************************************************************/
-void bl31_plat_arch_setup(void)
-{
-	/* Enable non-secure access to CCI-400 registers */
-	mmio_write_32(CCI400_BASE + CCI_SEC_ACCESS_OFFSET, 0x1);
-
-	plat_cci_init();
-	plat_cci_enable();
-
-	if (gteearg.atf_log_buf_size != 0) {
-		INFO("mmap atf buffer : 0x%x, 0x%x\n\r",
-			gteearg.atf_log_buf_start,
-			gteearg.atf_log_buf_size);
-
-		mmap_add_region(
-			gteearg.atf_log_buf_start &
-			~(PAGE_SIZE_2MB_MASK),
-			gteearg.atf_log_buf_start &
-			~(PAGE_SIZE_2MB_MASK),
-			PAGE_SIZE_2MB,
-			MT_DEVICE | MT_RW | MT_NS);
-
-		INFO("mmap atf buffer (force 2MB aligned):0x%x, 0x%x\n",
-			(gteearg.atf_log_buf_start & ~(PAGE_SIZE_2MB_MASK)),
-		PAGE_SIZE_2MB);
-	}
-	/*
-	 * add TZRAM_BASE to memory map
-	 * then set RO and COHERENT to different attribute
-	 */
-	plat_configure_mmu_el3(
-		(TZRAM_BASE & ~(PAGE_SIZE_MASK)),
-		(TZRAM_SIZE & ~(PAGE_SIZE_MASK)),
-		(BL31_RO_BASE & ~(PAGE_SIZE_MASK)),
-		BL31_RO_LIMIT,
-		BL_COHERENT_RAM_BASE,
-		BL_COHERENT_RAM_END);
-	/* Initialize for ATF log buffer */
-	if (gteearg.atf_log_buf_size != 0) {
-		gteearg.atf_aee_debug_buf_size = ATF_AEE_BUFFER_SIZE;
-		gteearg.atf_aee_debug_buf_start =
-			gteearg.atf_log_buf_start +
-			gteearg.atf_log_buf_size - ATF_AEE_BUFFER_SIZE;
-		INFO("ATF log service is registered (0x%x, aee:0x%x)\n",
-			gteearg.atf_log_buf_start,
-			gteearg.atf_aee_debug_buf_start);
-	} else{
-		gteearg.atf_aee_debug_buf_size = 0;
-		gteearg.atf_aee_debug_buf_start = 0;
-	}
-
-	/* Platform code before bl31_main */
-	/* compatible to the earlier chipset */
-
-	/* Show to ATF log buffer & UART */
-	INFO("BL3-1: %s\n", version_string);
-	INFO("BL3-1: %s\n", build_message);
-
-}
-#if 0
-/* MTK Define */
-#define ACTLR_CPUECTLR_BIT    (1 << 1)
-
-void enable_ns_access_to_cpuectlr(void)
-{
-	unsigned int next_actlr;
-
-
-	/* ACTLR_EL1 do not implement CUPECTLR  */
-	next_actlr = read_actlr_el2();
-	next_actlr |= ACTLR_CPUECTLR_BIT;
-	write_actlr_el2(next_actlr);
-
-	next_actlr = read_actlr_el3();
-	next_actlr |= ACTLR_CPUECTLR_BIT;
-	write_actlr_el3(next_actlr);
-}
-#endif
-/*******************************************************************************
- * This function prepare boot argument for 64 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned int mode;
-
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	if (el_implemented(2) != EL_IMPL_NONE) {
-		INFO("Kernel_EL2\n");
-		mode = MODE_EL2;
-	} else{
-		INFO("Kernel_EL1\n");
-		mode = MODE_EL1;
-	}
-
-	INFO("Kernel is 64Bit\n");
-	next_image_info->spsr =
-		SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-	next_image_info->pc = get_kernel_info_pc();
-	next_image_info->args.arg0 = get_kernel_info_r0();
-	next_image_info->args.arg1 = get_kernel_info_r1();
-
-	INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx\n",
-				 next_image_info->pc,
-				 next_image_info->args.arg0,
-				 next_image_info->args.arg1);
-
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc)
-		return next_image_info;
-	else
-		return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for 32 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned int mode;
-
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	mode = MODE32_hyp;
-	/*
-	* TODO: Consider the possibility of specifying the SPSR in
-	* the FIP ToC and allowing the platform to have a say as
-	* well.
-	*/
-
-	INFO("Kernel is 32Bit\n");
-	next_image_info->spsr =
-		SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
-		(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
-	next_image_info->pc = get_kernel_info_pc();
-	next_image_info->args.arg0 = get_kernel_info_r0();
-	next_image_info->args.arg1 = get_kernel_info_r1();
-	next_image_info->args.arg2 = get_kernel_info_r2();
-
-	INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx, r2=0x%lx\n",
-				 next_image_info->pc,
-				 next_image_info->args.arg0,
-				 next_image_info->args.arg1,
-				 next_image_info->args.arg2);
-
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc)
-		return next_image_info;
-	else
-		return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for kernel entrypoint
- ******************************************************************************/
-void bl31_prepare_kernel_entry(uint64_t k32_64)
-{
-	entry_point_info_t *next_image_info;
-	uint32_t image_type;
-
-	/* Determine which image to execute next */
-	/* image_type = bl31_get_next_image_type(); */
-	image_type = NON_SECURE;
-
-	/* Program EL3 registers to enable entry into the next EL */
-	if (k32_64 == 0)
-		next_image_info = bl31_plat_get_next_kernel32_ep_info();
-	else
-		next_image_info = bl31_plat_get_next_kernel64_ep_info();
-
-	assert(next_image_info);
-	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
-
-	INFO("BL3-1: Preparing for EL3 exit to %s world, Kernel\n",
-		(image_type == SECURE) ? "secure" : "normal");
-	INFO("BL3-1: Next image address = 0x%llx\n",
-		(unsigned long long) next_image_info->pc);
-	INFO("BL3-1: Next image spsr = 0x%x\n", next_image_info->spsr);
-	cm_init_my_context(next_image_info);
-	cm_prepare_el3_exit(image_type);
-}
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
deleted file mode 100644
index 3696f8e..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdint.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <lib/mmio.h>
-#include <plat/common/platform.h>
-
-#include <mt_cpuxgpt.h>
-
-#define CPUXGPT_BASE	0x10200000
-#define INDEX_BASE		(CPUXGPT_BASE+0x0674)
-#define CTL_BASE		(CPUXGPT_BASE+0x0670)
-
-uint64_t normal_time_base;
-uint64_t atf_time_base;
-
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base)
-{
-	normal_time_base = normal_base;
-	atf_time_base = atf_base;
-}
-
-uint64_t sched_clock(void)
-{
-	uint64_t cval;
-
-	cval = (((read_cntpct_el0() - atf_time_base)*1000)/
-		SYS_COUNTER_FREQ_IN_MHZ) + normal_time_base;
-	return cval;
-}
-
-/*
-  * Return: 0 - Trying to disable the CPUXGPT control bit,
-  * and not allowed to disable it.
-  * Return: 1 - reg_addr is not realted to disable the control bit.
-  */
-unsigned char check_cpuxgpt_write_permission(unsigned int reg_addr,
-	unsigned int reg_value)
-{
-	unsigned int idx;
-	unsigned int ctl_val;
-
-	if (reg_addr == CTL_BASE) {
-		idx = mmio_read_32(INDEX_BASE);
-
-		/* idx 0: CPUXGPT system control */
-		if (idx == 0) {
-			ctl_val = mmio_read_32(CTL_BASE);
-			if (ctl_val & 1) {
-				/*
-				 * if enable bit already set,
-				 * then bit 0 is not allow to set as 0
-				 */
-				if (!(reg_value & 1))
-					return 0;
-			}
-		}
-	}
-	return 1;
-}
-
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
deleted file mode 100644
index 84df081..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MT_CPUXGPT_H
-#define MT_CPUXGPT_H
-
-/* REG */
-#define INDEX_CTL_REG       0x000
-#define INDEX_STA_REG       0x004
-#define INDEX_CNT_L_INIT    0x008
-#define INDEX_CNT_H_INIT    0x00C
-
-/* CTL_REG SET */
-#define EN_CPUXGPT          0x01
-#define EN_AHLT_DEBUG       0x02
-#define CLK_DIV1            (0x1 << 8)
-#define CLK_DIV2            (0x2 << 8)
-#define CLK_DIV4            (0x4 << 8)
-#define CLK_DIV_MASK        (~(0x7<<8))
-
-void generic_timer_backup(void);
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base);
-uint64_t sched_clock(void);
-
-#endif /* MT_CPUXGPT_H */
diff --git a/plat/mediatek/mt6795/include/mcucfg.h b/plat/mediatek/mt6795/include/mcucfg.h
deleted file mode 100644
index 21c5394..0000000
--- a/plat/mediatek/mt6795/include/mcucfg.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MCUCFG_H
-#define MCUCFG_H
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-struct mt6795_mcucfg_regs {
-	uint32_t mp0_ca7l_cache_config;
-	struct {
-		uint32_t mem_delsel0;
-		uint32_t mem_delsel1;
-	} mp0_cpu[4];
-	uint32_t mp0_cache_mem_delsel0;
-	uint32_t mp0_cache_mem_delsel1;
-	uint32_t mp0_axi_config;
-	uint32_t mp0_misc_config[2];
-	struct {
-		uint32_t rv_addr_lw;
-		uint32_t rv_addr_hw;
-	} mp0_rv_addr[4];
-	uint32_t mp0_ca7l_cfg_dis;
-	uint32_t mp0_ca7l_clken_ctrl;
-	uint32_t mp0_ca7l_rst_ctrl;
-	uint32_t mp0_ca7l_misc_config;
-	uint32_t mp0_ca7l_dbg_pwr_ctrl;
-	uint32_t mp0_rw_rsvd0;
-	uint32_t mp0_rw_rsvd1;
-	uint32_t mp0_ro_rsvd;
-	uint32_t reserved0_0[100];
-	uint32_t mp1_cpucfg;
-	uint32_t mp1_miscdbg;
-	uint32_t reserved0_1[13];
-	uint32_t mp1_rst_ctl;
-	uint32_t mp1_clkenm_div;
-	uint32_t reserved0_2[7];
-	uint32_t mp1_config_res;
-	uint32_t reserved0_3[13];
-	struct {
-		uint32_t rv_addr_lw;
-		uint32_t rv_addr_hw;
-	} mp1_rv_addr[2];
-	uint32_t reserved0_4[84];
-	uint32_t mp0_rst_status;		/* 0x400 */
-	uint32_t mp0_dbg_ctrl;
-	uint32_t mp0_dbg_flag;
-	uint32_t mp0_ca7l_ir_mon;
-	struct {
-		uint32_t pc_lw;
-		uint32_t pc_hw;
-		uint32_t fp_arch32;
-		uint32_t sp_arch32;
-		uint32_t fp_arch64_lw;
-		uint32_t fp_arch64_hw;
-		uint32_t sp_arch64_lw;
-		uint32_t sp_arch64_hw;
-	} mp0_dbg_core[4];
-	uint32_t dfd_ctrl;
-	uint32_t dfd_cnt_l;
-	uint32_t dfd_cnt_h;
-	uint32_t misccfg_mp0_rw_rsvd;
-	uint32_t misccfg_sec_vio_status0;
-	uint32_t misccfg_sec_vio_status1;
-	uint32_t reserved1[22];
-	uint32_t misccfg_rw_rsvd;		/* 0x500 */
-	uint32_t mcusys_dbg_mon_sel_a;
-	uint32_t mcusys_dbg_mon;
-	uint32_t reserved2[61];
-	uint32_t mcusys_config_a;		/* 0x600 */
-	uint32_t mcusys_config1_a;
-	uint32_t mcusys_gic_peribase_a;
-	uint32_t reserved3;
-	uint32_t sec_range0_start;		/* 0x610 */
-	uint32_t sec_range0_end;
-	uint32_t sec_range_enable;
-	uint32_t reserved4;
-	uint32_t int_pol_ctl[8];		/* 0x620 */
-	uint32_t aclken_div;			/* 0x640 */
-	uint32_t pclken_div;
-	uint32_t l2c_sram_ctrl;
-	uint32_t armpll_jit_ctrl;
-	uint32_t cci_addrmap;			/* 0x650 */
-	uint32_t cci_config;
-	uint32_t cci_periphbase;
-	uint32_t cci_nevntcntovfl;
-	uint32_t cci_clk_ctrl;			/* 0x660 */
-	uint32_t cci_acel_s1_ctrl;
-	uint32_t bus_fabric_dcm_ctrl;
-	uint32_t reserved5;
-	uint32_t xgpt_ctl;			/* 0x670 */
-	uint32_t xgpt_idx;
-	uint32_t ptpod2_ctl0;
-	uint32_t ptpod2_ctl1;
-	uint32_t mcusys_revid;
-	uint32_t mcusys_rw_rsvd0;
-	uint32_t mcusys_rw_rsvd1;
-};
-
-static struct mt6795_mcucfg_regs *const mt6795_mcucfg = (void *)MCUCFG_BASE;
-
-/* cpu boot mode */
-#define	MP0_CPUCFG_64BIT_SHIFT	12
-#define	MP1_CPUCFG_64BIT_SHIFT	28
-#define	MP0_CPUCFG_64BIT	(U(0xf) << MP0_CPUCFG_64BIT_SHIFT)
-#define	MP1_CPUCFG_64BIT	(U(0xf) << MP1_CPUCFG_64BIT_SHIFT)
-
-/* scu related */
-enum {
-	MP0_ACINACTM_SHIFT = 4,
-	MP1_ACINACTM_SHIFT = 0,
-	MP0_ACINACTM = 1 << MP0_ACINACTM_SHIFT,
-	MP1_ACINACTM = 1 << MP1_ACINACTM_SHIFT
-};
-
-enum {
-	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0,
-	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4,
-	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8,
-	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12,
-	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16,
-
-	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK =
-		0xf << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
-	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK =
-		0xf << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
-	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK =
-		0xf << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
-	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK =
-		0xf << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
-	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK =
-		0xf << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT
-};
-
-enum {
-	MP1_AINACTS_SHIFT = 4,
-	MP1_AINACTS = 1 << MP1_AINACTS_SHIFT
-};
-
-enum {
-	MP1_SW_CG_GEN_SHIFT = 12,
-	MP1_SW_CG_GEN = 1 << MP1_SW_CG_GEN_SHIFT
-};
-
-enum {
-	MP1_L2RSTDISABLE_SHIFT = 14,
-	MP1_L2RSTDISABLE = 1 << MP1_L2RSTDISABLE_SHIFT
-};
-
-#endif  /* MCUCFG_H */
diff --git a/plat/mediatek/mt6795/include/plat_macros.S b/plat/mediatek/mt6795/include/plat_macros.S
deleted file mode 100644
index d198fdc..0000000
--- a/plat/mediatek/mt6795/include/plat_macros.S
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <drivers/arm/cci.h>
-#include <platform_def.h>
-
-.section .rodata.gic_reg_name, "aS"
-gicc_regs:
-	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
-gicd_pend_reg:
-	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
-		" Offset:\t\t\tvalue\n"
-newline:
-	.asciz "\n"
-spacer:
-	.asciz ":\t\t0x"
-
-	/* ---------------------------------------------
-	 * The below macro prints out relevant GIC
-	 * registers whenever an unhandled exception is
-	 * taken in BL3-1.
-	 * Clobbers: x0 - x10, x16, x17, sp
-	 * ---------------------------------------------
-	 */
-	.macro plat_crash_print_regs
-	mov_imm x16, BASE_GICD_BASE
-	mov_imm x17, BASE_GICC_BASE
-	/* Load the gicc reg list to x6 */
-	adr	x6, gicc_regs
-	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
-	ldr	w8, [x17, #GICC_HPPIR]
-	ldr	w9, [x17, #GICC_AHPPIR]
-	ldr	w10, [x17, #GICC_CTLR]
-	/* Store to the crash buf and print to console */
-	bl	str_in_crash_buf_print
-
-	/* Print the GICD_ISPENDR regs */
-	add	x7, x16, #GICD_ISPENDR
-	adr	x4, gicd_pend_reg
-	bl	asm_print_str
-gicd_ispendr_loop:
-	sub	x4, x7, x16
-	cmp	x4, #0x280
-	b.eq	exit_print_gic_regs
-	bl	asm_print_hex
-
-	adr	x4, spacer
-	bl	asm_print_str
-
-	ldr	x4, [x7], #8
-	bl	asm_print_hex
-
-	adr	x4, newline
-	bl	asm_print_str
-	b	gicd_ispendr_loop
-exit_print_gic_regs:
-	.endm
-
-.section .rodata.cci_reg_name, "aS"
-cci_iface_regs:
-	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
-
-	/* ------------------------------------------------
-	 * The below macro prints out relevant interconnect
-	 * registers whenever an unhandled exception is
-	 * taken in BL3-1.
-	 * Clobbers: x0 - x9, sp
-	 * ------------------------------------------------
-	 */
-	.macro plat_print_interconnect_regs
-	adr	x6, cci_iface_regs
-	/* Store in x7 the base address of the first interface */
-	mov_imm	x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET(	\
-			PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX))
-	ldr	w8, [x7, #SNOOP_CTRL_REG]
-	/* Store in x7 the base address of the second interface */
-	mov_imm	x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET(	\
-			PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX))
-	ldr	w9, [x7, #SNOOP_CTRL_REG]
-	/* Store to the crash buf and print to console */
-	bl	str_in_crash_buf_print
-	.endm
diff --git a/plat/mediatek/mt6795/include/plat_private.h b/plat/mediatek/mt6795/include/plat_private.h
deleted file mode 100644
index f7450ca..0000000
--- a/plat/mediatek/mt6795/include/plat_private.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_PRIVATE_H
-#define PLAT_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/xlat_tables/xlat_tables.h>
-
-void plat_configure_mmu_el3(unsigned long total_base,
-					unsigned long total_size,
-					unsigned long,
-					unsigned long,
-					unsigned long,
-					unsigned long);
-
-void plat_cci_init(void);
-void plat_cci_enable(void);
-void plat_cci_disable(void);
-
-/* Declarations for plat_mt_gic.c */
-void plat_mt_gic_init(void);
-
-/* Declarations for plat_topology.c */
-int mt_setup_topology(void);
-void plat_delay_timer_init(void);
-
-void plat_mt_gic_driver_init(void);
-void plat_mt_gic_init(void);
-void plat_mt_gic_cpuif_enable(void);
-void plat_mt_gic_cpuif_disable(void);
-void plat_mt_gic_pcpu_init(void);
-
-#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt6795/include/plat_sip_calls.h b/plat/mediatek/mt6795/include/plat_sip_calls.h
deleted file mode 100644
index b9a1363..0000000
--- a/plat/mediatek/mt6795/include/plat_sip_calls.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_SIP_CALLS_H
-#define PLAT_SIP_CALLS_H
-
-/*******************************************************************************
- * Plat SiP function constants
- ******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS	0
-
-#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h
deleted file mode 100644
index b353a3d..0000000
--- a/plat/mediatek/mt6795/include/platform_def.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#define PLAT_PRIMARY_CPU  0x0
-
-/* Special value used to verify platform parameters from BL2 to BL3-1 */
-#define MT_BL31_PLAT_PARAM_VAL  0x0f1e2d3c4b5a6978ULL
-
-#define IO_PHYS             (0x10000000)
-#define INFRACFG_AO_BASE    (IO_PHYS + 0x1000)
-#define MCUCFG_BASE         (IO_PHYS + 0x200000)
-#define PERI_BASE           (IO_PHYS + 0x1000000)
-
-
-#define GPIO_BASE           (IO_PHYS + 0x370000)
-#define SPM_BASE            (IO_PHYS + 0x6000)
-#define RGU_BASE            (MCUCFG_BASE + 0x11000)
-#define PMIC_WRAP_BASE      (IO_PHYS + 0x10000)
-
-#define TRNG_base           (MCUCFG_BASE + 0x230000)
-#define MT_GIC_BASE         (0x10220000)
-#define MCU_SYS_SIZE        (0x700000)
-#define PLAT_MT_CCI_BASE    (IO_PHYS + 0x390000)
-
-/* Aggregate of all devices in the first GB */
-#define MTK_DEV_RNG0_BASE   IO_PHYS
-#define MTK_DEV_RNG0_SIZE   0x400000
-#define MTK_DEV_RNG1_BASE   (PERI_BASE)
-#define MTK_DEV_RNG1_SIZE   0x4000000
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define UART0_BASE (PERI_BASE + 0x2000)
-
-#define UART_BAUDRATE   (921600)
-#define UART_CLOCK (26000000)
-
-/*******************************************************************************
- * System counter frequency related constants
- ******************************************************************************/
-#define SYS_COUNTER_FREQ_IN_TICKS	13000000
-#define SYS_COUNTER_FREQ_IN_MHZ		(SYS_COUNTER_FREQ_IN_TICKS/1000000)
-
-/*******************************************************************************
- * GIC-400 & interrupt handling related constants
- ******************************************************************************/
-
-/* Base MTK_platform compatible GIC memory map */
-#define BASE_GICD_BASE      (MT_GIC_BASE+0x1000)
-#define BASE_GICC_BASE      (MT_GIC_BASE + 0x2000)
-#define BASE_GICR_BASE      (MT_GIC_BASE + 0x200000)
-#define BASE_GICH_BASE      (MT_GIC_BASE + 0x4000)
-#define BASE_GICV_BASE      (MT_GIC_BASE + 0x6000)
-
-#define INT_POL_CTL0        0x10200620
-#define GIC_PRIVATE_SIGNALS (32)
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX  4
-#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX  3
-
-/*******************************************************************************
- * WDT Registers
- ******************************************************************************/
-#define MTK_WDT_BASE                        (RGU_BASE)
-#define MTK_WDT_SIZE                        (0x1000)
-#define MTK_WDT_MODE                        (MTK_WDT_BASE+0x0000)
-#define MTK_WDT_LENGTH                      (MTK_WDT_BASE+0x0004)
-#define MTK_WDT_RESTART                     (MTK_WDT_BASE+0x0008)
-#define MTK_WDT_STATUS                      (MTK_WDT_BASE+0x000C)
-#define MTK_WDT_INTERVAL                    (MTK_WDT_BASE+0x0010)
-#define MTK_WDT_SWRST                       (MTK_WDT_BASE+0x0014)
-#define MTK_WDT_SWSYSRST                    (MTK_WDT_BASE+0x0018)
-#define MTK_WDT_NONRST_REG                  (MTK_WDT_BASE+0x0020)
-#define MTK_WDT_NONRST_REG2                 (MTK_WDT_BASE+0x0024)
-#define MTK_WDT_REQ_MODE                    (MTK_WDT_BASE+0x0030)
-#define MTK_WDT_REQ_IRQ_EN                  (MTK_WDT_BASE+0x0034)
-#define MTK_WDT_DEBUG_CTL                   (MTK_WDT_BASE+0x0040)
-
-/*WDT_STATUS*/
-#define MTK_WDT_STATUS_HWWDT_RST            (0x80000000)
-#define MTK_WDT_STATUS_SWWDT_RST            (0x40000000)
-#define MTK_WDT_STATUS_IRQWDT_RST           (0x20000000)
-#define MTK_WDT_STATUS_DEBUGWDT_RST         (0x00080000)
-#define MTK_WDT_STATUS_SPMWDT_RST           (0x0002)
-#define MTK_WDT_STATUS_SPM_THERMAL_RST      (0x0001)
-#define MTK_WDT_STATUS_THERMAL_DIRECT_RST   (1<<18)
-#define MTK_WDT_STATUS_SECURITY_RST         (1<<28)
-
-#define MTK_WDT_MODE_DUAL_MODE              0x0040
-#define MTK_WDT_MODE_IRQ                    0x0008
-#define MTK_WDT_MODE_KEY                    0x22000000
-#define MTK_WDT_MODE_EXTEN                  0x0004
-#define MTK_WDT_SWRST_KEY                   0x1209
-#define MTK_WDT_RESTART_KEY                 (0x1971)
-
-/* FIQ platform related define */
-#define MT_IRQ_SEC_SGI_0  8
-#define MT_IRQ_SEC_SGI_1  9
-#define MT_IRQ_SEC_SGI_2  10
-#define MT_IRQ_SEC_SGI_3  11
-#define MT_IRQ_SEC_SGI_4  12
-#define MT_IRQ_SEC_SGI_5  13
-#define MT_IRQ_SEC_SGI_6  14
-#define MT_IRQ_SEC_SGI_7  15
-
-#define FIQ_SMP_CALL_SGI  MT_IRQ_SEC_SGI_5
-
-/*******************************************************************************
- * Platform binary types for linking
- ******************************************************************************/
-#define PLATFORM_LINKER_FORMAT    "elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH      aarch64
-
-/*******************************************************************************
- * Generic platform constants
- ******************************************************************************/
-
-/* Size of cacheable stacks */
-#if defined(IMAGE_BL1)
-#define PLATFORM_STACK_SIZE 0x440
-#elif defined(IMAGE_BL2)
-#define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-#define PLATFORM_STACK_SIZE 0x800
-#elif defined(IMAGE_BL32)
-#define PLATFORM_STACK_SIZE 0x440
-#endif
-
-#define FIRMWARE_WELCOME_STR    "Booting Trusted Firmware\n"
-#define PLAT_MAX_PWR_LVL        U(2) /* MPIDR_AFFLVL2 */
-
-#define PLAT_MAX_RET_STATE	U(1)
-#define PLAT_MAX_OFF_STATE	U(2)
-
-#define PLATFORM_CACHE_LINE_SIZE      64
-#define PLATFORM_SYSTEM_COUNT         U(1)
-#define PLATFORM_CLUSTER_COUNT        U(2)
-#define PLATFORM_CLUSTER0_CORE_COUNT  U(4)
-#define PLATFORM_CLUSTER1_CORE_COUNT  U(4)
-#define PLATFORM_CORE_COUNT   (PLATFORM_CLUSTER1_CORE_COUNT + \
-					PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_NUM_AFFS   (PLATFORM_SYSTEM_COUNT +  \
-					PLATFORM_CLUSTER_COUNT + \
-					PLATFORM_CORE_COUNT)
-
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-/* ATF Argument */
-#define ATF_ARG_SIZE      (0x800)
-
-/* TF txet, ro, rw, internal SRAM, Size: release: 80KB, debug: 92KB */
-#define TZRAM_BASE        (0x110000)
-#if DEBUG
-#define TZRAM_SIZE        (0x1C400)
-#else
-#define TZRAM_SIZE        (0x1C400)
-#endif
-#define TZRAM2_BASE	   0x00100000
-#define TZRAM2_SIZE	   0xDC00
-#define TZRAM2_LIMIT		(TZRAM2_BASE + TZRAM2_SIZE)
-
-#define RAM_CONSOLE_BASE  0x0012D000
-#define RAM_CONSOLE_SIZE  0x00001000
-/*******************************************************************************
- * BL31 specific defines.
- ******************************************************************************/
-/*
- * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
- * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
- * little space for growth.
- */
-#define BL31_BASE           (TZRAM_BASE + 0x1000)
-#define BL31_LIMIT          (TZRAM_BASE + TZRAM_SIZE)
-#define BSS1_STACK_LIMIT    (TZRAM_BASE + TZRAM_SIZE)
-#define BL31_TZRAM_SIZE     (TZRAM_SIZE - ATF_ARG_SIZE)
-
-/*******************************************************************************
- * Platform specific page table and MMU setup constants
- ******************************************************************************/
-#define PLAT_VIRT_ADDR_SPACE_SIZE   (1ULL << 32)
-#define PLAT_PHY_ADDR_SPACE_SIZE    (1ULL << 32)
-#define MAX_XLAT_TABLES   7
-#define MAX_MMAP_REGIONS  16
-
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define CCI400_BASE                     0x10390000
-#define CCI400_SL_IFACE_CLUSTER0        4
-#define CCI400_SL_IFACE_CLUSTER1        3
-#define CCI400_SL_IFACE_INDEX(mpidr)  (mpidr & MPIDR_CLUSTER_MASK ? \
-					CCI400_SL_IFACE_CLUSTER1 :   \
-					CCI400_SL_IFACE_CLUSTER0)
-#define CCI_SEC_ACCESS_OFFSET           (0x8)
-
-
-/*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned on the biggest cache line size in the platform. This is known only
- * to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
- ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT     6
-#define CACHE_WRITEBACK_GRANULE   (1 << CACHE_WRITEBACK_SHIFT)
-
-#define BL32_BASE                 (0x0)
-
-/*
- * Load address of BL3-3 for this platform port
- */
-#define LK_SIZE_LIMIT				(0x100000)
-#define PLAT_MTK_NS_IMAGE_OFFSET	(0x41E00000)
-/* 16KB */
-#define ATF_AEE_BUFFER_SIZE         (0x4000)
-#define PAGE_SIZE_2MB_MASK          (PAGE_SIZE_2MB - 1)
-#define IS_PAGE_2MB_ALIGNED(addr)   (((addr) & PAGE_SIZE_2MB_MASK) == 0)
-#define PAGE_SIZE_2MB               (1 << PAGE_SIZE_2MB_SHIFT)
-#define PAGE_SIZE_2MB_SHIFT         TWO_MB_SHIFT
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt6795/include/power_tracer.h b/plat/mediatek/mt6795/include/power_tracer.h
deleted file mode 100644
index 8c98dbd..0000000
--- a/plat/mediatek/mt6795/include/power_tracer.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef POWER_TRACER_H
-#define POWER_TRACER_H
-
-#define CPU_UP		0
-#define CPU_DOWN	1
-#define CPU_SUSPEND	2
-#define CLUSTER_UP	3
-#define CLUSTER_DOWN	4
-#define CLUSTER_SUSPEND	5
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode);
-
-#endif /* POWER_TRACER_H */
diff --git a/plat/mediatek/mt6795/include/scu.h b/plat/mediatek/mt6795/include/scu.h
deleted file mode 100644
index 625418a..0000000
--- a/plat/mediatek/mt6795/include/scu.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SCU_H
-#define SCU_H
-
-void disable_scu(unsigned long mpidr);
-void enable_scu(unsigned long mpidr);
-
-#endif /* SCU_H */
diff --git a/plat/mediatek/mt6795/include/spm.h b/plat/mediatek/mt6795/include/spm.h
deleted file mode 100644
index 5227e1d..0000000
--- a/plat/mediatek/mt6795/include/spm.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_H
-#define SPM_H
-
-#define SPM_POWERON_CONFIG_SET			(SPM_BASE + 0x000)
-#define SPM_POWER_ON_VAL0			(SPM_BASE + 0x010)
-#define SPM_POWER_ON_VAL1			(SPM_BASE + 0x014)
-#define SPM_CLK_SETTLE				(SPM_BASE + 0x100)
-#define SPM_CA7_CPU1_PWR_CON			(SPM_BASE + 0x218)
-#define SPM_CA7_CPU2_PWR_CON			(SPM_BASE + 0x21c)
-#define SPM_CA7_CPU3_PWR_CON			(SPM_BASE + 0x220)
-#define SPM_CA7_CPU1_L1_PDN			(SPM_BASE + 0x264)
-#define SPM_CA7_CPU2_L1_PDN			(SPM_BASE + 0x26c)
-#define SPM_CA7_CPU3_L1_PDN			(SPM_BASE + 0x274)
-#define SPM_MD32_SRAM_CON			(SPM_BASE + 0x2c8)
-#define SPM_PCM_CON0				(SPM_BASE + 0x310)
-#define SPM_PCM_CON1				(SPM_BASE + 0x314)
-#define SPM_PCM_IM_PTR				(SPM_BASE + 0x318)
-#define SPM_PCM_IM_LEN				(SPM_BASE + 0x31c)
-#define SPM_PCM_REG_DATA_INI			(SPM_BASE + 0x320)
-#define SPM_PCM_EVENT_VECTOR0			(SPM_BASE + 0x340)
-#define SPM_PCM_EVENT_VECTOR1			(SPM_BASE + 0x344)
-#define SPM_PCM_EVENT_VECTOR2			(SPM_BASE + 0x348)
-#define SPM_PCM_EVENT_VECTOR3			(SPM_BASE + 0x34c)
-#define SPM_PCM_MAS_PAUSE_MASK			(SPM_BASE + 0x354)
-#define SPM_PCM_PWR_IO_EN			(SPM_BASE + 0x358)
-#define SPM_PCM_TIMER_VAL			(SPM_BASE + 0x35c)
-#define SPM_PCM_TIMER_OUT			(SPM_BASE + 0x360)
-#define SPM_PCM_REG0_DATA			(SPM_BASE + 0x380)
-#define SPM_PCM_REG1_DATA			(SPM_BASE + 0x384)
-#define SPM_PCM_REG2_DATA			(SPM_BASE + 0x388)
-#define SPM_PCM_REG3_DATA			(SPM_BASE + 0x38c)
-#define SPM_PCM_REG4_DATA			(SPM_BASE + 0x390)
-#define SPM_PCM_REG5_DATA			(SPM_BASE + 0x394)
-#define SPM_PCM_REG6_DATA			(SPM_BASE + 0x398)
-#define SPM_PCM_REG7_DATA			(SPM_BASE + 0x39c)
-#define SPM_PCM_REG8_DATA			(SPM_BASE + 0x3a0)
-#define SPM_PCM_REG9_DATA			(SPM_BASE + 0x3a4)
-#define SPM_PCM_REG10_DATA			(SPM_BASE + 0x3a8)
-#define SPM_PCM_REG11_DATA			(SPM_BASE + 0x3ac)
-#define SPM_PCM_REG12_DATA			(SPM_BASE + 0x3b0)
-#define SPM_PCM_REG13_DATA			(SPM_BASE + 0x3b4)
-#define SPM_PCM_REG14_DATA			(SPM_BASE + 0x3b8)
-#define SPM_PCM_REG15_DATA			(SPM_BASE + 0x3bc)
-#define SPM_PCM_EVENT_REG_STA			(SPM_BASE + 0x3c0)
-#define SPM_PCM_FSM_STA				(SPM_BASE + 0x3c4)
-#define SPM_PCM_IM_HOST_RW_PTR			(SPM_BASE + 0x3c8)
-#define SPM_PCM_IM_HOST_RW_DAT			(SPM_BASE + 0x3cc)
-#define SPM_PCM_EVENT_VECTOR4			(SPM_BASE + 0x3d0)
-#define SPM_PCM_EVENT_VECTOR5			(SPM_BASE + 0x3d4)
-#define SPM_PCM_EVENT_VECTOR6			(SPM_BASE + 0x3d8)
-#define SPM_PCM_EVENT_VECTOR7			(SPM_BASE + 0x3dc)
-#define SPM_PCM_SW_INT_SET			(SPM_BASE + 0x3e0)
-#define SPM_PCM_SW_INT_CLEAR			(SPM_BASE + 0x3e4)
-#define SPM_CLK_CON				(SPM_BASE + 0x400)
-#define SPM_SLEEP_PTPOD2_CON			(SPM_BASE + 0x408)
-#define SPM_APMCU_PWRCTL			(SPM_BASE + 0x600)
-#define SPM_AP_DVFS_CON_SET			(SPM_BASE + 0x604)
-#define SPM_AP_STANBY_CON			(SPM_BASE + 0x608)
-#define SPM_PWR_STATUS				(SPM_BASE + 0x60c)
-#define SPM_PWR_STATUS_2ND			(SPM_BASE + 0x610)
-#define SPM_AP_BSI_REQ				(SPM_BASE + 0x614)
-#define SPM_SLEEP_TIMER_STA			(SPM_BASE + 0x720)
-#define SPM_SLEEP_WAKEUP_EVENT_MASK		(SPM_BASE + 0x810)
-#define SPM_SLEEP_CPU_WAKEUP_EVENT		(SPM_BASE + 0x814)
-#define SPM_SLEEP_MD32_WAKEUP_EVENT_MASK	(SPM_BASE + 0x818)
-#define SPM_PCM_WDT_TIMER_VAL			(SPM_BASE + 0x824)
-#define SPM_PCM_WDT_TIMER_OUT			(SPM_BASE + 0x828)
-#define SPM_PCM_MD32_MAILBOX			(SPM_BASE + 0x830)
-#define SPM_PCM_MD32_IRQ			(SPM_BASE + 0x834)
-#define SPM_SLEEP_ISR_MASK			(SPM_BASE + 0x900)
-#define SPM_SLEEP_ISR_STATUS			(SPM_BASE + 0x904)
-#define SPM_SLEEP_ISR_RAW_STA			(SPM_BASE + 0x910)
-#define SPM_SLEEP_MD32_ISR_RAW_STA		(SPM_BASE + 0x914)
-#define SPM_SLEEP_WAKEUP_MISC			(SPM_BASE + 0x918)
-#define SPM_SLEEP_BUS_PROTECT_RDY		(SPM_BASE + 0x91c)
-#define SPM_SLEEP_SUBSYS_IDLE_STA		(SPM_BASE + 0x920)
-#define SPM_PCM_RESERVE				(SPM_BASE + 0xb00)
-#define SPM_PCM_RESERVE2			(SPM_BASE + 0xb04)
-#define SPM_PCM_FLAGS				(SPM_BASE + 0xb08)
-#define SPM_PCM_SRC_REQ				(SPM_BASE + 0xb0c)
-#define SPM_PCM_DEBUG_CON			(SPM_BASE + 0xb20)
-#define SPM_CA7_CPU0_IRQ_MASK			(SPM_BASE + 0xb30)
-#define SPM_CA7_CPU1_IRQ_MASK			(SPM_BASE + 0xb34)
-#define SPM_CA7_CPU2_IRQ_MASK			(SPM_BASE + 0xb38)
-#define SPM_CA7_CPU3_IRQ_MASK			(SPM_BASE + 0xb3c)
-#define SPM_CA15_CPU0_IRQ_MASK			(SPM_BASE + 0xb40)
-#define SPM_CA15_CPU1_IRQ_MASK			(SPM_BASE + 0xb44)
-#define SPM_CA15_CPU2_IRQ_MASK			(SPM_BASE + 0xb48)
-#define SPM_CA15_CPU3_IRQ_MASK			(SPM_BASE + 0xb4c)
-#define SPM_PCM_PASR_DPD_0			(SPM_BASE + 0xb60)
-#define SPM_PCM_PASR_DPD_1			(SPM_BASE + 0xb64)
-#define SPM_PCM_PASR_DPD_2			(SPM_BASE + 0xb68)
-#define SPM_PCM_PASR_DPD_3			(SPM_BASE + 0xb6c)
-#define SPM_SLEEP_CA7_WFI0_EN			(SPM_BASE + 0xf00)
-#define SPM_SLEEP_CA7_WFI1_EN			(SPM_BASE + 0xf04)
-#define SPM_SLEEP_CA7_WFI2_EN			(SPM_BASE + 0xf08)
-#define SPM_SLEEP_CA7_WFI3_EN			(SPM_BASE + 0xf0c)
-#define SPM_SLEEP_CA15_WFI0_EN			(SPM_BASE + 0xf10)
-#define SPM_SLEEP_CA15_WFI1_EN			(SPM_BASE + 0xf14)
-#define SPM_SLEEP_CA15_WFI2_EN			(SPM_BASE + 0xf18)
-#define SPM_SLEEP_CA15_WFI3_EN			(SPM_BASE + 0xf1c)
-
-#define SPM_PROJECT_CODE	0xb16
-
-#define SPM_REGWR_EN		(1U << 0)
-#define SPM_REGWR_CFG_KEY	(SPM_PROJECT_CODE << 16)
-
-#define SPM_CPU_PDN_DIS		(1U << 0)
-#define SPM_INFRA_PDN_DIS	(1U << 1)
-#define SPM_DDRPHY_PDN_DIS	(1U << 2)
-#define SPM_DUALVCORE_PDN_DIS	(1U << 3)
-#define SPM_PASR_DIS		(1U << 4)
-#define SPM_DPD_DIS		(1U << 5)
-#define SPM_SODI_DIS		(1U << 6)
-#define SPM_MEMPLL_RESET	(1U << 7)
-#define SPM_MAINPLL_PDN_DIS	(1U << 8)
-#define SPM_CPU_DVS_DIS		(1U << 9)
-#define SPM_CPU_DORMANT		(1U << 10)
-#define SPM_EXT_VSEL_GPIO103	(1U << 11)
-#define SPM_DDR_HIGH_SPEED	(1U << 12)
-#define SPM_OPT			(1U << 13)
-
-#define POWER_ON_VAL1_DEF	0x01011820
-#define PCM_FSM_STA_DEF		0x48490
-#define PCM_END_FSM_STA_DEF	0x08490
-#define PCM_END_FSM_STA_MASK	0x3fff0
-#define PCM_HANDSHAKE_SEND1	0xbeefbeef
-
-#define PCM_WDT_TIMEOUT		(30 * 32768)
-#define PCM_TIMER_MAX		(0xffffffff - PCM_WDT_TIMEOUT)
-
-#define CON0_PCM_KICK		(1U << 0)
-#define CON0_IM_KICK		(1U << 1)
-#define CON0_IM_SLEEP_DVS	(1U << 3)
-#define CON0_PCM_SW_RESET	(1U << 15)
-#define CON0_CFG_KEY		(SPM_PROJECT_CODE << 16)
-
-#define CON1_IM_SLAVE		(1U << 0)
-#define CON1_MIF_APBEN		(1U << 3)
-#define CON1_PCM_TIMER_EN	(1U << 5)
-#define CON1_IM_NONRP_EN	(1U << 6)
-#define CON1_PCM_WDT_EN		(1U << 8)
-#define CON1_PCM_WDT_WAKE_MODE	(1U << 9)
-#define CON1_SPM_SRAM_SLP_B	(1U << 10)
-#define CON1_SPM_SRAM_ISO_B	(1U << 11)
-#define CON1_EVENT_LOCK_EN	(1U << 12)
-#define CON1_CFG_KEY		(SPM_PROJECT_CODE << 16)
-
-#define PCM_PWRIO_EN_R0		(1U << 0)
-#define PCM_PWRIO_EN_R7		(1U << 7)
-#define PCM_RF_SYNC_R0		(1U << 16)
-#define PCM_RF_SYNC_R2		(1U << 18)
-#define PCM_RF_SYNC_R6		(1U << 22)
-#define PCM_RF_SYNC_R7		(1U << 23)
-
-#define CC_SYSCLK0_EN_0		(1U << 0)
-#define CC_SYSCLK0_EN_1		(1U << 1)
-#define CC_SYSCLK1_EN_0		(1U << 2)
-#define CC_SYSCLK1_EN_1		(1U << 3)
-#define CC_SYSSETTLE_SEL	(1U << 4)
-#define CC_LOCK_INFRA_DCM	(1U << 5)
-#define CC_SRCLKENA_MASK_0	(1U << 6)
-#define CC_CXO32K_RM_EN_MD1	(1U << 9)
-#define CC_CXO32K_RM_EN_MD2	(1U << 10)
-#define CC_CLKSQ1_SEL		(1U << 12)
-#define CC_DISABLE_DORM_PWR	(1U << 14)
-#define CC_MD32_DCM_EN		(1U << 18)
-
-#define WFI_OP_AND		1
-#define WFI_OP_OR		0
-
-#define WAKE_MISC_PCM_TIMER	(1U << 19)
-#define WAKE_MISC_CPU_WAKE	(1U << 20)
-
-/* define WAKE_SRC_XXX */
-#define WAKE_SRC_SPM_MERGE	(1 << 0)
-#define WAKE_SRC_KP		(1 << 2)
-#define WAKE_SRC_WDT		(1 << 3)
-#define WAKE_SRC_GPT		(1 << 4)
-#define WAKE_SRC_EINT		(1 << 6)
-#define WAKE_SRC_LOW_BAT	(1 << 9)
-#define WAKE_SRC_MD32		(1 << 10)
-#define WAKE_SRC_USB_CD		(1 << 14)
-#define WAKE_SRC_USB_PDN	(1 << 15)
-#define WAKE_SRC_AFE		(1 << 20)
-#define WAKE_SRC_THERM		(1 << 21)
-#define WAKE_SRC_SYSPWREQ	(1 << 24)
-#define WAKE_SRC_SEJ		(1 << 27)
-#define WAKE_SRC_ALL_MD32	(1 << 28)
-#define WAKE_SRC_CPU_IRQ	(1 << 29)
-
-#endif /* SPM_H */
diff --git a/plat/mediatek/mt6795/plat_delay_timer.c b/plat/mediatek/mt6795/plat_delay_timer.c
deleted file mode 100644
index 965b653..0000000
--- a/plat/mediatek/mt6795/plat_delay_timer.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <drivers/delay_timer.h>
-
-static uint32_t plat_get_timer_value(void)
-{
-	/*
-	 * Generic delay timer implementation expects the timer to be a down
-	 * counter. We apply bitwise NOT operator to the tick values returned
-	 * by read_cntpct_el0() to simulate the down counter.
-	 */
-	return (uint32_t)(~read_cntpct_el0());
-}
-
-static const timer_ops_t plat_timer_ops = {
-	.get_timer_value	= plat_get_timer_value,
-	.clk_mult		= 1,
-	.clk_div		= SYS_COUNTER_FREQ_IN_MHZ,
-};
-
-void plat_delay_timer_init(void)
-{
-	timer_init(&plat_timer_ops);
-}
diff --git a/plat/mediatek/mt6795/plat_mt_gic.c b/plat/mediatek/mt6795/plat_mt_gic.c
deleted file mode 100644
index 20cb26d..0000000
--- a/plat/mediatek/mt6795/plat_mt_gic.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/interrupt_props.h>
-#include <drivers/arm/gicv2.h>
-#include <plat/common/platform.h>
-
-static const interrupt_prop_t g0_interrupt_props[] = {
-	INTR_PROP_DESC(FIQ_SMP_CALL_SGI, GIC_HIGHEST_SEC_PRIORITY,
-		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
-};
-
-gicv2_driver_data_t arm_gic_data = {
-	.gicd_base = BASE_GICD_BASE,
-	.gicc_base = BASE_GICC_BASE,
-	.interrupt_props = g0_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
-};
-
-void plat_mt_gic_driver_init(void)
-{
-	gicv2_driver_init(&arm_gic_data);
-}
-
-void plat_mt_gic_init(void)
-{
-	gicv2_distif_init();
-	gicv2_pcpu_distif_init();
-	gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_enable(void)
-{
-	gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_disable(void)
-{
-	gicv2_cpuif_disable();
-}
-
-void plat_mt_gic_pcpu_init(void)
-{
-	gicv2_pcpu_distif_init();
-}
diff --git a/plat/mediatek/mt6795/plat_pm.c b/plat/mediatek/mt6795/plat_pm.c
deleted file mode 100644
index 0dfbd18..0000000
--- a/plat/mediatek/mt6795/plat_pm.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-
-#include <mcucfg.h>
-#include <plat_private.h>
-#include <power_tracer.h>
-#include <scu.h>
-
-struct core_context {
-	unsigned long timer_data[8];
-	unsigned int count;
-	unsigned int rst;
-	unsigned int abt;
-	unsigned int brk;
-};
-
-struct cluster_context {
-	struct core_context core[PLATFORM_MAX_CPUS_PER_CLUSTER];
-};
-
-/*
- * Top level structure to hold the complete context of a multi cluster system
- */
-struct system_context {
-	struct cluster_context cluster[PLATFORM_CLUSTER_COUNT];
-};
-
-/*
- * Top level structure which encapsulates the context of the entire system
- */
-static struct system_context dormant_data[1];
-
-static inline struct cluster_context *system_cluster(
-						struct system_context *system,
-						uint32_t clusterid)
-{
-	return &system->cluster[clusterid];
-}
-
-static inline struct core_context *cluster_core(struct cluster_context *cluster,
-						uint32_t cpuid)
-{
-	return &cluster->core[cpuid];
-}
-
-static struct cluster_context *get_cluster_data(unsigned long mpidr)
-{
-	uint32_t clusterid;
-
-	clusterid = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
-
-	return system_cluster(dormant_data, clusterid);
-}
-
-static struct core_context *get_core_data(unsigned long mpidr)
-{
-	struct cluster_context *cluster;
-	uint32_t cpuid;
-
-	cluster = get_cluster_data(mpidr);
-	cpuid = mpidr & MPIDR_CPU_MASK;
-
-	return cluster_core(cluster, cpuid);
-}
-
-static void mt_save_generic_timer(unsigned long *container)
-{
-	uint64_t ctl;
-	uint64_t val;
-
-	__asm__ volatile("mrs	%x0, cntkctl_el1\n\t"
-			 "mrs	%x1, cntp_cval_el0\n\t"
-			 "stp	%x0, %x1, [%2, #0]"
-			 : "=&r" (ctl), "=&r" (val)
-			 : "r" (container)
-			 : "memory");
-
-	__asm__ volatile("mrs	%x0, cntp_tval_el0\n\t"
-			 "mrs	%x1, cntp_ctl_el0\n\t"
-			 "stp	%x0, %x1, [%2, #16]"
-			 : "=&r" (val), "=&r" (ctl)
-			 : "r" (container)
-			 : "memory");
-
-	__asm__ volatile("mrs	%x0, cntv_tval_el0\n\t"
-			 "mrs	%x1, cntv_ctl_el0\n\t"
-			 "stp	%x0, %x1, [%2, #32]"
-			 : "=&r" (val), "=&r" (ctl)
-			 : "r" (container)
-			 : "memory");
-}
-
-static void mt_restore_generic_timer(unsigned long *container)
-{
-	uint64_t ctl;
-	uint64_t val;
-
-	__asm__ volatile("ldp	%x0, %x1, [%2, #0]\n\t"
-			 "msr	cntkctl_el1, %x0\n\t"
-			 "msr	cntp_cval_el0, %x1"
-			 : "=&r" (ctl), "=&r" (val)
-			 : "r" (container)
-			 : "memory");
-
-	__asm__ volatile("ldp	%x0, %x1, [%2, #16]\n\t"
-			 "msr	cntp_tval_el0, %x0\n\t"
-			 "msr	cntp_ctl_el0, %x1"
-			 : "=&r" (val), "=&r" (ctl)
-			 : "r" (container)
-			 : "memory");
-
-	__asm__ volatile("ldp	%x0, %x1, [%2, #32]\n\t"
-			 "msr	cntv_tval_el0, %x0\n\t"
-			 "msr	cntv_ctl_el0, %x1"
-			 : "=&r" (val), "=&r" (ctl)
-			 : "r" (container)
-			 : "memory");
-}
-
-static void stop_generic_timer(void)
-{
-	/*
-	 * Disable the timer and mask the irq to prevent
-	 * suprious interrupts on this cpu interface. It
-	 * will bite us when we come back if we don't. It
-	 * will be replayed on the inbound cluster.
-	 */
-	uint64_t cntpctl = read_cntp_ctl_el0();
-
-	write_cntp_ctl_el0(clr_cntp_ctl_enable(cntpctl));
-}
-
-static void mt_cpu_save(unsigned long mpidr)
-{
-	struct core_context *core;
-
-	core = get_core_data(mpidr);
-	mt_save_generic_timer(core->timer_data);
-
-	/* disable timer irq, and upper layer should enable it again. */
-	stop_generic_timer();
-}
-
-static void mt_cpu_restore(unsigned long mpidr)
-{
-	struct core_context *core;
-
-	core = get_core_data(mpidr);
-	mt_restore_generic_timer(core->timer_data);
-}
-
-static void mt_platform_save_context(unsigned long mpidr)
-{
-	/* mcusys_save_context: */
-	mt_cpu_save(mpidr);
-}
-
-static void mt_platform_restore_context(unsigned long mpidr)
-{
-	/* mcusys_restore_context: */
-	mt_cpu_restore(mpidr);
-}
-
-/*******************************************************************************
-* Private function which is used to determine if any platform actions
-* should be performed for the specified affinity instance given its
-* state. Nothing needs to be done if the 'state' is not off or if this is not
-* the highest affinity level which will enter the 'state'.
-*******************************************************************************/
-static int32_t plat_do_plat_actions(unsigned int afflvl, unsigned int state)
-{
-	unsigned int max_phys_off_afflvl;
-
-	assert(afflvl <= MPIDR_AFFLVL2);
-
-	if (state != PSCI_STATE_OFF)
-		return -EAGAIN;
-
-	/*
-	 * Find the highest affinity level which will be suspended and postpone
-	 * all the platform specific actions until that level is hit.
-	 */
-	max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
-	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
-	if (afflvl != max_phys_off_afflvl)
-		return -EAGAIN;
-
-	return 0;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to enter
- * standby.
- ******************************************************************************/
-static void plat_affinst_standby(unsigned int power_state)
-{
-	unsigned int target_afflvl;
-
-	/* Sanity check the requested state */
-	target_afflvl = psci_get_pstate_afflvl(power_state);
-
-	/*
-	 * It's possible to enter standby only on affinity level 0 i.e. a cpu
-	 * on the MTK_platform. Ignore any other affinity level.
-	 */
-	if (target_afflvl == MPIDR_AFFLVL0) {
-		/*
-		 * Enter standby state. dsb is good practice before using wfi
-		 * to enter low power states.
-		 */
-		dsb();
-		wfi();
-	}
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * on. The level and mpidr determine the affinity instance.
- ******************************************************************************/
-static int plat_affinst_on(unsigned long mpidr,
-		    unsigned long sec_entrypoint,
-		    unsigned int afflvl,
-		    unsigned int state)
-{
-	int rc = PSCI_E_SUCCESS;
-	unsigned long cpu_id;
-	unsigned long cluster_id;
-	uintptr_t rv;
-
-	/*
-	 * It's possible to turn on only affinity level 0 i.e. a cpu
-	 * on the MTK_platform. Ignore any other affinity level.
-	 */
-	if (afflvl != MPIDR_AFFLVL0)
-		return rc;
-
-	cpu_id = mpidr & MPIDR_CPU_MASK;
-	cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
-	if (cluster_id)
-		rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
-	else
-		rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
-	mmio_write_32(rv, sec_entrypoint);
-	INFO("mt_on[%ld:%ld], entry %x\n",
-		cluster_id, cpu_id, mmio_read_32(rv));
-
-	return rc;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * off. The level and mpidr determine the affinity instance. The 'state' arg.
- * allows the platform to decide whether the cluster is being turned off and
- * take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_off(unsigned int afflvl, unsigned int state)
-{
-	unsigned long mpidr = read_mpidr_el1();
-
-	/* Determine if any platform actions need to be executed. */
-	if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
-		return;
-
-	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_mt_gic_cpuif_disable();
-
-	trace_power_flow(mpidr, CPU_DOWN);
-
-	if (afflvl != MPIDR_AFFLVL0) {
-		/* Disable coherency if this cluster is to be turned off */
-		plat_cci_disable();
-
-		trace_power_flow(mpidr, CLUSTER_DOWN);
-	}
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be
- * suspended. The level and mpidr determine the affinity instance. The 'state'
- * arg. allows the platform to decide whether the cluster is being turned off
- * and take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_suspend(unsigned long sec_entrypoint,
-			  unsigned int afflvl,
-			  unsigned int state)
-{
-	unsigned long mpidr = read_mpidr_el1();
-	unsigned long cluster_id;
-	unsigned long cpu_id;
-	uintptr_t rv;
-
-	/* Determine if any platform actions need to be executed. */
-	if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
-		return;
-
-	cpu_id = mpidr & MPIDR_CPU_MASK;
-	cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
-	if (cluster_id)
-		rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
-	else
-		rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
-	mmio_write_32(rv, sec_entrypoint);
-
-	if (afflvl >= MPIDR_AFFLVL0)
-		mt_platform_save_context(mpidr);
-
-	/* Perform the common cluster specific operations */
-	if (afflvl >= MPIDR_AFFLVL1) {
-		/* Disable coherency if this cluster is to be turned off */
-		plat_cci_disable();
-		disable_scu(mpidr);
-
-		trace_power_flow(mpidr, CLUSTER_SUSPEND);
-	}
-
-	if (afflvl >= MPIDR_AFFLVL2) {
-		/* Prevent interrupts from spuriously waking up this cpu */
-		plat_mt_gic_cpuif_disable();
-	}
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after being turned off earlier. The level and mpidr determine the affinity
- * instance. The 'state' arg. allows the platform to decide whether the cluster
- * was turned off prior to wakeup and do what's necessary to setup it up
- * correctly.
- ******************************************************************************/
-static void plat_affinst_on_finish(unsigned int afflvl, unsigned int state)
-{
-	unsigned long mpidr = read_mpidr_el1();
-
-	/* Determine if any platform actions need to be executed. */
-	if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
-		return;
-
-	/* Perform the common cluster specific operations */
-	if (afflvl >= MPIDR_AFFLVL1) {
-		enable_scu(mpidr);
-
-		/* Enable coherency if this cluster was off */
-		plat_cci_enable();
-		trace_power_flow(mpidr, CLUSTER_UP);
-	}
-
-	/* Enable the gic cpu interface */
-	plat_mt_gic_cpuif_enable();
-	plat_mt_gic_pcpu_init();
-	trace_power_flow(mpidr, CPU_UP);
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after having been suspended earlier. The level and mpidr determine the
- * affinity instance.
- ******************************************************************************/
-static void plat_affinst_suspend_finish(unsigned int afflvl, unsigned int state)
-{
-	unsigned long mpidr = read_mpidr_el1();
-
-	/* Determine if any platform actions need to be executed. */
-	if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
-		return;
-
-	if (afflvl >= MPIDR_AFFLVL2) {
-		/* Enable the gic cpu interface */
-		plat_mt_gic_init();
-		plat_mt_gic_cpuif_enable();
-	}
-
-	/* Perform the common cluster specific operations */
-	if (afflvl >= MPIDR_AFFLVL1) {
-		enable_scu(mpidr);
-
-		/* Enable coherency if this cluster was off */
-		plat_cci_enable();
-		trace_power_flow(mpidr, CLUSTER_UP);
-	}
-
-	if (afflvl >= MPIDR_AFFLVL0)
-		mt_platform_restore_context(mpidr);
-
-	plat_mt_gic_pcpu_init();
-}
-
-static unsigned int plat_get_sys_suspend_power_state(void)
-{
-	/* StateID: 0, StateType: 1(power down), PowerLevel: 2(system) */
-	return psci_make_powerstate(0, 1, 2);
-}
-
-/*******************************************************************************
- * MTK handlers to shutdown/reboot the system
- ******************************************************************************/
-static void __dead2 plat_system_off(void)
-{
-	INFO("MTK System Off\n");
-	wfi();
-	ERROR("MTK System Off: operation not handled.\n");
-	panic();
-}
-
-static void __dead2 plat_system_reset(void)
-{
-	/* Write the System Configuration Control Register */
-	INFO("MTK System Reset\n");
-
-	mmio_clrbits_32(MTK_WDT_BASE,
-		(MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ));
-	mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
-	mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
-
-	wfi();
-	ERROR("MTK System Reset: operation not handled.\n");
-	panic();
-}
-
-/*******************************************************************************
- * Export the platform handlers to enable psci to invoke them
- ******************************************************************************/
-static const plat_pm_ops_t plat_plat_pm_ops = {
-	.affinst_standby		= plat_affinst_standby,
-	.affinst_on			= plat_affinst_on,
-	.affinst_off			= plat_affinst_off,
-	.affinst_suspend		= plat_affinst_suspend,
-	.affinst_on_finish		= plat_affinst_on_finish,
-	.affinst_suspend_finish		= plat_affinst_suspend_finish,
-	.system_off			= plat_system_off,
-	.system_reset			= plat_system_reset,
-	.get_sys_suspend_power_state	= plat_get_sys_suspend_power_state,
-};
-
-/*******************************************************************************
- * Export the platform specific power ops & initialize the mtk_platform power
- * controller
- ******************************************************************************/
-int platform_setup_pm(const plat_pm_ops_t **plat_ops)
-{
-	*plat_ops = &plat_plat_pm_ops;
-	return 0;
-}
diff --git a/plat/mediatek/mt6795/plat_topology.c b/plat/mediatek/mt6795/plat_topology.c
deleted file mode 100644
index 7425d26..0000000
--- a/plat/mediatek/mt6795/plat_topology.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <lib/psci/psci.h>
-
-unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
-{
-	/* Report 1 (absent) instance at levels higher that the cluster level */
-	if (aff_lvl > MPIDR_AFFLVL1)
-		return PLATFORM_SYSTEM_COUNT;
-
-	if (aff_lvl == MPIDR_AFFLVL1)
-		return PLATFORM_CLUSTER_COUNT;
-
-	return mpidr & 0x100 ? PLATFORM_CLUSTER1_CORE_COUNT :
-			       PLATFORM_CLUSTER0_CORE_COUNT;
-}
-
-unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
-{
-	return aff_lvl <= MPIDR_AFFLVL2 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
-}
-
-int mt_setup_topology(void)
-{
-	/* [TODO] Make topology configurable via SCC */
-	return 0;
-}
diff --git a/plat/mediatek/mt6795/platform.mk b/plat/mediatek/mt6795/platform.mk
deleted file mode 100644
index 4ab692d..0000000
--- a/plat/mediatek/mt6795/platform.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-MTK_PLAT		:=	plat/mediatek
-MTK_PLAT_SOC		:=	${MTK_PLAT}/${PLAT}
-
-# Add OEM customized codes
-OEMS				:= true
-MTK_SIP_KERNEL_BOOT_ENABLE := 1
-
-
-ifneq (${OEMS},none)
-  OEMS_INCLUDES		:= -I${MTK_PLAT}/common/custom/
-  OEMS_SOURCES		:=	${MTK_PLAT}/common/custom/oem_svc.c
-endif
-
-PLAT_INCLUDES		:=	-I${MTK_PLAT}/common/				\
-				-I${MTK_PLAT}/common/drivers/uart			\
-				-I${MTK_PLAT_SOC}/				\
-				-I${MTK_PLAT_SOC}/drivers/timer/			\
-				-I${MTK_PLAT_SOC}/include/					\
-				-Iinclude/plat/arm/common/					\
-				${OEMS_INCLUDES}
-
-PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/aarch64/xlat_tables.c			\
-				lib/xlat_tables/xlat_tables_common.c			\
-				plat/common/plat_gic.c
-
-BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
-				drivers/delay_timer/generic_delay_timer.c	\
-				drivers/arm/gic/common/gic_common.c		\
-				drivers/arm/gic/v2/gicv2_main.c			\
-				drivers/arm/gic/v2/gicv2_helpers.c		\
-				plat/common/plat_gicv2.c			\
-				drivers/console/aarch64/console.S		\
-				drivers/delay_timer/delay_timer.c		\
-				lib/cpus/aarch64/cortex_a53.S			\
-				${MTK_PLAT_SOC}/bl31_plat_setup.c		\
-				${MTK_PLAT_SOC}/plat_mt_gic.c			\
-				${MTK_PLAT}/common/mtk_sip_svc.c		\
-				${MTK_PLAT}/common/mtk_plat_common.c		\
-				${MTK_PLAT}/common/drivers/uart/8250_console.S		\
-				${MTK_PLAT_SOC}/aarch64/plat_helpers.S		\
-				${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c	\
-				${MTK_PLAT_SOC}/plat_delay_timer.c		\
-				${MTK_PLAT_SOC}/plat_pm.c			\
-				${MTK_PLAT_SOC}/plat_topology.c			\
-				${MTK_PLAT_SOC}/power_tracer.c			\
-				${MTK_PLAT_SOC}/scu.c		\
-				${OEMS_SOURCES}
-
-# Enable workarounds for selected Cortex-A53 erratas.
-ERRATA_A53_826319	:=	1
-ERRATA_A53_836870	:=	1
-
-WORKAROUND_CVE_2017_5715	:=	0
-
-# indicate the reset vector address can be programmed
-PROGRAMMABLE_RESET_ADDRESS	:=	1
-
-$(eval $(call add_define,MTK_SIP_KERNEL_BOOT_ENABLE))
-
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:=	0
diff --git a/plat/mediatek/mt6795/power_tracer.c b/plat/mediatek/mt6795/power_tracer.c
deleted file mode 100644
index 64d086d..0000000
--- a/plat/mediatek/mt6795/power_tracer.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <common/debug.h>
-
-#include <power_tracer.h>
-
-#define trace_log(...)  INFO("psci: " __VA_ARGS__)
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode)
-{
-	switch (mode) {
-	case CPU_UP:
-		trace_log("core %lld:%lld ON\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
-			  (mpidr & MPIDR_CPU_MASK));
-		break;
-	case CPU_DOWN:
-		trace_log("core %lld:%lld OFF\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
-			  (mpidr & MPIDR_CPU_MASK));
-		break;
-	case CPU_SUSPEND:
-		trace_log("core %lld:%lld SUSPEND\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
-			  (mpidr & MPIDR_CPU_MASK));
-		break;
-	case CLUSTER_UP:
-		trace_log("cluster %lld ON\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
-		break;
-	case CLUSTER_DOWN:
-		trace_log("cluster %lld OFF\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
-		break;
-	case CLUSTER_SUSPEND:
-		trace_log("cluster %lld SUSPEND\n",
-			  (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
-		break;
-	default:
-		trace_log("unknown power mode\n");
-		break;
-	}
-}
diff --git a/plat/mediatek/mt6795/scu.c b/plat/mediatek/mt6795/scu.c
deleted file mode 100644
index 3b74527..0000000
--- a/plat/mediatek/mt6795/scu.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <lib/mmio.h>
-
-#include <mcucfg.h>
-
-void disable_scu(unsigned long mpidr)
-{
-	if (mpidr & MPIDR_CLUSTER_MASK)
-		mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
-			MP1_ACINACTM);
-	else
-		mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
-			MP0_ACINACTM);
-}
-
-void enable_scu(unsigned long mpidr)
-{
-	if (mpidr & MPIDR_CLUSTER_MASK)
-		mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
-			MP1_ACINACTM);
-	else
-		mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
-			MP0_ACINACTM);
-}
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 47ec791..0c184f4 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <common/bl_common.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
+#include <plat/common/platform.h>
 #include "qemu_private.h"
 
 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
@@ -160,4 +161,9 @@
 DEFINE_CONFIGURE_MMU_EL(svc_mon)
 #endif
 
-
+#if MEASURED_BOOT || TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 4dc62f5..c313cb6 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,4 +34,18 @@
 void qemu_pwr_gic_on_finish(void);
 void qemu_pwr_gic_off(void);
 
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+			size_t log_size);
+
+int qemu_set_nt_fw_info(
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this option should be removed when feature is supported.
+ */
+#ifdef SPD_opteed
+			uintptr_t log_addr,
+#endif
+			size_t log_size,
+			uintptr_t *ns_log_addr);
+
 #endif /* QEMU_PRIVATE_H */
diff --git a/plat/qemu/common/qemu_trusted_boot.c b/plat/qemu/common/qemu_trusted_boot.c
index 1ef7e43..6a8edca 100644
--- a/plat/qemu/common/qemu_trusted_boot.c
+++ b/plat/qemu/common/qemu_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,8 +29,3 @@
 {
 	return 1;
 }
-
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
-	return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index c02eff9..78467c4 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -270,4 +270,9 @@
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
 
+/*
+ * Maximum size of Event Log buffer used in Measured Boot Event Log driver
+ */
+#define	PLAT_EVENT_LOG_MAX_SIZE		UL(0x400)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index a8f978a..6a877c3 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -57,11 +57,7 @@
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
-    include drivers/auth/mbedtls/mbedtls_crypto.mk
-    include drivers/auth/mbedtls/mbedtls_x509.mk
-
     AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
-				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
 				drivers/auth/tbbr/tbbr_cot_common.c
 
@@ -78,6 +74,8 @@
 				$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S	\
 				drivers/auth/tbbr/tbbr_cot_bl2.c
 
+    include drivers/auth/mbedtls/mbedtls_x509.mk
+
     ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
     ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
@@ -98,6 +96,34 @@
 	openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
+# Include Measured Boot makefile before any Crypto library makefile.
+# Crypto library makefile may need default definitions of Measured Boot build
+# flags present in Measured Boot makefile.
+ifeq (${MEASURED_BOOT},1)
+    MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
+    $(info Including ${MEASURED_BOOT_MK})
+    include ${MEASURED_BOOT_MK}
+
+    BL2_SOURCES		+=	plat/qemu/qemu/qemu_measured_boot.c	\
+				plat/qemu/qemu/qemu_common_measured_boot.c	\
+				plat/qemu/qemu/qemu_helpers.c		\
+				${EVENT_LOG_SOURCES}
+
+     BL1_SOURCES	+=      plat/qemu/qemu/qemu_bl1_measured_boot.c
+
+endif
+
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT}),)
+    CRYPTO_SOURCES	:=	drivers/auth/crypto_mod.c
+
+    BL1_SOURCES		+=	${CRYPTO_SOURCES}
+    BL2_SOURCES		+=	${CRYPTO_SOURCES}
+
+    # We expect to locate the *.mk files under the directories specified below
+    #
+    include drivers/auth/mbedtls/mbedtls_crypto.mk
+endif
+
 BL1_SOURCES		+=	drivers/io/io_semihosting.c		\
 				drivers/io/io_storage.c			\
 				drivers/io/io_fip.c			\
@@ -131,6 +157,7 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
 				common/fdt_fixup.c					\
+				common/fdt_wrappers.c					\
 				common/desc_image_load.c
 
 ifeq ($(add-lib-optee),yes)
diff --git a/plat/qemu/qemu/qemu_bl1_measured_boot.c b/plat/qemu/qemu/qemu_bl1_measured_boot.c
new file mode 100644
index 0000000..3d20f97
--- /dev/null
+++ b/plat/qemu/qemu/qemu_bl1_measured_boot.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <common/desc_image_load.h>
+
+/*
+ * Add dummy functions for measured boot for BL1.
+ * In most of the SoC's, ROM/BL1 code is pre-built. So we are assumimg that
+ * it doesn't have the capability to do measurements and extend eventlog.
+ * hence these are dummy functions.
+ */
+void bl1_plat_mboot_init(void)
+{
+}
+
+void bl1_plat_mboot_finish(void)
+{
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	return 0;
+}
diff --git a/plat/qemu/qemu/qemu_common_measured_boot.c b/plat/qemu/qemu/qemu_common_measured_boot.c
new file mode 100644
index 0000000..41f7f87
--- /dev/null
+++ b/plat/qemu/qemu/qemu_common_measured_boot.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/platform.h>
+
+extern event_log_metadata_t qemu_event_log_metadata[];
+
+const event_log_metadata_t *plat_event_log_get_metadata(void)
+{
+	return qemu_event_log_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	/* Calculate image hash and record data in Event Log */
+	int err = event_log_measure_and_record(image_data->image_base,
+					       image_data->image_size,
+					       image_id);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record", image_id, err);
+		return err;
+	}
+
+	return 0;
+}
diff --git a/plat/qemu/qemu/qemu_helpers.c b/plat/qemu/qemu/qemu_helpers.c
new file mode 100644
index 0000000..01b8249
--- /dev/null
+++ b/plat/qemu/qemu/qemu_helpers.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#if MEASURED_BOOT
+#include <common/desc_image_load.h>
+#endif
+#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+
+#ifdef SPD_opteed
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this property should be removed when this feature is supported.
+ */
+#define DTB_PROP_HW_SM_LOG_ADDR	"tpm_event_log_sm_addr"
+#endif
+
+#define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE    "tpm_event_log_size"
+
+#if MEASURED_BOOT
+
+#ifdef SPD_opteed
+int qemu_set_tee_fw_info(uintptr_t config_base, uintptr_t log_addr,
+			 size_t log_size)
+{
+	int offs, err = 0;
+	void *dtb = (void *)config_base;
+	const char *compatible = "arm,tpm_event_log";
+	uint64_t sec_base = cpu_to_fdt64(log_addr);
+	uint32_t sz = cpu_to_fdt32(log_size);
+
+	offs = fdtw_find_or_add_subnode(dtb, 0, "tpm-event-log");
+	if (offs < 0) {
+		ERROR("Failed to add node tpm-event-log %d\n", offs);
+		return offs;
+	}
+
+	if (fdt_appendprop(dtb, offs, "compatible", compatible,
+			   strlen(compatible) + 1) < 0) {
+		return -1;
+	}
+
+	err = fdt_setprop(dtb, offs, DTB_PROP_HW_SM_LOG_ADDR, &sec_base, 8);
+	if (err < 0) {
+		ERROR("Failed to add log addr err %d\n", err);
+		return err;
+	}
+
+	err = fdt_setprop(dtb, offs, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+	if (err < 0) {
+		ERROR("Failed to add log addr err %d\n", err);
+		return err;
+	}
+
+	return err;
+}
+#endif
+
+/*
+ * Write the Event Log address and its size in the DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+static int qemu_set_event_log_info(uintptr_t config_base,
+#ifdef SPD_opteed
+				  uintptr_t sm_log_addr,
+#endif
+				  uintptr_t log_addr, size_t log_size)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	void *dtb = (void *)config_base;
+	const char *compatible_tpm = "tcg,tpm-tis-mmio";
+	uint64_t base = cpu_to_fdt64(log_addr);
+	uint32_t sz = cpu_to_fdt32(log_size);
+	int err, node;
+
+	err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
+	if (err < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+		return err;
+	}
+
+	/*
+	 * Verify that the DTB is valid, before attempting to write to it,
+	 * and get the DTB root node.
+	 */
+
+	/* Check if the pointer to DT is correct */
+	err = fdt_check_header(dtb);
+	if (err < 0) {
+		WARN("Invalid DTB file passed\n");
+		return err;
+	}
+
+	/*
+	 * Find the TPM node in device tree. On qemu, we assume it will
+	 * be sw-tpm.
+	 */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_tpm);
+	if (node < 0) {
+		ERROR("The compatible property '%s' not%s", compatible_tpm,
+			" found in the config\n");
+		return node;
+	}
+
+	err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_ADDR, &base, 8);
+	if (err < 0) {
+		ERROR("Failed to add log addr err %d\n", err);
+		return err;
+	}
+
+	err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+	if (err < 0) {
+		ERROR("Failed to add log addr err %d\n", err);
+		return err;
+	}
+
+#ifdef SPD_opteed
+	err = qemu_set_tee_fw_info(config_base, sm_log_addr, log_size);
+	if (err < 0) {
+		ERROR("Failed to add tpm-event-node at %p: err %d\n", dtb, err);
+		return err;
+	}
+#endif
+
+	err = fdt_pack(dtb);
+	if (err < 0) {
+		ERROR("Failed to pack Device Tree at %p: err %d\n", dtb, err);
+		return err;
+	}
+
+	/*
+	 * Ensure that the info written to the DTB is visible
+	 * to other images.
+	 */
+	flush_dcache_range(config_base, fdt_totalsize(dtb));
+
+	return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the TOS_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+			size_t log_size)
+{
+	int err = 0;
+
+	assert(config_base != 0UL);
+	assert(log_addr != 0UL);
+
+	/*
+	 * FIXME - add code to add/update Log address and it's
+	 * size in TOS FW CONFIG.
+	 * For now we don't have support for TOS FW config in OP-TEE.
+	 * So leave this function blank
+	 */
+
+	return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the QEMU DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+			uintptr_t log_addr,
+#endif
+			size_t log_size, uintptr_t *ns_log_addr)
+{
+	uintptr_t ns_addr;
+	int err;
+
+	assert(ns_log_addr != NULL);
+
+	ns_addr = PLAT_QEMU_DT_BASE + PLAT_QEMU_DT_MAX_SIZE;
+
+	/* Write the Event Log address and its size in the DTB */
+	err = qemu_set_event_log_info(PLAT_QEMU_DT_BASE,
+#ifdef SPD_opteed
+					log_addr,
+#endif
+					ns_addr, log_size);
+
+	/* Return Event Log address in Non-secure memory */
+	*ns_log_addr = (err < 0) ? 0UL : ns_addr;
+	return err;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
new file mode 100644
index 0000000..d9e475a
--- /dev/null
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/common_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "../common/qemu_private.h"
+
+/* Event Log data */
+static uint8_t event_log[PLAT_EVENT_LOG_MAX_SIZE];
+static uint64_t event_log_base;
+
+/* FVP table with platform specific image IDs, names and PCRs */
+const event_log_metadata_t qemu_event_log_metadata[] = {
+	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+
+	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
+};
+
+void bl2_plat_mboot_init(void)
+{
+	/*
+	 * Here we assume that BL1/ROM code doesn't have the driver
+	 * to measure the BL2 code which is a common case for
+	 * already existing platforms
+	 */
+	event_log_init(event_log, event_log + sizeof(event_log));
+	event_log_write_header();
+
+	/*
+	 * TBD - Add code to do self measurement of BL2 code and add an
+	 * event for BL2 measurement
+	 */
+
+	event_log_base = (uintptr_t)event_log;
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	int rc;
+
+	/* Event Log address in Non-Secure memory */
+	uintptr_t ns_log_addr;
+
+	/* Event Log filled size */
+	size_t event_log_cur_size;
+
+	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
+
+	rc = qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+			    (uintptr_t)event_log_base,
+#endif
+			    event_log_cur_size, &ns_log_addr);
+	if (rc != 0) {
+		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+		      __func__, "NT");
+		/*
+		 * It is a fatal error because on QEMU secure world software
+		 * assumes that a valid event log exists and will use it to
+		 * record the measurements into the fTPM or sw-tpm.
+		 * Note: In QEMU platform, OP-TEE uses nt_fw_config to get the
+		 * secure Event Log buffer address.
+		 */
+		panic();
+	}
+
+	/* Copy Event Log to Non-secure memory */
+	(void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
+		     event_log_cur_size);
+
+	/* Ensure that the Event Log is visible in Non-secure memory */
+	flush_dcache_range(ns_log_addr, event_log_cur_size);
+
+#if defined(SPD_tspd) || defined(SPD_spmd)
+	/* Set Event Log data in TOS_FW_CONFIG */
+	rc = qemu_set_tos_fw_info((uintptr_t)event_log_base,
+				 event_log_cur_size);
+	if (rc != 0) {
+		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+		      __func__, "TOS");
+		panic();
+	}
+#endif /* defined(SPD_tspd) || defined(SPD_spmd) */
+
+	dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
+}
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index e129dfd..7cd5eb5 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -409,6 +409,7 @@
 			gpt_init_done = true;
 		} else {
 			bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+			assert(bl_mem_params != NULL);
 
 			mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
 			mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
@@ -485,22 +486,46 @@
 
 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
 /*
- * Eventually, this function will return the
- * boot index to be passed on to the Update
- * Agent after performing certain checks like
- * a watchdog timeout, or Auth failure while
- * trying to load from a certain bank.
- * For now, since we do not have that logic
- * implemented, just pass the active_index
- * read from the metadata.
+ * In each boot in non-trial mode, we set the BKP register to
+ * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
+ *
+ * As long as the update agent didn't update the "accepted" field in metadata
+ * (i.e. we are in trial mode), we select the new active_index.
+ * To avoid infinite boot loop at trial boot we decrement a BKP register.
+ * If this counter is 0:
+ *     - an unexpected TAMPER event raised (that resets the BKP registers to 0)
+ *     - a power-off occurs before the update agent was able to update the
+ *       "accepted' field
+ *     - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
+ * we select the previous_active_index.
  */
+#define INVALID_BOOT_IDX		0xFFFFFFFF
+
 uint32_t plat_fwu_get_boot_idx(void)
 {
-	const struct fwu_metadata *metadata;
+	/*
+	 * Select boot index and update boot counter only once per boot
+	 * even if this function is called several times.
+	 */
+	static uint32_t boot_idx = INVALID_BOOT_IDX;
+	const struct fwu_metadata *data;
 
-	metadata = fwu_get_metadata();
+	data = fwu_get_metadata();
+
+	if (boot_idx == INVALID_BOOT_IDX) {
+		boot_idx = data->active_index;
+		if (fwu_is_trial_run_state()) {
+			if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
+				WARN("Trial FWU fails %u times\n",
+				     FWU_MAX_TRIAL_REBOOT);
+				boot_idx = data->previous_active_index;
+			}
+		} else {
+			stm32_set_max_fwu_trial_boot_cnt();
+		}
+	}
 
-	return metadata->active_index;
+	return boot_idx;
 }
 
 static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index d8d1c13..0010cd8 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -129,6 +129,8 @@
 
 #if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void);
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
+void stm32_set_max_fwu_trial_boot_cnt(void);
 #endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
 
 #endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index ea71571..c9efeb5 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -11,8 +11,6 @@
 #include <common/fdt_wrappers.h>
 #include <drivers/st/regulator.h>
 #include <drivers/st/stm32_gpio.h>
-#include <drivers/st/stm32mp1_ddr.h>
-#include <drivers/st/stm32mp1_ram.h>
 #include <libfdt.h>
 
 #include <platform_def.h>
@@ -328,48 +326,32 @@
 int dt_find_otp_name(const char *name, uint32_t *otp, uint32_t *otp_len)
 {
 	int node;
-	int index, len;
+	int len;
 	const fdt32_t *cuint;
 
 	if ((name == NULL) || (otp == NULL)) {
 		return -FDT_ERR_BADVALUE;
 	}
 
-	node = fdt_node_offset_by_compatible(fdt, -1, DT_NVMEM_LAYOUT_COMPAT);
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
 	if (node < 0) {
 		return node;
 	}
 
-	index = fdt_stringlist_search(fdt, node, "nvmem-cell-names", name);
-	if (index < 0) {
-		return index;
-	}
-
-	cuint = fdt_getprop(fdt, node, "nvmem-cells", &len);
-	if (cuint == NULL) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	if ((index * (int)sizeof(uint32_t)) > len) {
-		return -FDT_ERR_BADVALUE;
-	}
-
-	cuint += index;
-
-	node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	node = fdt_subnode_offset(fdt, node, name);
 	if (node < 0) {
-		ERROR("Malformed nvmem_layout node: ignored\n");
+		ERROR("nvmem node %s not found\n", name);
 		return node;
 	}
 
 	cuint = fdt_getprop(fdt, node, "reg", &len);
 	if ((cuint == NULL) || (len != (2 * (int)sizeof(uint32_t)))) {
-		ERROR("Malformed nvmem_layout node: ignored\n");
+		ERROR("Malformed nvmem node %s: ignored\n", name);
 		return -FDT_ERR_BADVALUE;
 	}
 
 	if (fdt32_to_cpu(*cuint) % sizeof(uint32_t)) {
-		ERROR("Misaligned nvmem_layout element: ignored\n");
+		ERROR("Misaligned nvmem %s element: ignored\n", name);
 		return -FDT_ERR_BADVALUE;
 	}
 
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 88d0f8a..6f5fcc7 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -432,7 +432,8 @@
 #if !STM32MP_USE_STM32IMAGE
 	case FW_CONFIG_ID:
 		/* Set global DTB info for fixed fw_config information */
-		set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+		set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
+				FW_CONFIG_ID);
 		fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
 
 		idx = dyn_cfg_dtb_info_get_index(TOS_FW_CONFIG_ID);
@@ -462,12 +463,14 @@
 
 				/* In case of OPTEE, initialize address space with tos_fw addr */
 				pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+				assert(pager_mem_params != NULL);
 				pager_mem_params->image_info.image_base = config_info->config_addr;
 				pager_mem_params->image_info.image_max_size =
 					config_info->config_max_size;
 
 				/* Init base and size for pager if exist */
 				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+				assert(paged_mem_params != NULL);
 				paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
 					(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
 					 STM32MP_DDR_SHMEM_SIZE);
@@ -525,6 +528,7 @@
 #if !STM32MP_USE_STM32IMAGE
 			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
 			tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+			assert(tos_fw_mem_params != NULL);
 			bl_mem_params->image_info.image_max_size +=
 				tos_fw_mem_params->image_info.image_max_size;
 #endif /* !STM32MP_USE_STM32IMAGE */
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 36a3a1c..76af0fc 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
-
 #include <common/desc_image_load.h>
 #include <plat/common/platform.h>
 
+#include <platform_def.h>
+
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
  * in memory for the next BL image.
@@ -27,6 +27,8 @@
 	bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID);
 	uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size();
 
+	assert(bl33 != NULL);
+
 	/* Max size is non-secure DDR end address minus image_base */
 	bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size -
 					  bl33->image_info.image_base;
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index a890534..9e67989 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -146,7 +146,7 @@
 endif
 
 $(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
-$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o [0-9]*)))
+$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
 DTC_CPPFLAGS		+=	${INCLUDES}
 DTC_FLAGS		+=	-Wno-unit_address_vs_reg
 ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index d869978..7e0745a 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -511,6 +511,9 @@
 /* UID OTP */
 #define UID_WORD_NB			U(3)
 
+/* FWU configuration (max supported value is 15) */
+#define FWU_MAX_TRIAL_REBOOT		U(3)
+
 /*******************************************************************************
  * STM32MP1 TAMP
  ******************************************************************************/
@@ -621,7 +624,6 @@
 #define DT_DDR_COMPAT			"st,stm32mp1-ddr"
 #endif
 #define DT_IWDG_COMPAT			"st,stm32mp1-iwdg"
-#define DT_NVMEM_LAYOUT_COMPAT		"st,stm32-nvmem-layout"
 #define DT_PWR_COMPAT			"st,stm32mp1,pwr-reg"
 #if STM32MP13
 #define DT_RCC_CLK_COMPAT		"st,stm32mp13-rcc"
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index a9b9f4c..1617afd 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -46,7 +46,16 @@
 #define TAMP_BOOT_MODE_ITF_MASK		U(0x0000FF00)
 #define TAMP_BOOT_MODE_ITF_SHIFT	8
 
-#define TAMP_BOOT_COUNTER_REG_ID	U(21)
+/*
+ * Backup register to store fwu update information.
+ * It should be writeable only by secure world, but also readable by non secure
+ * (so it should be in Zone 2).
+ */
+#define TAMP_BOOT_FWU_INFO_REG_ID	U(10)
+#define TAMP_BOOT_FWU_INFO_IDX_MSK	U(0xF)
+#define TAMP_BOOT_FWU_INFO_IDX_OFF	U(0)
+#define TAMP_BOOT_FWU_INFO_CNT_MSK	U(0xF0)
+#define TAMP_BOOT_FWU_INFO_CNT_OFF	U(4)
 
 #if defined(IMAGE_BL2)
 #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -732,9 +741,42 @@
 #if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void)
 {
+	clk_enable(RTCAPB);
+	mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
+			   TAMP_BOOT_FWU_INFO_IDX_MSK,
+			   (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
+			   TAMP_BOOT_FWU_INFO_IDX_MSK);
+	clk_disable(RTCAPB);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+	uint32_t try_cnt;
+
+	clk_enable(RTCAPB);
+	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
+		TAMP_BOOT_FWU_INFO_CNT_OFF;
+
+	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+	if (try_cnt != 0U) {
+		mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+				   (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
+	}
+	clk_disable(RTCAPB);
+
+	return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+
 	clk_enable(RTCAPB);
-	mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
-		      plat_fwu_get_boot_idx());
+	mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+			   (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
+			   TAMP_BOOT_FWU_INFO_CNT_MSK);
 	clk_disable(RTCAPB);
 }
 #endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h
index 18b7f42..fd4e5b1 100644
--- a/plat/ti/k3/board/lite/include/board_def.h
+++ b/plat/ti/k3/board/lite/include/board_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,7 @@
  * defined as default for our platform.
  */
 #define SEC_SRAM_BASE			UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE			UL(0x0001c000) /* 112k */
+#define SEC_SRAM_SIZE			UL(0x00020000) /* 128k */
 
 #define PLAT_MAX_OFF_STATE		U(2)
 #define PLAT_MAX_RET_STATE		U(1)
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 2c3313c..2cbfa3d 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -2,7 +2,7 @@
  * Texas Instruments System Control Interface Driver
  *   Based on Linux and U-Boot implementation
  *
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1664,6 +1664,57 @@
 }
 
 /**
+ * ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ *
+ * @proc_id: Processor ID.
+ * @mode: Low power mode to enter.
+ * @core_resume_addr: Address that core should be
+ *		      resumed from after low power transition.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+		       uint8_t mode,
+		       uint64_t core_resume_addr)
+{
+	struct ti_sci_msg_req_enter_sleep req;
+	struct ti_sci_msg_hdr *hdr;
+	struct k3_sec_proxy_msg tx_message;
+	int ret;
+
+	/* Ensure we have sane transfer size */
+	if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) {
+		return -ERANGE;
+	}
+
+	hdr = (struct ti_sci_msg_hdr *)&req;
+	hdr->seq = ++message_sequence;
+	hdr->type = TI_SCI_MSG_ENTER_SLEEP;
+	hdr->host = TI_SCI_HOST_ID;
+	/* Setup with NORESPONSE flag to keep response queue clean */
+	hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+	req.processor_id = proc_id;
+	req.mode = mode;
+	req.core_resume_lo = core_resume_addr & TISCI_ADDR_LOW_MASK;
+	req.core_resume_hi = (core_resume_addr & TISCI_ADDR_HIGH_MASK) >>
+			     TISCI_ADDR_HIGH_SHIFT;
+
+	tx_message.buf = (uint8_t *)&req;
+	tx_message.len = sizeof(req);
+
+	/* Send message */
+	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+	if (ret != 0) {
+		ERROR("Message sending failed (%d)\n", ret);
+		return ret;
+	}
+
+	/* Return without waiting for response */
+	return 0;
+}
+
+/**
  * ti_sci_init() - Basic initialization
  *
  * Return: 0 if all goes well, else appropriate error message
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index c7b09b3..06944a7 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -2,7 +2,7 @@
  * Texas Instruments System Control Interface API
  *   Based on Linux and U-Boot implementation
  *
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -207,6 +207,22 @@
 					 uint32_t status_flags_1_clr_any_wait);
 
 /**
+ * System Low Power Operations
+ *
+ * - ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ *		@proc_id: Processor ID.
+ *		@mode: Low power mode to enter.
+ *		@core_resume_addr: Address that core should be resumed from
+ *				   after low power transition.
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * Returns 0 for successful request, else returns corresponding error message.
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+		       uint8_t mode,
+		       uint64_t core_resume_addr);
+
+/**
  * ti_sci_init() - Basic initialization
  *
  * Return: 0 if all goes good, else appropriate error message.
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 310bf45..d220612 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -5,7 +5,7 @@
  * The system works in a message response protocol
  * See: http://processors.wiki.ti.com/index.php/TISCI for details
  *
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,6 +28,9 @@
 #define TI_SCI_MSG_GET_DEVICE_STATE	0x0201
 #define TI_SCI_MSG_SET_DEVICE_RESETS	0x0202
 
+/* Low Power Mode Requests */
+#define TI_SCI_MSG_ENTER_SLEEP		0x0301
+
 /* Clock requests */
 #define TI_SCI_MSG_SET_CLOCK_STATE	0x0100
 #define TI_SCI_MSG_GET_CLOCK_STATE	0x0101
@@ -706,4 +709,26 @@
 	uint32_t status_flags_1_clr_any_wait;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_enter_sleep - Request for TI_SCI_MSG_ENTER_SLEEP.
+ *
+ * @hdr		    Generic Header
+ * @mode	    Low power mode to enter.
+ * @proc_id	    Processor id to be restored.
+ * @core_resume_lo  Low 32-bits of physical pointer to address for core
+ *		    to begin execution upon resume.
+ * @core_resume_hi  High 32-bits of physical pointer to address for core
+ *		    to begin execution upon resume.
+ *
+ * This message is to be sent after TI_SCI_MSG_PREPARE_SLEEP is sent from OS
+ * and is what actually triggers entry into the specified low power mode.
+ */
+struct ti_sci_msg_req_enter_sleep {
+	struct ti_sci_msg_hdr hdr;
+	uint8_t mode;
+	uint8_t processor_id;
+	uint32_t core_resume_lo;
+	uint32_t core_resume_hi;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index 1932eaa..0199822 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -19,6 +19,11 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
+#if K3_PM_SYSTEM_SUSPEND
+static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+static gicv3_dist_ctx_t dist_ctx;
+#endif
+
 static const interrupt_prop_t k3_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
@@ -88,3 +93,21 @@
 {
 	gicv3_rdistif_init(plat_my_core_pos());
 }
+
+#if K3_PM_SYSTEM_SUSPEND
+void k3_gic_save_context(void)
+{
+	for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		gicv3_rdistif_save(i, &rdist_ctx[i]);
+	}
+	gicv3_distif_save(&dist_ctx);
+}
+
+void k3_gic_restore_context(void)
+{
+	gicv3_distif_init_restore(&dist_ctx);
+	for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		gicv3_rdistif_init_restore(i, &rdist_ctx[i]);
+	}
+}
+#endif
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index 0500740..6febbc6 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,11 +234,50 @@
 	return PSCI_E_SUCCESS;
 }
 
+#if K3_PM_SYSTEM_SUSPEND
+static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	unsigned int core, proc_id;
+
+	core = plat_my_core_pos();
+	proc_id = PLAT_PROC_START_ID + core;
+
+	/* Prevent interrupts from spuriously waking up this cpu */
+	k3_gic_cpuif_disable();
+	k3_gic_save_context();
+
+	k3_pwr_domain_off(target_state);
+
+	ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
+}
+
+static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	k3_gic_restore_context();
+	k3_gic_cpuif_enable();
+}
+
+static void k3_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+
+	/* CPU & cluster off, system in retention */
+	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+	}
+}
+#endif
+
 static const plat_psci_ops_t k3_plat_psci_ops = {
 	.cpu_standby = k3_cpu_standby,
 	.pwr_domain_on = k3_pwr_domain_on,
 	.pwr_domain_off = k3_pwr_domain_off,
 	.pwr_domain_on_finish = k3_pwr_domain_on_finish,
+#if K3_PM_SYSTEM_SUSPEND
+	.pwr_domain_suspend = k3_pwr_domain_suspend,
+	.pwr_domain_suspend_finish = k3_pwr_domain_suspend_finish,
+	.get_sys_suspend_power_state = k3_get_sys_suspend_power_state,
+#endif
 	.system_off = k3_system_off,
 	.system_reset = k3_system_reset,
 	.validate_power_state = k3_validate_power_state,
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index ab7366b..e299c30 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -45,6 +45,10 @@
 K3_USART_BAUD		:=	115200
 $(eval $(call add_define,K3_USART_BAUD))
 
+# Enable system suspend modes
+K3_PM_SYSTEM_SUSPEND	:=	0
+$(eval $(call add_define,K3_PM_SYSTEM_SUSPEND))
+
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 2329a16..2c68a75 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -14,5 +14,7 @@
 void k3_gic_cpuif_enable(void);
 void k3_gic_cpuif_disable(void);
 void k3_gic_pcpu_init(void);
+void k3_gic_save_context(void);
+void k3_gic_restore_context(void);
 
 #endif /* K3_GICV3_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 0b8020b..2f52f38 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -69,8 +69,9 @@
 {
 	int ret = 1;
 
-	if (remote >= ipi_total || local >= ipi_total)
+	if (remote >= ipi_total || local >= ipi_total) {
 		ret = 0;
+	}
 
 	return ret;
 }
@@ -88,12 +89,15 @@
 {
 	int ret = 0;
 
-	if (!is_ipi_mb_within_range(local, remote))
+	if (!is_ipi_mb_within_range(local, remote)) {
 		ret = -EINVAL;
-	else if (IPI_IS_SECURE(local) && !is_secure)
+	} else if (IPI_IS_SECURE(local) && !is_secure) {
 		ret = -EPERM;
-	else if (IPI_IS_SECURE(remote) && !is_secure)
+	} else if (IPI_IS_SECURE(remote) && !is_secure) {
 		ret = -EPERM;
+	} else {
+		/* To fix the misra 15.7 warning */
+	}
 
 	return ret;
 }
@@ -141,11 +145,13 @@
 	uint32_t status;
 
 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
-	if (status & IPI_BIT_MASK(remote))
+	if (status & IPI_BIT_MASK(remote)) {
 		ret |= IPI_MB_STATUS_SEND_PENDING;
+	}
 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
-	if (status & IPI_BIT_MASK(remote))
+	if (status & IPI_BIT_MASK(remote)) {
 		ret |= IPI_MB_STATUS_RECV_PENDING;
+	}
 
 	return ret;
 }
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index f02f41e..b8f88c4 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -123,10 +123,11 @@
 
 	flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
 
-	if (flags == FSBL_FLAGS_ENDIAN_BE)
+	if (flags == FSBL_FLAGS_ENDIAN_BE) {
 		return SPSR_E_BIG;
-	else
+	} else {
 		return SPSR_E_LITTLE;
+	}
 }
 
 /**
@@ -226,30 +227,33 @@
 		if (target_secure == FSBL_FLAGS_SECURE) {
 			image = bl32;
 
-			if (target_estate == FSBL_FLAGS_ESTATE_A32)
+			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
 				bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
-			else
+			} else {
 				bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
 						     DISABLE_ALL_EXCEPTIONS);
+			}
 		} else {
 			image = bl33;
 
 			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
-				if (target_el == FSBL_FLAGS_EL2)
+				if (target_el == FSBL_FLAGS_EL2) {
 					target_el = MODE32_hyp;
-				else
+				} else {
 					target_el = MODE32_sys;
+				}
 
 				bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
 			} else {
-				if (target_el == FSBL_FLAGS_EL2)
+				if (target_el == FSBL_FLAGS_EL2) {
 					target_el = MODE_EL2;
-				else
+				} else {
 					target_el = MODE_EL1;
+				}
 
 				bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
 						     DISABLE_ALL_EXCEPTIONS);
@@ -262,10 +266,11 @@
 			target_el);
 		image->pc = ATFHandoffParams->partition[i].entry_point;
 
-		if (target_endianness == SPSR_E_BIG)
+		if (target_endianness == SPSR_E_BIG) {
 			EP_SET_EE(image->h.attr, EP_EE_BIG);
-		else
+		} else {
 			EP_SET_EE(image->h.attr, EP_EE_LITTLE);
+		}
 	}
 
 	return FSBL_HANDOFF_SUCCESS;
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 03a7278..1d1ba85 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -154,14 +154,16 @@
 		value++;
 	}
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
 		response_payload[j] = mmio_read_32(buffer_base +
 						(j * PAYLOAD_ARG_SIZE));
+	}
 
 	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
 		NOTICE("ERROR in CRC response payload value:0x%x\n",
 					response_payload[PAYLOAD_CRC_POS]);
+	}
 #endif
 
 	return mmio_read_32(buffer_base);
@@ -186,22 +188,25 @@
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
 				IPI_BUFFER_REQ_OFFSET;
 
-	if (count > IPI_BUFFER_MAX_WORDS)
+	if (count > IPI_BUFFER_MAX_WORDS) {
 		count = IPI_BUFFER_MAX_WORDS;
+	}
 
 	for (i = 0; i <= count; i++) {
 		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 		value++;
 	}
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
 		response_payload[j] = mmio_read_32(buffer_base +
 						(j * PAYLOAD_ARG_SIZE));
+	}
 
 	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
 		NOTICE("ERROR in CRC response payload value:0x%x\n",
 					response_payload[PAYLOAD_CRC_POS]);
+	}
 #endif
 }
 
@@ -226,8 +231,9 @@
 	bakery_lock_get(&pm_secure_lock);
 
 	ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
-	if (ret != PM_RET_SUCCESS)
+	if (ret != PM_RET_SUCCESS) {
 		goto unlock;
+	}
 
 	ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
 
@@ -253,14 +259,15 @@
 
 	ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
 				    proc->ipi->remote_ipi_id);
-	if (ret & IPI_MB_STATUS_RECV_PENDING)
+	if (ret & IPI_MB_STATUS_RECV_PENDING) {
 		return 1;
-	else
+	} else {
 		return 0;
+	}
 }
 
 #if IPI_CRC_CHECK
-uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize)
+uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t bufsize)
 {
 	uint32_t crcinit = CRC_INIT_VALUE;
 	uint32_t order   = CRC_ORDER;
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 9372954..731742d 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,8 @@
 
 /* List all supported platforms */
 #define VERSAL_PLATFORM_ID_versal_virt	1
+#define VERSAL_PLATFORM_ID_spp_itr6	2
+#define VERSAL_PLATFORM_ID_emu_itr6	3
 #define VERSAL_PLATFORM_ID_silicon	4
 
 #define VERSAL_PLATFORM_IS(con)	(VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
@@ -92,6 +94,16 @@
 # define VERSAL_UART_CLOCK	100000000
 # define VERSAL_UART_BAUDRATE	115200
 # define VERSAL_CPU_CLOCK	100000000
+#elif VERSAL_PLATFORM_IS(spp_itr6)
+# define PLATFORM_NAME          "SPP ITR6"
+# define VERSAL_UART_CLOCK      25000000
+# define VERSAL_UART_BAUDRATE   115200
+# define VERSAL_CPU_CLOCK       2720000
+#elif VERSAL_PLATFORM_IS(emu_itr6)
+# define PLATFORM_NAME          "EMU ITR6"
+# define VERSAL_UART_CLOCK      212000
+# define VERSAL_UART_BAUDRATE   9600
+# define VERSAL_CPU_CLOCK       212000
 #endif
 
 /* Access control register defines */
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 534d910..c7b6047 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,8 @@
 #define LOADER_MODULE_ID	0x7U
 
 #define  MODE	0x80000000U
+#define MODULE_ID_MASK		0x0000ff00
+
 /* default shutdown/reboot scope is system(2) */
 static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
 
@@ -73,38 +75,29 @@
 /* PM API functions */
 
 /**
- * pm_get_api_version() - Get version number of PMC PM firmware
- * @version	Returns 32-bit version number of PMC Power Management Firmware
+ * pm_handle_eemi_call() - PM call for processor to send eemi payload
  * @flag	0 - Call from secure source
  *		1 - Call from non-secure source
+ * @x0 to x5	Arguments received per SMC64 standard
+ * @result	Payload received from firmware
  *
- * @return	Returns status, either success or error+reason
+ * @return	 PM_RET_SUCCESS on success or error code
  */
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+				       uint32_t x2, uint32_t x3, uint32_t x4,
+				       uint32_t x5, uint64_t *result)
 {
-	uint32_t payload[PAYLOAD_ARG_CNT];
+	uint32_t payload[PAYLOAD_ARG_CNT] = {0};
+	uint32_t module_id;
 
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
-	return pm_ipi_send_sync(primary_proc, payload, version, 1);
-}
+	module_id = (x0 & MODULE_ID_MASK) >> 8;
 
-/**
- * pm_init_finalize() - Call to notify PMC PM firmware that master has power
- *			management enabled and that it has finished its
- *			initialization
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Status returned by the PMU firmware
- */
-enum pm_ret_status pm_init_finalize(uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
+	//default module id is for LIBPM
+	if (module_id == 0)
+		module_id = LIBPM_MODULE_ID;
 
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
+	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
 }
 
 /**
@@ -235,134 +228,6 @@
 }
 
 /**
- * pm_request_device() - Request a device
- * @device_id		Device ID
- * @capabilities	Requested capabilities for the device
- * @qos			Required Quality of Service
- * @ack			Flag to specify whether acknowledge requested
- * @flag		0 - Call from secure source
- *			1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
-				     uint32_t qos, uint32_t ack, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
-			 device_id, capabilities, qos, ack);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_release_device() - Release a device
- * @device_id		Device ID
- * @flag		0 - Call from secure source
- *			1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
-			 device_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_set_requirement() - Set requirement for the device
- * @device_id		Device ID
- * @capabilities	Requested capabilities for the device
- * @latency		Requested maximum latency
- * @qos			Required Quality of Service
- * @flag		0 - Call from secure source
- *			1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
-				      uint32_t latency, uint32_t qos,
-				      uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
-			 device_id, capabilities, latency, qos);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_get_device_status() - Get device's status
- * @device_id		Device ID
- * @response		Buffer to store device status response
- * @flag		0 - Call from secure source
- *			1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
-					uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
-			 device_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, response, 3);
-}
-
-/**
- * pm_reset_assert() - Assert/De-assert reset
- * @reset	Reset ID
- * @assert	Assert (1) or de-assert (0)
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
-			 assert);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_reset_get_status() - Get current status of a reset line
- * @reset	Reset ID
- * @status	Returns current status of selected reset ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
-				       uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
-			 reset);
-
-	return pm_ipi_send_sync(primary_proc, payload, status, 1);
-}
-
-/**
  * pm_get_callbackdata() - Read from IPI response buffer
  * @data - array of PAYLOAD_ARG_CNT elements
  * @flag - 0 - Call from secure source
@@ -382,294 +247,12 @@
 }
 
 /**
- * pm_pinctrl_request() - Request a pin
- * @pin		Pin ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
-			 pin);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_release() - Release a pin
- * @pin		Pin ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
-			 pin);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_set_function() - Set pin function
- * @pin		Pin ID
- * @function	Function ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
-					   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
-			 PM_PINCTRL_SET_FUNCTION, pin, function)
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_function() - Get function set on the pin
- * @pin		Pin ID
- * @function	Function set on the pin
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
-					   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
-			 PM_PINCTRL_SET_FUNCTION, pin);
-
-	return pm_ipi_send_sync(primary_proc, payload, function, 1);
-}
-
-/**
- * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
- * @pin		Pin ID
- * @param	Parameter ID
- * @value	Parameter value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
-					    uint32_t value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
-			 PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
- * @pin		Pin ID
- * @param	Parameter ID
- * @value	Buffer to store parameter value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
-					    uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
-			 PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_clock_enable() - Enable the clock
- * @clk_id	Clock ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_disable() - Disable the clock
- * @clk_id	Clock ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_state() - Get clock status
- * @clk_id	Clock ID
- * @state:	Buffer to store clock status (1: Enabled, 0:Disabled)
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
-				      uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, state, 1);
-}
-
-/**
- * pm_clock_set_divider() - Set divider for the clock
- * @clk_id	Clock ID
- * @divider	Divider value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
-					uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
-			 clk_id, divider);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_divider() - Get divider value for the clock
- * @clk_id	Clock ID
- * @divider:	Buffer to store clock divider value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
-					uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, divider, 1);
-}
-
-/**
- * pm_clock_set_parent() - Set parent for the clock
- * @clk_id	Clock ID
- * @parent	Parent ID
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
-				       uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
-			 clk_id, parent);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_parent() - Get parent value for the clock
- * @clk_id	Clock ID
- * @parent:	Buffer to store clock parent value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * pm_pll_set_param() - Set PLL parameter
  *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
-				       uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, parent, 1);
-}
-/**
- * pm_clock_get_rate() - Get the rate value for the clock
- * @clk_id	Clock ID
- * @rate:	Buffer to store clock rate value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
  *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
-				     uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
-}
-
-/**
- * pm_pll_set_param() - Set PLL parameter
  * @clk_id	PLL clock ID
  * @param	PLL parameter ID
  * @value	Value to set for PLL parameter
@@ -692,6 +275,11 @@
 
 /**
  * pm_pll_get_param() - Get PLL parameter value
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
  * @clk_id	PLL clock ID
  * @param	PLL parameter ID
  * @value:	Buffer to store PLL parameter value
@@ -714,6 +302,11 @@
 
 /**
  * pm_pll_set_mode() - Set PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
  * @clk_id	PLL clock ID
  * @mode	PLL mode
  * @flag	0 - Call from secure source
@@ -735,6 +328,11 @@
 
 /**
  * pm_pll_get_mode() - Get PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
  * @clk_id	PLL clock ID
  * @mode:	Buffer to store PLL mode
  * @flag	0 - Call from secure source
@@ -808,22 +406,28 @@
 }
 
 /**
-* pm_query_data() -  PM API for querying firmware data
-* @qid	The type of data to query
-* @arg1	Argument 1 to requested query data call
-* @arg2	Argument 2 to requested query data call
-* @arg3	Argument 3 to requested query data call
-* @data	Returned output data
-* @flag 0 - Call from secure source
-*	1 - Call from non-secure source
-*
-* This function returns requested data.
-*/
+ * pm_query_data() -  PM API for querying firmware data
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * @qid	The type of data to query
+ * @arg1	Argument 1 to requested query data call
+ * @arg2	Argument 2 to requested query data call
+ * @arg3	Argument 3 to requested query data call
+ * @data	Returned output data
+ * @flag 0 - Call from secure source
+ *	1 - Call from non-secure source
+ *
+ * @retur - 0 if success else non-zero error code of type
+ * enum pm_ret_status
+ */
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag)
 {
 	uint32_t ret;
-	uint32_t version;
+	uint32_t version[PAYLOAD_ARG_CNT] = {0};
 	uint32_t payload[PAYLOAD_ARG_CNT];
 	uint32_t fw_api_version;
 
@@ -831,42 +435,50 @@
 	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
 			 arg1, arg2, arg3);
 
-	ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
-	if (PM_RET_SUCCESS == ret) {
-		fw_api_version = version & 0xFFFFU;
-		if ((2U == fw_api_version) &&
-		    ((XPM_QID_CLOCK_GET_NAME == qid) ||
-		     (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
-			ret = data[0];
-			data[0] = data[1];
-			data[1] = data[2];
-			data[2] = data[3];
+	ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version[0] & 0xFFFF;
+		if ((fw_api_version == 2U) &&
+		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
+		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
+			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
+			if (ret == PM_RET_SUCCESS) {
+				ret = data[0];
+				data[0] = data[1];
+				data[1] = data[2];
+				data[2] = data[3];
+			}
 		} else {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
+			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
 		}
 	}
 	return ret;
 }
 /**
  * pm_api_ioctl() -  PM IOCTL API for device control and configs
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
  * @device_id	Device ID
  * @ioctl_id	ID of the requested IOCTL
  * @arg1	Argument 1 to requested IOCTL call
  * @arg2	Argument 2 to requested IOCTL call
+ * @arg3	Argument 3 to requested IOCTL call
  * @value	Returned output value
  * @flag	0 - Call from secure source
  *		1 - Call from non-secure source
  *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either success or error+reason
+ * @return	Returns status, either 0 on success or non-zero error code
+ * of type enum pm_ret_status
  */
 enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t *value,
-				uint32_t flag)
+				uint32_t arg1, uint32_t arg2, uint32_t arg3,
+				uint32_t *value, uint32_t flag)
 {
-	uint32_t payload[PAYLOAD_ARG_CNT];
 	enum pm_ret_status ret;
 
 	switch (ioctl_id) {
@@ -892,11 +504,7 @@
 		ret =  PM_RET_SUCCESS;
 		break;
 	default:
-		/* Send request to the PMC */
-		PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
-				 device_id, ioctl_id, arg1, arg2);
-		ret =  pm_ipi_send_sync(primary_proc, payload, value, 1);
-		break;
+		return PM_RET_ERROR_NOTSUPPORTED;
 	}
 
 	return ret;
@@ -923,116 +531,48 @@
 }
 
 /**
- * pm_get_chipid() - Read silicon ID registers
- * @value       Buffer for return values. Must be large enough
- *		to hold 8 bytes.
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return      Returns silicon ID registers
- */
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 2);
-}
-
-/**
  * pm_feature_check() - Returns the supported API version if supported
  * @api_id	API ID to check
- * @value	Returned supported API version
  * @flag	0 - Call from secure source
  *		1 - Call from non-secure source
+ * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
+ *		words Returned supported API version and bitmasks
+ *		for IOCTL and QUERY ID
  *
  * @return	Returns status, either success or error+reason
  */
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
 				    uint32_t flag)
 {
-	uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
-	enum pm_ret_status status = PM_RET_ERROR_NOFEATURE;
+	uint32_t payload[PAYLOAD_ARG_CNT];
+	uint32_t module_id;
 
+	/* Return version of API which are implemented in ATF only */
 	switch (api_id) {
 	case PM_GET_CALLBACK_DATA:
 	case PM_GET_TRUSTZONE_VERSION:
+		ret_payload[0] = PM_API_VERSION_2;
+		return PM_RET_SUCCESS;
 	case PM_LOAD_PDI:
-		*version = (PM_API_BASE_VERSION << 16);
-		status = PM_RET_SUCCESS;
-		break;
-	case PM_GET_API_VERSION:
-	case PM_GET_DEVICE_STATUS:
-	case PM_GET_OP_CHARACTERISTIC:
-	case PM_REQ_SUSPEND:
-	case PM_SELF_SUSPEND:
-	case PM_FORCE_POWERDOWN:
-	case PM_ABORT_SUSPEND:
-	case PM_REQ_WAKEUP:
-	case PM_SET_WAKEUP_SOURCE:
-	case PM_SYSTEM_SHUTDOWN:
-	case PM_REQUEST_DEVICE:
-	case PM_RELEASE_DEVICE:
-	case PM_SET_REQUIREMENT:
-	case PM_RESET_ASSERT:
-	case PM_RESET_GET_STATUS:
-	case PM_GET_CHIPID:
-	case PM_PINCTRL_REQUEST:
-	case PM_PINCTRL_RELEASE:
-	case PM_PINCTRL_GET_FUNCTION:
-	case PM_PINCTRL_SET_FUNCTION:
-	case PM_PINCTRL_CONFIG_PARAM_GET:
-	case PM_PINCTRL_CONFIG_PARAM_SET:
-	case PM_IOCTL:
-	case PM_CLOCK_ENABLE:
-	case PM_CLOCK_DISABLE:
-	case PM_CLOCK_GETSTATE:
-	case PM_CLOCK_SETDIVIDER:
-	case PM_CLOCK_GETDIVIDER:
-	case PM_CLOCK_SETPARENT:
-	case PM_CLOCK_GETPARENT:
-	case PM_CLOCK_GETRATE:
-	case PM_PLL_SET_PARAMETER:
-	case PM_PLL_GET_PARAMETER:
-	case PM_PLL_SET_MODE:
-	case PM_PLL_GET_MODE:
-	case PM_FEATURE_CHECK:
-	case PM_INIT_FINALIZE:
-	case PM_SET_MAX_LATENCY:
-	case PM_REGISTER_NOTIFIER:
-		*version = (PM_API_BASE_VERSION << 16);
-		status = PM_RET_SUCCESS;
-		break;
-	case PM_QUERY_DATA:
-		*version = (PM_API_QUERY_DATA_VERSION << 16);
-		status = PM_RET_SUCCESS;
-		break;
+		ret_payload[0] = PM_API_BASE_VERSION;
+		return PM_RET_SUCCESS;
 	default:
-		*version = 0U;
-		status = PM_RET_ERROR_NOFEATURE;
 		break;
 	}
 
-	if (status != PM_RET_SUCCESS) {
-		goto done;
+	module_id = (api_id & MODULE_ID_MASK) >> 8;
+
+	/*
+	 * feature check should be done only for LIBPM module
+	 * If module_id is 0, then we consider it LIBPM module as default id
+	 */
+	if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
+		return PM_RET_SUCCESS;
 	}
 
 	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
 			 PM_FEATURE_CHECK, api_id);
-
-	status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
-	if (status != PM_RET_SUCCESS) {
-		goto done;
-	}
-
-	*version |= fw_api_version;
-
-	status = PM_RET_SUCCESS;
-
-done:
-	return status;
+	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
 }
 
 /**
@@ -1060,54 +600,6 @@
 }
 
 /**
- * pm_get_op_characteristic() - PM call to request operating characteristics
- *                              of a device
- * @device_id   Device id
- * @type        Type of the operating characteristic
- *              (power, temperature and latency)
- * @result      Returns the operating characteristic for the requested device,
- *              specified by the type
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return      Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
-					    enum pm_opchar_type type,
-					    uint32_t *result, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
-			 PM_GET_OP_CHARACTERISTIC, device_id, type);
-	return pm_ipi_send_sync(primary_proc, payload, result, 1);
-}
-
-/**
- * pm_set_max_latency() - PM call to change in the maximum wake-up latency
- *			  requirements for a specific device currently
- *			  used by that CPU.
- * @device_id	Device ID
- * @latency	Latency value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
-				      uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
-			 device_id, latency);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
  * pm_register_notifier() - PM call to register a subsystem to be notified
  * 			    about the device event
  * @device_id	Device ID for the Node to which the event is related
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 5a92704..86a46d0 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,8 +14,9 @@
  * PM API function declarations
  **********************************************************/
 
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag);
-enum pm_ret_status pm_init_finalize(uint32_t flag);
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+				       uint32_t x2, uint32_t x3, uint32_t x4,
+				       uint32_t x5, uint64_t *result);
 enum pm_ret_status pm_self_suspend(uint32_t nid,
 				   unsigned int latency,
 				   unsigned int state,
@@ -29,42 +30,7 @@
 				 uintptr_t address, uint8_t ack, uint32_t flag);
 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
 					uint8_t enable, uint32_t flag);
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
-				     uint32_t qos, uint32_t ack, uint32_t flag);
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag);
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
-				      uint32_t latency, uint32_t qos,
-				      uint32_t flag);
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
-					uint32_t flag);
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag);
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
-				       uint32_t flag);
 void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag);
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
-					   uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
-					   uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
-					    uint32_t value, uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
-					    uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
-				      uint32_t flag);
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
-					uint32_t flag);
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
-					uint32_t flag);
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
-				       uint32_t flag);
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
-				       uint32_t flag);
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
-				     uint32_t flag);
 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
 				    uint32_t value, uint32_t flag);
 enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
@@ -78,21 +44,15 @@
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 				      uint32_t flag);
 enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t *value,
-				uint32_t flag);
+				uint32_t arg1, uint32_t arg2, uint32_t arg3,
+				uint32_t *value, uint32_t flag);
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag);
 unsigned int pm_get_shutdown_scope(void);
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
 				    uint32_t flag);
 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
 			       uint32_t address_high, uint32_t flag);
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
-					    enum pm_opchar_type type,
-					    uint32_t *result, uint32_t flag);
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
-				      uint32_t flag);
 enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
 					uint32_t wake, uint32_t enable,
 					uint32_t flag);
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 4c1d340..4012f32 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,7 @@
 #include <plat/common/platform.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
+#include "pm_defs.h"
 
 #define UNDEFINED_CPUID		(~0)
 #define IRQ_MAX		142U
@@ -147,14 +148,16 @@
 			node_idx = irq_to_pm_node_idx(irq);
 			reg &= ~lowest_set;
 
-			if ((node_idx != XPM_NODEIDX_DEV_MIN) &&
-			    (pm_wakeup_nodes_set[node_idx] == 0U)) {
-				/* Get device ID from node index */
-				device_id = PERIPH_DEVID(node_idx);
-				ret = pm_set_wakeup_source(node_id,
-							   device_id, 1,
-							   SECURE_FLAG);
-				pm_wakeup_nodes_set[node_idx] = (uint8_t)(!ret);
+			if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) {
+				if (pm_wakeup_nodes_set[node_idx] == 0U) {
+					/* Get device ID from node index */
+					device_id = PERIPH_DEVID(node_idx);
+					ret = pm_set_wakeup_source(node_id,
+								   device_id, 1,
+								   SECURE_FLAG);
+					pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
+											 1 : 0;
+				}
 			}
 		}
 	}
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 08b46e2..3785650 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,13 +38,11 @@
 
 /* PM API Versions */
 #define PM_API_BASE_VERSION		1U
+#define PM_API_VERSION_2                2U
 
 #define PM_API_QUERY_DATA_VERSION	2U
 
 /* PM API ids */
-#define PM_GET_API_VERSION		1U
-#define PM_GET_DEVICE_STATUS		3U
-#define PM_GET_OP_CHARACTERISTIC	4U
 #define PM_REGISTER_NOTIFIER		5U
 #define PM_REQ_SUSPEND			6U
 #define PM_SELF_SUSPEND			7U
@@ -53,31 +51,8 @@
 #define PM_REQ_WAKEUP			10U
 #define PM_SET_WAKEUP_SOURCE		11U
 #define PM_SYSTEM_SHUTDOWN		12U
-#define PM_REQUEST_DEVICE		13U
-#define PM_RELEASE_DEVICE		14U
-#define PM_SET_REQUIREMENT		15U
-#define PM_SET_MAX_LATENCY		16U
-#define PM_RESET_ASSERT			17U
-#define PM_RESET_GET_STATUS		18U
-#define PM_INIT_FINALIZE		21U
-#define PM_GET_CHIPID			24U
-#define	PM_PINCTRL_REQUEST		28U
-#define	PM_PINCTRL_RELEASE		29U
-#define	PM_PINCTRL_GET_FUNCTION		30U
-#define	PM_PINCTRL_SET_FUNCTION		31U
-#define	PM_PINCTRL_CONFIG_PARAM_GET	32U
-#define	PM_PINCTRL_CONFIG_PARAM_SET	33U
 #define PM_IOCTL			34U
 #define PM_QUERY_DATA			35U
-#define PM_CLOCK_ENABLE			36U
-#define PM_CLOCK_DISABLE		37U
-#define PM_CLOCK_GETSTATE		38U
-#define PM_CLOCK_SETDIVIDER		39U
-#define PM_CLOCK_GETDIVIDER		40U
-#define PM_CLOCK_SETRATE		41U
-#define PM_CLOCK_GETRATE		42U
-#define PM_CLOCK_SETPARENT		43U
-#define PM_CLOCK_GETPARENT		44U
 #define PM_PLL_SET_PARAMETER		48U
 #define PM_PLL_GET_PARAMETER		49U
 #define PM_PLL_SET_MODE			50U
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index b082acb..75c1268 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -114,49 +114,84 @@
 }
 
 /**
- * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
+ * eemi_for_compatibility() - EEMI calls handler for deprecated calls
  *
- * @return  - Unused
- *
- * Determines that smc_fid is valid and supported PM SMC Function ID from the
- * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * @return - If EEMI API found then, uintptr_t type address, else 0
  *
- * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * Some EEMI API's use case needs to be changed in Linux driver, so they
+ * can take advantage of common EEMI handler in TF-A. As of now the old
+ * implementation of these APIs are required to maintain backward compatibility
+ * until their use case in linux driver changes.
  */
-uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle, uint64_t flags)
+static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
+					void *handle, uint32_t security_flag)
 {
 	enum pm_ret_status ret;
 
-	uint32_t pm_arg[4];
-	uint32_t security_flag = SECURE_FLAG;
+	switch (api_id) {
 
-	/* Handle case where PM wasn't initialized properly */
-	if (pm_up == false) {
-		SMC_RET1(handle, SMC_UNK);
+	case PM_IOCTL:
+	{
+		uint32_t value;
+
+		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
+				   pm_arg[3], pm_arg[4],
+				   &value, security_flag);
+		if (ret == PM_RET_ERROR_NOTSUPPORTED)
+			return (uintptr_t)0;
+
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
 	}
 
-	pm_arg[0] = (uint32_t)x1;
-	pm_arg[1] = (uint32_t)(x1 >> 32);
-	pm_arg[2] = (uint32_t)x2;
-	pm_arg[3] = (uint32_t)(x2 >> 32);
+	case PM_QUERY_DATA:
+	{
+		uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
 
-	/*
-	 * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
-	 * if smc called is non secure
-	 */
-	if (is_caller_non_secure(flags) != 0) {
-		security_flag = NON_SECURE_FLAG;
+		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+				      pm_arg[3], data, security_flag);
+
+		SMC_RET2(handle, (uint64_t)ret  | ((uint64_t)data[0] << 32),
+				 (uint64_t)data[1] | ((uint64_t)data[2] << 32));
+	}
+
+	case PM_FEATURE_CHECK:
+	{
+		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+
+		ret = pm_feature_check(pm_arg[0], result, security_flag);
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
+			 (uint64_t)result[1] | ((uint64_t)result[2] << 32));
+	}
+
+	case PM_LOAD_PDI:
+	{
+		ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
+				  security_flag);
+		SMC_RET1(handle, (uint64_t)ret);
+	}
+
+	default:
+		return (uintptr_t)0;
 	}
+}
 
-	switch (smc_fid & FUNCID_NUM_MASK) {
-	/* PM API Functions */
+/**
+ * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
+ *
+ * These EEMI APIs performs CPU specific power management tasks.
+ * These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
+ * These calls require CPU specific processing before sending IPI request to
+ * Platform Management Controller. For example enable/disable CPU specific
+ * interrupts. This requires separate handler for these calls and may not be
+ * handled using common eemi handler
+ */
+static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
+					   void *handle, uint32_t security_flag)
+{
+	enum pm_ret_status ret;
+
+	switch (api_id) {
+
 	case PM_SELF_SUSPEND:
 		ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], security_flag);
@@ -179,65 +214,22 @@
 		ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
 		SMC_RET1(handle, (uint64_t)ret);
 
-	case PM_REQ_WAKEUP:
-		ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
-				    security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_SET_WAKEUP_SOURCE:
-		ret = pm_set_wakeup_source(pm_arg[0], pm_arg[1], pm_arg[2],
-					   security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_REQUEST_DEVICE:
-		ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2],
-					pm_arg[3], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_RELEASE_DEVICE:
-		ret = pm_release_device(pm_arg[0], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_SET_REQUIREMENT:
-		ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2],
-					 pm_arg[3], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_GET_API_VERSION:
-	{
-		uint32_t api_version;
-
-		ret = pm_get_api_version(&api_version, security_flag);
-		SMC_RET1(handle, (u_register_t)PM_RET_SUCCESS |
-				 ((u_register_t)api_version << 32));
-	}
-
-	case PM_GET_DEVICE_STATUS:
-	{
-		uint32_t buff[3];
-
-		ret = pm_get_device_status(pm_arg[0], buff, security_flag);
-		SMC_RET2(handle, (u_register_t)ret | ((u_register_t)buff[0] << 32),
-			 (u_register_t)buff[1] | ((u_register_t)buff[2] << 32));
-	}
-
-	case PM_RESET_ASSERT:
-		ret = pm_reset_assert(pm_arg[0], pm_arg[1], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_RESET_GET_STATUS:
-	{
-		uint32_t reset_status;
-
-		ret = pm_reset_get_status(pm_arg[0], &reset_status,
-					  security_flag);
-		SMC_RET1(handle, (u_register_t)ret |
-			 ((u_register_t)reset_status << 32));
+	default:
+		return (uintptr_t)0;
 	}
+}
 
-	case PM_INIT_FINALIZE:
-		ret = pm_init_finalize(security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
+/**
+ * TF_A_specific_handler() - SMC handler for TF-A specific functionality
+ *
+ * These EEMI calls performs functionality that does not require
+ * IPI transaction. The handler ends in TF-A and returns requested data to
+ * kernel from TF-A
+ */
+static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
+				       void *handle, uint32_t security_flag)
+{
+	switch (api_id) {
 
 	case PM_GET_CALLBACK_DATA:
 	{
@@ -245,192 +237,115 @@
 
 		pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag);
 		SMC_RET2(handle,
-			 (u_register_t)result[0] | ((u_register_t)result[1] << 32),
-			 (u_register_t)result[2] | ((u_register_t)result[3] << 32));
-	}
-
-	case PM_PINCTRL_REQUEST:
-		ret = pm_pinctrl_request(pm_arg[0], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_RELEASE:
-		ret = pm_pinctrl_release(pm_arg[0], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_GET_FUNCTION:
-	{
-		uint32_t value = 0;
-
-		ret = pm_pinctrl_get_function(pm_arg[0], &value, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
+			(uint64_t)result[0] | ((uint64_t)result[1] << 32),
+			(uint64_t)result[2] | ((uint64_t)result[3] << 32));
 	}
 
-	case PM_PINCTRL_SET_FUNCTION:
-		ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1],
-					      security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_CONFIG_PARAM_GET:
-	{
-		uint32_t value;
-
-		ret = pm_pinctrl_get_pin_param(pm_arg[0], pm_arg[1], &value,
-					       security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
-	}
-
-	case PM_PINCTRL_CONFIG_PARAM_SET:
-		ret = pm_pinctrl_set_pin_param(pm_arg[0], pm_arg[1], pm_arg[2],
-					       security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_IOCTL:
-	{
-		uint32_t value;
-
-		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
-				   pm_arg[3], &value, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
-	}
-
-	case PM_QUERY_DATA:
-	{
-		uint32_t data[8] = { 0 };
-
-		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
-				      pm_arg[3], data, security_flag);
-
-		SMC_RET2(handle, (u_register_t)ret  | ((u_register_t)data[0] << 32),
-				 (u_register_t)data[1] | ((u_register_t)data[2] << 32));
-
-	}
-	case PM_CLOCK_ENABLE:
-		ret = pm_clock_enable(pm_arg[0], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_CLOCK_DISABLE:
-		ret = pm_clock_disable(pm_arg[0], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_CLOCK_GETSTATE:
-	{
-		uint32_t value;
-
-		ret = pm_clock_get_state(pm_arg[0], &value, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
-	}
-
-	case PM_CLOCK_SETDIVIDER:
-		ret = pm_clock_set_divider(pm_arg[0], pm_arg[1], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_CLOCK_GETDIVIDER:
-	{
-		uint32_t value;
-
-		ret = pm_clock_get_divider(pm_arg[0], &value, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
-	}
-
-	case PM_CLOCK_SETPARENT:
-		ret = pm_clock_set_parent(pm_arg[0], pm_arg[1], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_CLOCK_GETPARENT:
-	{
-		uint32_t value;
-
-		ret = pm_clock_get_parent(pm_arg[0], &value, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
-	}
-
-	case PM_CLOCK_GETRATE:
-	{
-		uint32_t rate[2] = { 0 };
-
-		ret = pm_clock_get_rate(pm_arg[0], rate, security_flag);
-		SMC_RET2(handle, (u_register_t)ret | ((u_register_t)rate[0] << 32),
-			 (u_register_t)rate[1] | ((u_register_t)0U << 32));
-	}
-
-	case PM_PLL_SET_PARAMETER:
-		ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2],
-				       security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PLL_GET_PARAMETER:
-	{
-		uint32_t value;
+	case PM_GET_TRUSTZONE_VERSION:
+		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+			 ((uint64_t)VERSAL_TZ_VERSION << 32));
 
-		ret = pm_pll_get_param(pm_arg[0], pm_arg[1], &value,
-				       security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value << 32));
+	default:
+		return (uintptr_t)0;
 	}
-
-	case PM_PLL_SET_MODE:
-		ret = pm_pll_set_mode(pm_arg[0], pm_arg[1], security_flag);
-		SMC_RET1(handle, (uint64_t)ret);
+}
 
-	case PM_PLL_GET_MODE:
-	{
-		uint32_t mode;
+/**
+ * eemi_handler() - Prepare EEMI payload and perform IPI transaction
+ *
+ * EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
+ * to allow communication between power management controller and different
+ * processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ */
+static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
+			      void *handle, uint32_t security_flag)
+{
+	enum pm_ret_status ret;
+	uint32_t buf[PAYLOAD_ARG_CNT] = {0};
 
-		ret = pm_pll_get_mode(pm_arg[0], &mode, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)mode << 32));
+	ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
+				  pm_arg[2], pm_arg[3], pm_arg[4],
+				  (uint64_t *)buf);
+	/*
+	 * Two IOCTLs, to get clock name and pinctrl name of pm_query_data API
+	 * receives 5 words of respoonse from firmware. Currently linux driver can
+	 * receive only 4 words from TF-A. So, this needs to be handled separately
+	 * than other eemi calls.
+	 */
+	if (api_id == PM_QUERY_DATA) {
+		if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
+		    pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
+		    ret == PM_RET_SUCCESS) {
+			SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32),
+				(uint64_t)buf[2] | ((uint64_t)buf[3] << 32));
+		}
 	}
 
-	case PM_GET_TRUSTZONE_VERSION:
-		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-			 ((uint64_t)VERSAL_TZ_VERSION << 32));
-
-	case PM_GET_CHIPID:
-	{
-		uint32_t result[2];
+	SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32),
+		 (uint64_t)buf[1] | ((uint64_t)buf[2] << 32));
+}
 
-		ret = pm_get_chipid(result, security_flag);
-		SMC_RET2(handle, (u_register_t)ret | ((u_register_t)result[0] << 32),
-			 (u_register_t)result[1] | ((u_register_t)0U << 32));
-	}
+/**
+ * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
+ * @smc_fid - Function Identifier
+ * @x1 - x4 - SMC64 Arguments from kernel
+ *	      x3 (upper 32-bits) and x4 are Unused
+ * @cookie  - Unused
+ * @handler - Pointer to caller's context structure
+ *
+ * @return  - Unused
+ *
+ * Determines that smc_fid is valid and supported PM SMC Function ID from the
+ * list of pm_api_ids, otherwise completes the request with
+ * the unknown SMC Function ID
+ *
+ * The SMC calls for PM service are forwarded from SIP Service SMC handler
+ * function with rt_svc_handle signature
+ */
+uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+	uintptr_t ret;
+	uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
+	uint32_t security_flag = SECURE_FLAG;
+	uint32_t api_id;
 
-	case PM_FEATURE_CHECK:
-	{
-		uint32_t version;
+	/* Handle case where PM wasn't initialized properly */
+	if (!pm_up)
+		SMC_RET1(handle, SMC_UNK);
 
-		ret = pm_feature_check(pm_arg[0], &version, security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)version << 32));
+	/*
+	 * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
+	 * if smc called is non secure
+	 */
+	if (is_caller_non_secure(flags)) {
+		security_flag = NON_SECURE_FLAG;
 	}
 
-	case PM_LOAD_PDI:
-	{
-		ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
-				  security_flag);
-		SMC_RET1(handle, (u_register_t)ret);
-	}
+	pm_arg[0] = (uint32_t)x1;
+	pm_arg[1] = (uint32_t)(x1 >> 32);
+	pm_arg[2] = (uint32_t)x2;
+	pm_arg[3] = (uint32_t)(x2 >> 32);
+	pm_arg[4] = (uint32_t)x3;
+	(void)(x4);
+	api_id = smc_fid & FUNCID_NUM_MASK;
 
-	case PM_GET_OP_CHARACTERISTIC:
-	{
-		uint32_t result;
+	ret = eemi_for_compatibility(api_id, pm_arg, handle, security_flag);
+	if (ret != (uintptr_t)0)
+		return ret;
 
-		ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result,
-					       security_flag);
-		SMC_RET1(handle, (u_register_t)ret | ((u_register_t)result << 32));
-	}
+	ret = eemi_psci_debugfs_handler(api_id, pm_arg, handle, flags);
+	if (ret !=  (uintptr_t)0)
+		return ret;
 
-	case PM_SET_MAX_LATENCY:
-	{
-		ret = pm_set_max_latency(pm_arg[0], pm_arg[1], security_flag);
-		SMC_RET1(handle, (u_register_t)ret);
-	}
+	ret = TF_A_specific_handler(api_id, pm_arg, handle, security_flag);
+	if (ret !=  (uintptr_t)0)
+		return ret;
 
-	case PM_REGISTER_NOTIFIER:
-	{
-		ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
-					   pm_arg[3], security_flag);
-		SMC_RET1(handle, (u_register_t)ret);
-	}
+	ret = eemi_handler(api_id, pm_arg, handle, security_flag);
 
-	default:
-		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
-		SMC_RET1(handle, SMC_UNK);
-	}
+	return ret;
 }
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index fae73cf..32b0123 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,10 +47,11 @@
 {
 	unsigned int ver = zynqmp_get_silicon_ver();
 
-	if (ver == ZYNQMP_CSU_VERSION_QEMU)
+	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
 		return 133000000;
-	else
+	} else {
 		return 100000000;
+	}
 }
 
 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
@@ -232,8 +233,9 @@
 	chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
 	chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
 #else
-	if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
+	if (pm_get_chipid(chipid) != PM_RET_SUCCESS) {
 		return "XCZUUNKN";
+	}
 #endif
 
 	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
@@ -243,8 +245,9 @@
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
 		if (zynqmp_devices[i].id == id &&
-		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
+		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
 			break;
+		}
 	}
 
 	if (i >= ARRAY_SIZE(zynqmp_devices)) {
@@ -255,11 +258,13 @@
 		}
 	}
 
-	if (!zynqmp_devices[i].evexists)
+	if (!zynqmp_devices[i].evexists) {
 		return zynqmp_devices[i].name;
+	}
 
-	if (ver & ZYNQMP_PL_STATUS_MASK)
+	if ((ver & ZYNQMP_PL_STATUS_MASK) != 0U) {
 		return zynqmp_devices[i].name;
+	}
 
 	len = strlen(zynqmp_devices[i].name) - 2;
 	for (j = 0; j < strlen(name); j++) {
@@ -329,8 +334,8 @@
 		break;
 	}
 
-	NOTICE("TF-A running on %s/%s at 0x%x\n",
-	       zynqmp_print_silicon_idcode(), label, BL31_BASE);
+	VERBOSE("TF-A running on %s/%s at 0x%x\n",
+		zynqmp_print_silicon_idcode(), label, BL31_BASE);
 	VERBOSE("TF-A running on v%d/RTL%d.%d\n",
 	       zynqmp_get_ps_ver(), (rtl & 0xf0) >> 4, rtl & 0xf);
 }
@@ -345,8 +350,9 @@
 
 	ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
 
-	if (ret != PM_RET_SUCCESS)
+	if (ret != PM_RET_SUCCESS) {
 		r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
+	}
 
 	return r & CRL_APB_BOOT_MODE_MASK;
 }
@@ -373,8 +379,9 @@
 {
 	unsigned int ver = zynqmp_get_silicon_ver();
 
-	if (ver == ZYNQMP_CSU_VERSION_QEMU)
+	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
 		return 65000000;
-	else
+	} else {
 		return mmio_read_32(IOU_SCNTRS_BASEFREQ);
+	}
 }
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 58eee3a..5ad33cc 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -83,6 +83,8 @@
 		if (rc == 0) {
 			panic();
 		}
+	} else {
+		ERROR("BL31: No console device found.\n");
 	}
 	/* Initialize the platform config for future decision making */
 	zynqmp_config_setup();
@@ -119,10 +121,10 @@
 			panic();
 		}
 	}
-	if (bl32_image_ep_info.pc) {
+	if (bl32_image_ep_info.pc != 0) {
 		VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
 	}
-	if (bl33_image_ep_info.pc) {
+	if (bl33_image_ep_info.pc != 0) {
 		VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
 	}
 }
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 1c4daa1..9c1600a 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -37,11 +37,11 @@
  */
 #ifndef ZYNQMP_ATF_MEM_BASE
 #if !DEBUG && defined(SPD_none) && !SDEI_SUPPORT
-# define BL31_BASE			0xfffea000
-# define BL31_LIMIT			0x100000000
+# define BL31_BASE			U(0xfffea000)
+# define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			0x1000
-# define BL31_LIMIT			0x7ffff
+# define BL31_BASE			U(0x1000)
+# define BL31_LIMIT			U(0x7ffff)
 #endif
 #else
 # define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
@@ -55,8 +55,8 @@
  * BL32 specific defines.
  ******************************************************************************/
 #ifndef ZYNQMP_BL32_MEM_BASE
-# define BL32_BASE			0x60000000
-# define BL32_LIMIT			0x7fffffff
+# define BL32_BASE			U(0x60000000)
+# define BL32_LIMIT			U(0x7fffffff)
 #else
 # define BL32_BASE			(ZYNQMP_BL32_MEM_BASE)
 # define BL32_LIMIT			(ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE - 1)
@@ -66,7 +66,7 @@
  * BL33 specific defines.
  ******************************************************************************/
 #ifndef PRELOADED_BL33_BASE
-# define PLAT_ARM_NS_IMAGE_BASE	0x8000000
+# define PLAT_ARM_NS_IMAGE_BASE	U(0x8000000)
 #else
 # define PLAT_ARM_NS_IMAGE_BASE	PRELOADED_BL33_BASE
 #endif
@@ -83,9 +83,9 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define XILINX_OF_BOARD_DTB_ADDR	0x100000
-#define XILINX_OF_BOARD_DTB_MAX_SIZE	0x200000
-#define PLAT_DDR_LOWMEM_MAX		0x80000000
+#define XILINX_OF_BOARD_DTB_ADDR	U(0x100000)
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 7e58391..19b6937 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -74,11 +74,11 @@
 #define ZYNQMP_ULPI_RESET_VAL_LOW	CRL_APB_BOOT_ENABLE_PIN_1
 
 /* system counter registers and bitfields */
-#define IOU_SCNTRS_BASE			0xFF260000
+#define IOU_SCNTRS_BASE			U(0xFF260000)
 #define IOU_SCNTRS_BASEFREQ		(IOU_SCNTRS_BASE + 0x20)
 
 /* APU registers and bitfields */
-#define APU_BASE		0xFD5C0000
+#define APU_BASE		U(0xFD5C0000)
 #define APU_CONFIG_0		(APU_BASE + 0x20)
 #define APU_RVBAR_L_0		(APU_BASE + 0x40)
 #define APU_RVBAR_H_0		(APU_BASE + 0x44)
@@ -91,7 +91,7 @@
 #define APU_3_PWRCTL_CPUPWRDWNREQ_MASK		8
 
 /* PMU registers and bitfields */
-#define PMU_GLOBAL_BASE			0xFFD80000
+#define PMU_GLOBAL_BASE			U(0xFFD80000)
 #define PMU_GLOBAL_CNTRL		(PMU_GLOBAL_BASE + 0)
 #define PMU_GLOBAL_GEN_STORAGE6		(PMU_GLOBAL_BASE + 0x48)
 #define PMU_GLOBAL_REQ_PWRUP_STATUS	(PMU_GLOBAL_BASE + 0x110)
@@ -104,22 +104,22 @@
 /*******************************************************************************
  * CCI-400 related constants
  ******************************************************************************/
-#define PLAT_ARM_CCI_BASE		0xFD6E0000
+#define PLAT_ARM_CCI_BASE		U(0xFD6E0000)
 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	3
 #define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	4
 
 /*******************************************************************************
  * GIC-400 & interrupt handling related constants
  ******************************************************************************/
-#define BASE_GICD_BASE		0xF9010000
-#define BASE_GICC_BASE		0xF9020000
-#define BASE_GICH_BASE		0xF9040000
-#define BASE_GICV_BASE		0xF9060000
+#define BASE_GICD_BASE		U(0xF9010000)
+#define BASE_GICC_BASE		U(0xF9020000)
+#define BASE_GICH_BASE		U(0xF9040000)
+#define BASE_GICV_BASE		U(0xF9060000)
 
 #if ZYNQMP_WDT_RESTART
 #define IRQ_SEC_IPI_APU		67
 #define IRQ_TTC3_1		77
-#define TTC3_BASE_ADDR		0xFF140000
+#define TTC3_BASE_ADDR		U(0xFF140000)
 #define TTC3_INTR_REGISTER_1	(TTC3_BASE_ADDR + 0x54)
 #define TTC3_INTR_ENABLE_1	(TTC3_BASE_ADDR + 0x60)
 #endif
@@ -140,8 +140,8 @@
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
-#define ZYNQMP_UART0_BASE		0xFF000000
-#define ZYNQMP_UART1_BASE		0xFF010000
+#define ZYNQMP_UART0_BASE		U(0xFF000000)
+#define ZYNQMP_UART1_BASE		U(0xFF010000)
 
 #if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
 # define ZYNQMP_UART_BASE	ZYNQMP_UART0_BASE
@@ -169,7 +169,7 @@
 #define ZYNQMP_PS_VER_MASK		0xF
 #define ZYNQMP_PS_VER_SHIFT		0
 
-#define ZYNQMP_CSU_BASEADDR		0xFFCA0000
+#define ZYNQMP_CSU_BASEADDR		U(0xFFCA0000)
 #define ZYNQMP_CSU_IDCODE_OFFSET	0x40
 
 #define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT	0
@@ -199,7 +199,7 @@
 #define ZYNQMP_CSU_VERSION_OFFSET	0x44
 
 /* Efuse */
-#define EFUSE_BASEADDR		0xFFCC0000
+#define EFUSE_BASEADDR		U(0xFFCC0000)
 #define EFUSE_IPDISABLE_OFFSET	0x1018
 #define EFUSE_IPDISABLE_VERSION	0x1FFU
 #define ZYNQMP_EFUSE_IPDISABLE_SHIFT	20
@@ -357,9 +357,9 @@
 #define  FABRIC_WIDTH		U(3)
 
 /* CSUDMA Module Base Address*/
-#define CSUDMA_BASE		0xFFC80000
+#define CSUDMA_BASE		U(0xFFC80000)
 
 /* RSA-CORE Module Base Address*/
-#define RSA_CORE_BASE		0xFFCE0000
+#define RSA_CORE_BASE		U(0xFFCE0000)
 
 #endif /* ZYNQMP_DEF_H */
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index b2b473a..881dfe6 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -38,9 +38,9 @@
 
 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
 
-	if (cpu_id == -1)
+	if (cpu_id == -1) {
 		return PSCI_E_INTERN_FAIL;
-
+	}
 	proc = pm_get_proc(cpu_id);
 
 	/* Check the APU proc status before wakeup */
@@ -63,9 +63,10 @@
 	unsigned int cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
+	}
 
 	/* Prevent interrupts from spuriously waking up this cpu */
 	gicv2_cpuif_disable();
@@ -106,9 +107,10 @@
 
 static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
+	}
 	plat_arm_gic_pcpu_init();
 	gicv2_cpuif_enable();
 }
@@ -118,9 +120,10 @@
 	unsigned int cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
+	}
 
 	/* Clear the APU power control register for this cpu */
 	pm_client_wakeup(proc);
@@ -149,8 +152,9 @@
 	pm_system_shutdown(PMF_SHUTDOWN_TYPE_SHUTDOWN,
 			   pm_get_shutdown_scope());
 
-	while (1)
+	while (1) {
 		wfi();
+	}
 }
 
 static void __dead2 zynqmp_system_reset(void)
@@ -162,8 +166,9 @@
 	pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
 			   pm_get_shutdown_scope());
 
-	while (1)
+	while (1) {
 		wfi();
+	}
 }
 
 int zynqmp_validate_power_state(unsigned int power_state,
@@ -176,14 +181,15 @@
 	assert(req_state);
 
 	/* Sanity check the requested state */
-	if (pstate == PSTATE_TYPE_STANDBY)
+	if (pstate == PSTATE_TYPE_STANDBY) {
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
-	else
+	} else {
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
-
+	}
 	/* We expect the 'state id' to be zero */
-	if (psci_get_pstate_id(power_state))
+	if (psci_get_pstate_id(power_state)) {
 		return PSCI_E_INVALID_PARAMS;
+	}
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 4109830..1ea741c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2446,16 +2446,17 @@
  */
 void pm_api_clock_get_name(unsigned int clock_id, char *name)
 {
-	if (clock_id == CLK_MAX)
+	if (clock_id == CLK_MAX) {
 		memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
 					 CLK_NAME_LEN : sizeof(END_OF_CLK));
-	else if (!pm_clock_valid(clock_id))
+	} else if (!pm_clock_valid(clock_id)) {
 		memset(name, 0, CLK_NAME_LEN);
-	else if (clock_id < CLK_MAX_OUTPUT_CLK)
+	} else if (clock_id < CLK_MAX_OUTPUT_CLK) {
 		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
-	else
+	} else {
 		memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
 		       CLK_NAME_LEN);
+	}
 }
 
 /**
@@ -2480,24 +2481,28 @@
 	unsigned int i;
 	uint16_t typeflags;
 
-	if (!pm_clock_valid(clock_id))
+	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
-	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
 		return PM_RET_ERROR_NOTSUPPORTED;
-
+	}
 
 	memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
 	clock_nodes = *clocks[clock_id].nodes;
 	num_nodes = clocks[clock_id].num_nodes;
 
 	/* Skip parent till index */
-	if (index >= num_nodes)
+	if (index >= num_nodes) {
 		return PM_RET_SUCCESS;
+	}
 
 	for (i = 0; i < 3U; i++) {
-		if ((index + i) == num_nodes)
+		if ((index + i) == num_nodes) {
 			break;
+		}
+
 		topology[i] = clock_nodes[index + i].type;
 		topology[i] |= clock_nodes[index + i].clkflags <<
 					CLK_CLKFLAGS_SHIFT;
@@ -2531,11 +2536,13 @@
 	uint8_t num_nodes;
 	unsigned int type, i;
 
-	if (!pm_clock_valid(clock_id))
+	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
-	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
 		return PM_RET_ERROR_NOTSUPPORTED;
+	}
 
 	clock_nodes = *clocks[clock_id].nodes;
 	num_nodes = clocks[clock_id].num_nodes;
@@ -2550,8 +2557,9 @@
 	}
 
 	/* Clock is not fixed clock */
-	if (i == num_nodes)
+	if (i == num_nodes) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return PM_RET_SUCCESS;
 }
@@ -2580,27 +2588,33 @@
 	unsigned int i;
 	int32_t *clk_parents;
 
-	if (!pm_clock_valid(clock_id))
+	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
-	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
 		return PM_RET_ERROR_NOTSUPPORTED;
+	}
 
 	clk_parents = *clocks[clock_id].parents;
-	if (clk_parents == NULL)
+	if (clk_parents == NULL) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
 
 	/* Skip parent till index */
-	for (i = 0; i < index; i++)
-		if (clk_parents[i] == CLK_NA_PARENT)
+	for (i = 0; i < index; i++) {
+		if (clk_parents[i] == CLK_NA_PARENT) {
 			return PM_RET_SUCCESS;
+		}
+	}
 
 	for (i = 0; i < 3; i++) {
 		parents[i] = clk_parents[index + i];
-		if (clk_parents[index + i] == CLK_NA_PARENT)
+		if (clk_parents[index + i] == CLK_NA_PARENT) {
 			break;
+		}
 	}
 
 	return PM_RET_SUCCESS;
@@ -2619,8 +2633,9 @@
 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
 					       uint32_t *attr)
 {
-	if (clock_id >= CLK_MAX)
+	if (clock_id >= CLK_MAX) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Clock valid bit */
 	*attr = pm_clock_valid(clock_id);
@@ -2648,8 +2663,9 @@
 	uint32_t i;
 	struct pm_clock_node *nodes;
 
-	if (clock_id >= CLK_MAX_OUTPUT_CLK)
+	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	nodes = *clocks[clock_id].nodes;
 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -2738,8 +2754,9 @@
 	uint32_t i;
 
 	for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
-		if (pm_plls[i].cid == clock_id)
+		if (pm_plls[i].cid == clock_id) {
 			return &pm_plls[i];
+		}
 	}
 
 	return NULL;
@@ -2798,12 +2815,14 @@
  */
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
 {
-	if (!pll)
+	if (!pll) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Set the PLL mode according to the buffered mode value */
-	if (pll->mode == PLL_FRAC_MODE)
+	if (pll->mode == PLL_FRAC_MODE) {
 		return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
+	}
 
 	return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
 }
@@ -2819,8 +2838,9 @@
  */
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 {
-	if (!pll)
+	if (!pll) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
 }
@@ -2842,17 +2862,20 @@
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if (!pll || !state)
+	if (!pll || !state) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	status = pm_pll_get_mode(pll->nid, &mode);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
-	if (mode == PM_PLL_MODE_RESET)
+	if (mode == PM_PLL_MODE_RESET) {
 		*state = 0;
-	else
+	} else {
 		*state = 1;
+	}
 
 	return PM_RET_SUCCESS;
 }
@@ -2873,17 +2896,21 @@
 					   enum clock_id clock_id,
 					   unsigned int parent_index)
 {
-	if (!pll)
+	if (!pll) {
 		return PM_RET_ERROR_ARGS;
-	if (pll->pre_src == clock_id)
+	}
+	if (pll->pre_src == clock_id) {
 		return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
 					    parent_index);
-	if (pll->post_src == clock_id)
+	}
+	if (pll->post_src == clock_id) {
 		return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
 					    parent_index);
-	if (pll->div2 == clock_id)
+	}
+	if (pll->div2 == clock_id) {
 		return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
 					    parent_index);
+	}
 
 	return PM_RET_ERROR_ARGS;
 }
@@ -2902,17 +2929,21 @@
 					   enum clock_id clock_id,
 					   unsigned int *parent_index)
 {
-	if (!pll)
+	if (!pll) {
 		return PM_RET_ERROR_ARGS;
-	if (pll->pre_src == clock_id)
+	}
+	if (pll->pre_src == clock_id) {
 		return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
 					    parent_index);
-	if (pll->post_src == clock_id)
+	}
+	if (pll->post_src == clock_id) {
 		return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
 					    parent_index);
-	if (pll->div2 == clock_id)
+	}
+	if (pll->div2 == clock_id) {
 		return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
 					    parent_index);
+	}
 	if (pll->bypass == clock_id) {
 		*parent_index = 0;
 		return PM_RET_SUCCESS;
@@ -2935,8 +2966,9 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE))
+	if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
 		return PM_RET_ERROR_ARGS;
+	}
 	pll->mode = mode;
 
 	return PM_RET_SUCCESS;
@@ -2956,8 +2988,9 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || !mode)
+	if (!pll || !mode) {
 		return PM_RET_ERROR_ARGS;
+	}
 	*mode = pll->mode;
 
 	return PM_RET_SUCCESS;
@@ -2971,11 +3004,13 @@
  */
 enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id)
 {
-	if (!pm_clock_valid(clock_id))
+	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
-	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
 		return PM_RET_ERROR_NOTSUPPORTED;
+	}
 
 	return PM_RET_SUCCESS;
 }
@@ -2992,8 +3027,9 @@
 	uint32_t i;
 	struct pm_clock_node *nodes;
 
-	if (clock_id >= CLK_MAX_OUTPUT_CLK)
+	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
 		return 0;
+	}
 
 	nodes = *clocks[clock_id].nodes;
 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -3003,6 +3039,8 @@
 		} else if (nodes[i].type == TYPE_DIV2) {
 			if (div_id == PM_CLOCK_DIV1_ID)
 				return 1;
+		} else {
+			/* To fix the misra 15.7 warning */
 		}
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index a87681b..f12143a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -35,10 +35,11 @@
 
 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
 	val &= ZYNQMP_SLSPLIT_MASK;
-	if (val == 0)
+	if (val == 0) {
 		*mode = PM_RPU_MODE_LOCKSTEP;
-	else
+	} else {
 		*mode = PM_RPU_MODE_SPLIT;
+	}
 
 	return PM_RET_SUCCESS;
 }
@@ -58,8 +59,9 @@
 {
 	unsigned int val;
 
-	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
+	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
 		return PM_RET_ERROR_ACCESS;
+	}
 
 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
 
@@ -94,21 +96,23 @@
 {
 	unsigned int rpu_cfg_addr, val;
 
-	if (nid == NODE_RPU_0)
+	if (nid == NODE_RPU_0) {
 		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
-	else if (nid == NODE_RPU_1)
+	} else if (nid == NODE_RPU_1) {
 		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
-	else
+	} else {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	val = mmio_read_32(rpu_cfg_addr);
 
-	if (value == PM_RPU_BOOTMEM_LOVEC)
+	if (value == PM_RPU_BOOTMEM_LOVEC) {
 		val &= ~ZYNQMP_VINITHI_MASK;
-	else if (value == PM_RPU_BOOTMEM_HIVEC)
+	} else if (value == PM_RPU_BOOTMEM_HIVEC) {
 		val |= ZYNQMP_VINITHI_MASK;
-	else
+	} else {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	mmio_write_32(rpu_cfg_addr, val);
 
@@ -130,12 +134,13 @@
 
 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
 
-	if (value == PM_RPU_TCM_SPLIT)
+	if (value == PM_RPU_TCM_SPLIT) {
 		val &= ~ZYNQMP_TCM_COMB_MASK;
-	else if (value == PM_RPU_TCM_COMB)
+	} else if (value == PM_RPU_TCM_COMB) {
 		val |= ZYNQMP_TCM_COMB_MASK;
-	else
+	} else {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
 
@@ -155,8 +160,9 @@
 						       unsigned int value)
 {
 	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
-	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
+	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
 }
@@ -178,8 +184,9 @@
 	unsigned int val, mask, shift;
 	enum pm_ret_status ret;
 
-	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
+	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	switch (nid) {
 	case NODE_ETH_0:
@@ -206,8 +213,9 @@
 		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
 		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
 		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
-		if (ret != PM_RET_SUCCESS)
+		if (ret != PM_RET_SUCCESS) {
 			return ret;
+		}
 
 		/* Set the GEM to SGMII mode */
 		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
@@ -248,11 +256,13 @@
 	case PM_DLL_RESET_ASSERT:
 	case PM_DLL_RESET_PULSE:
 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
-		if (ret != PM_RET_SUCCESS)
+		if (ret != PM_RET_SUCCESS) {
 			return ret;
+		}
 
-		if (type == PM_DLL_RESET_ASSERT)
+		if (type == PM_DLL_RESET_ASSERT) {
 			break;
+		}
 		mdelay(1);
 		/* Fallthrough */
 	case PM_DLL_RESET_RELEASE:
@@ -310,31 +320,44 @@
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
-		if (ret != PM_RET_SUCCESS)
+
+		if (ret != PM_RET_SUCCESS) {
 			goto reset_release;
-		if (value == 0)
+		}
+
+		if (value == 0) {
 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
 					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
 					     shift), 0);
-		else
+		} else {
 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
 					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
 					    shift), (ZYNQMP_SD_ITAPDLYENA <<
 					    shift));
-		if (ret != PM_RET_SUCCESS)
+		}
+
+		if (ret != PM_RET_SUCCESS) {
 			goto reset_release;
+		}
+
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
 				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
 				    (value << shift));
-		if (ret != PM_RET_SUCCESS)
+
+		if (ret != PM_RET_SUCCESS) {
 			goto reset_release;
+		}
+
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
 	} else if (type == PM_TAPDELAY_OUTPUT) {
 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
 				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
-		if (ret != PM_RET_SUCCESS)
+
+		if (ret != PM_RET_SUCCESS) {
 			goto reset_release;
+		}
+
 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
 				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
 				    (value << shift));
@@ -401,8 +424,9 @@
 
 	/* Get PLL node ID using PLL clock ID */
 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
 }
@@ -425,8 +449,9 @@
 
 	/* Get PLL node ID using PLL clock ID */
 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
 }
@@ -444,8 +469,9 @@
 static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
 					     unsigned int value)
 {
-	if (index >= GGS_NUM_REGS)
+	if (index >= GGS_NUM_REGS) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_mmio_write(GGS_BASEADDR + (index << 2),
 			     0xFFFFFFFFU, value);
@@ -464,8 +490,9 @@
 static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
 					    unsigned int *value)
 {
-	if (index >= GGS_NUM_REGS)
+	if (index >= GGS_NUM_REGS) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
 }
@@ -483,8 +510,9 @@
 static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
 					      unsigned int value)
 {
-	if (index >= PGGS_NUM_REGS)
+	if (index >= PGGS_NUM_REGS) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
 			     0xFFFFFFFFU, value);
@@ -503,31 +531,33 @@
 					      unsigned int value)
 {
 	unsigned int mask;
-	unsigned int regarr[] = {0xFD360000,
-				0xFD360014,
-				0xFD370000,
-				0xFD370014,
-				0xFD380000,
-				0xFD380014,
-				0xFD390000,
-				0xFD390014,
-				0xFD3a0000,
-				0xFD3a0014,
-				0xFD3b0000,
-				0xFD3b0014,
-				0xFF9b0000,
-				0xFF9b0014,
-				0xFD615000,
-				0xFF419000,
+	unsigned int regarr[] = {0xFD360000U,
+				0xFD360014U,
+				0xFD370000U,
+				0xFD370014U,
+				0xFD380000U,
+				0xFD380014U,
+				0xFD390000U,
+				0xFD390014U,
+				0xFD3a0000U,
+				0xFD3a0014U,
+				0xFD3b0000U,
+				0xFD3b0014U,
+				0xFF9b0000U,
+				0xFF9b0014U,
+				0xFD615000U,
+				0xFF419000U,
 				};
 
-	if (index >= ARRAY_SIZE(regarr))
+	if (index >= ARRAY_SIZE(regarr)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
-	if (index < AFIFM6_WRCTRL)
+	if (index < AFIFM6_WRCTRL) {
 		mask = FABRIC_WIDTH;
-	else
+	} else {
 		mask = 0xf00;
+	}
 
 	return pm_mmio_write(regarr[index], mask, value);
 }
@@ -545,8 +575,9 @@
 static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
 					     unsigned int *value)
 {
-	if (index >= PGGS_NUM_REGS)
+	if (index >= PGGS_NUM_REGS) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
 }
@@ -565,16 +596,18 @@
 
 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
-	if (ret != PM_RET_SUCCESS)
+	if (ret != PM_RET_SUCCESS) {
 		return ret;
+	}
 
 	/* Drive ULPI assert for atleast 1ms */
 	mdelay(1);
 
 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
 			    ZYNQMP_ULPI_RESET_VAL_LOW);
-	if (ret != PM_RET_SUCCESS)
+	if (ret != PM_RET_SUCCESS) {
 		return ret;
+	}
 
 	/* Drive ULPI de-assert for atleast 1ms */
 	mdelay(1);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 9a6b497..75e0499 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -2549,17 +2549,20 @@
 	int i = 0;
 	uint16_t *grps;
 
-	if (fid >= MAX_FUNCTION)
+	if (fid >= MAX_FUNCTION) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	*ngroups = 0;
 
 	grps = *pinctrl_functions[fid].groups;
-	if (grps == NULL)
+	if (grps == NULL) {
 		return PM_RET_SUCCESS;
+	}
 
-	while (grps[i++] != (uint16_t)END_OF_GROUPS)
+	while (grps[i++] != (uint16_t)END_OF_GROUPS) {
 		(*ngroups)++;
+	}
 
 	return PM_RET_SUCCESS;
 }
@@ -2574,10 +2577,11 @@
  */
 void pm_api_pinctrl_get_function_name(unsigned int fid, char *name)
 {
-	if (fid >= MAX_FUNCTION)
+	if (fid >= MAX_FUNCTION) {
 		memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
-	else
+	} else {
 		memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+	}
 }
 
 /**
@@ -2605,24 +2609,29 @@
 	unsigned int i;
 	uint16_t *grps;
 
-	if (fid >= MAX_FUNCTION)
+	if (fid >= MAX_FUNCTION) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = *pinctrl_functions[fid].groups;
-	if (grps == NULL)
+	if (grps == NULL) {
 		return PM_RET_SUCCESS;
+	}
 
 	/* Skip groups till index */
-	for (i = 0; i < index; i++)
-		if (grps[i] == (uint16_t)END_OF_GROUPS)
+	for (i = 0; i < index; i++) {
+		if (grps[i] == (uint16_t)END_OF_GROUPS) {
 			return PM_RET_SUCCESS;
+		}
+	}
 
 	for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
 		groups[i] = grps[index + i];
-		if (groups[i] == (uint16_t)END_OF_GROUPS)
+		if (groups[i] == (uint16_t)END_OF_GROUPS) {
 			break;
+		}
 	}
 
 	return PM_RET_SUCCESS;
@@ -2653,24 +2662,29 @@
 	unsigned int i;
 	uint16_t *grps;
 
-	if (pin >= MAX_PIN)
+	if (pin >= MAX_PIN) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = *zynqmp_pin_groups[pin].groups;
-	if (!grps)
+	if (grps == NULL) {
 		return PM_RET_SUCCESS;
+	}
 
 	/* Skip groups till index */
-	for (i = 0; i < index; i++)
-		if (grps[i] == (uint16_t)END_OF_GROUPS)
+	for (i = 0; i < index; i++) {
+		if (grps[i] == (uint16_t)END_OF_GROUPS) {
 			return PM_RET_SUCCESS;
+		}
+	}
 
 	for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
 		groups[i] = grps[index + i];
-		if (groups[i] == (uint16_t)END_OF_GROUPS)
+		if (groups[i] == (uint16_t)END_OF_GROUPS) {
 			break;
+		}
 	}
 
 	return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index f9af451..e524ba5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -306,10 +306,11 @@
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
-	if (ack == REQ_ACK_BLOCKING)
+	if (ack == REQ_ACK_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	else
+	} else {
 		return pm_ipi_send(primary_proc, payload);
+	}
 }
 
 /**
@@ -345,10 +346,11 @@
 	PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
 			 encoded_address >> 32, ack);
 
-	if (ack == REQ_ACK_BLOCKING)
+	if (ack == REQ_ACK_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	else
+	} else {
 		return pm_ipi_send(primary_proc, payload);
+	}
 }
 
 /**
@@ -367,10 +369,11 @@
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
 
-	if (ack == REQ_ACK_BLOCKING)
+	if (ack == REQ_ACK_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	else
+	} else {
 		return pm_ipi_send(primary_proc, payload);
+	}
 }
 
 /**
@@ -459,10 +462,11 @@
 
 	PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
 
-	if (ack == REQ_ACK_BLOCKING)
+	if (ack == REQ_ACK_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	else
+	} else {
 		return pm_ipi_send(primary_proc, payload);
+	}
 }
 
 /**
@@ -486,10 +490,11 @@
 	PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
 			 ack);
 
-	if (ack == REQ_ACK_BLOCKING)
+	if (ack == REQ_ACK_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	else
+	} else {
 		return pm_ipi_send(primary_proc, payload);
+	}
 }
 
 /* Miscellaneous API functions */
@@ -689,8 +694,9 @@
 void pm_get_callbackdata(uint32_t *data, size_t count)
 {
 	/* Return if interrupt is not from PMU */
-	if (!pm_ipi_irq_status(primary_proc))
+	if (!pm_ipi_irq_status(primary_proc)) {
 		return;
+	}
 
 	pm_ipi_buff_read_callb(data, count);
 	pm_ipi_irq_clear(primary_proc);
@@ -1070,21 +1076,24 @@
 
 	/* Check if clock ID is valid and return an error if it is not */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
-	if (enable)
+	if (enable) {
 		api_id = PM_CLOCK_ENABLE;
-	else
+	} else {
 		api_id = PM_CLOCK_DISABLE;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD2(payload, api_id, clock_id);
 	status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 
 	/* If action fails due to the lack of permissions filter the error */
-	if (status == PM_RET_ERROR_ACCESS)
+	if (status == PM_RET_ERROR_ACCESS) {
 		status = PM_RET_SUCCESS;
+	}
 
 	return status;
 }
@@ -1105,8 +1114,9 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll)
+	if (pll) {
 		return pm_clock_pll_enable(pll);
+	}
 
 	/* It's an on-chip clock, PMU should configure clock's gate */
 	return pm_clock_gate(clock_id, 1);
@@ -1128,8 +1138,9 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll)
+	if (pll) {
 		return pm_clock_pll_disable(pll);
+	}
 
 	/* It's an on-chip clock, PMU should configure clock's gate */
 	return pm_clock_gate(clock_id, 0);
@@ -1159,8 +1170,9 @@
 
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
@@ -1190,13 +1202,15 @@
 
 	/* Get PLL node ID using PLL clock ID */
 	status = pm_clock_get_pll_node_id(clock_id, &nid);
-	if (status == PM_RET_SUCCESS)
+	if (status == PM_RET_SUCCESS) {
 		return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+	}
 
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	if (div0 == (divider & div0)) {
 		div_id = PM_CLOCK_DIV0_ID;
@@ -1233,21 +1247,24 @@
 
 	/* Get PLL node ID using PLL clock ID */
 	status = pm_clock_get_pll_node_id(clock_id, &nid);
-	if (status == PM_RET_SUCCESS)
+	if (status == PM_RET_SUCCESS) {
 		return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+	}
 
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
 		/* Send request to the PMU to get div0 */
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV0_ID);
 		status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
-		if (status != PM_RET_SUCCESS)
+		if (status != PM_RET_SUCCESS) {
 			return status;
+		}
 		*divider = val;
 	}
 
@@ -1256,8 +1273,9 @@
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV1_ID);
 		status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
-		if (status != PM_RET_SUCCESS)
+		if (status != PM_RET_SUCCESS) {
 			return status;
+		}
 		*divider |= val << 16;
 	}
 
@@ -1313,13 +1331,15 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll)
+	if (pll) {
 		return pm_clock_pll_set_parent(pll, clock_id, parent_index);
+	}
 
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
@@ -1345,13 +1365,15 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll)
+	if (pll) {
 		return pm_clock_pll_get_parent(pll, clock_id, parent_index);
+	}
 
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
-	if (status != PM_RET_SUCCESS)
+	if (status != PM_RET_SUCCESS) {
 		return status;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
@@ -1522,6 +1544,7 @@
 	default:
 		data[0] = PM_RET_ERROR_ARGS;
 		WARN("Unimplemented query service call: 0x%x\n", qid);
+		break;
 	}
 }
 
@@ -1614,12 +1637,14 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL)
+	if (nid < NODE_APLL || nid > NODE_IOPLL) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Check if parameter ID is valid and return an error if it's not */
-	if (param_id >= PM_PLL_PARAM_MAX)
+	if (param_id >= PM_PLL_PARAM_MAX) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
@@ -1642,12 +1667,14 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL)
+	if (nid < NODE_APLL || nid > NODE_IOPLL) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Check if parameter ID is valid and return an error if it's not */
-	if (param_id >= PM_PLL_PARAM_MAX)
+	if (param_id >= PM_PLL_PARAM_MAX) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
@@ -1672,12 +1699,14 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL)
+	if (nid < NODE_APLL || nid > NODE_IOPLL) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Check if PLL mode is valid */
-	if (mode >= PM_PLL_MODE_MAX)
+	if (mode >= PM_PLL_MODE_MAX) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
@@ -1697,8 +1726,9 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL)
+	if (nid < NODE_APLL || nid > NODE_IOPLL) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
@@ -1733,8 +1763,9 @@
 	if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
 			((CSUDMA_BASE & address) != CSUDMA_BASE) &&
 			((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
-			((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE))
+			((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
 		return PM_RET_ERROR_ACCESS;
+	}
 
 	switch (register_access_id) {
 	case CONFIG_REG_WRITE:
@@ -1746,6 +1777,7 @@
 	default:
 		ret = PM_RET_ERROR_ARGS;
 		WARN("Unimplemented register_access call\n\r");
+		break;
 	}
 	return ret;
 }
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 163e891..1f54430 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -188,8 +188,9 @@
 		 * If NODE_EXTERN could not be set as wake source, proceed with
 		 * standard suspend (no one will wake the system otherwise)
 		 */
-		if (ret == PM_RET_SUCCESS)
+		if (ret == PM_RET_SUCCESS) {
 			return;
+		}
 	}
 
 	zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set));
@@ -198,8 +199,9 @@
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
 		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
 
-		if (!reg)
+		if (!reg) {
 			continue;
+		}
 
 		while (reg) {
 			enum pm_node_id node;
@@ -208,8 +210,9 @@
 			idx = __builtin_ctz(lowest_set);
 			irq = base_irq + idx;
 
-			if (irq > IRQ_MAX)
+			if (irq > IRQ_MAX) {
 				break;
+			}
 
 			node = irq_to_pm_node(irq);
 			reg &= ~lowest_set;
@@ -231,8 +234,9 @@
  */
 const struct pm_proc *pm_get_proc(unsigned int cpuid)
 {
-	if (cpuid < ARRAY_SIZE(pm_procs_all))
+	if (cpuid < ARRAY_SIZE(pm_procs_all)) {
 		return &pm_procs_all[cpuid];
+	}
 
 	return NULL;
 }
@@ -246,8 +250,9 @@
 const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
 {
 	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
-		if (nid == pm_procs_all[i].node_id)
+		if (nid == pm_procs_all[i].node_id) {
 			return &pm_procs_all[i];
+		}
 	}
 	return NULL;
 }
@@ -261,8 +266,9 @@
 static unsigned int pm_get_cpuid(enum pm_node_id nid)
 {
 	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
-		if (pm_procs_all[i].node_id == nid)
+		if (pm_procs_all[i].node_id == nid) {
 			return i;
+		}
 	}
 	return UNDEFINED_CPUID;
 }
@@ -280,8 +286,9 @@
 {
 	bakery_lock_get(&pm_client_secure_lock);
 
-	if (state == PM_STATE_SUSPEND_TO_RAM)
+	if (state == PM_STATE_SUSPEND_TO_RAM) {
 		pm_client_set_wakeup_sources();
+	}
 
 	/* Set powerdown request */
 	mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask);
@@ -320,8 +327,9 @@
 {
 	unsigned int cpuid = pm_get_cpuid(proc->node_id);
 
-	if (cpuid == UNDEFINED_CPUID)
+	if (cpuid == UNDEFINED_CPUID) {
 		return;
+	}
 
 	bakery_lock_get(&pm_client_secure_lock);
 
@@ -336,8 +344,9 @@
 enum pm_ret_status pm_set_suspend_mode(uint32_t mode)
 {
 	if ((mode != PM_SUSPEND_MODE_STD) &&
-	    (mode != PM_SUSPEND_MODE_POWER_OFF))
+	    (mode != PM_SUSPEND_MODE_POWER_OFF)) {
 		return PM_RET_ERROR_ARGS;
+	}
 
 	suspend_mode = mode;
 	return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 114da33..4a6095c 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -13,9 +13,9 @@
 #include "pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT	0x8200ff00
-#define ZYNQMP_SIP_SVC_UID		0x8200ff01
-#define ZYNQMP_SIP_SVC_VERSION		0x8200ff03
+#define ZYNQMP_SIP_SVC_CALL_COUNT	U(0x8200ff00)
+#define ZYNQMP_SIP_SVC_UID		U(0x8200ff01)
+#define ZYNQMP_SIP_SVC_VERSION		U(0x8200ff03)
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR	0
@@ -100,6 +100,6 @@
 		sip_svc,
 		OEN_SIP_START,
 		OEN_SIP_END,
-		SMC_TYPE_FAST,
+		(uint8_t)SMC_TYPE_FAST,
 		sip_svc_setup,
 		sip_svc_smc_handler);
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index f57369f..4ea3c6a 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -25,67 +25,67 @@
 	/* APU IPI */
 	{
 		.ipi_bit_mask = 0x1,
-		.ipi_reg_base = 0xFF300000,
+		.ipi_reg_base = 0xFF300000U,
 		.secure_only = 0,
 	},
 	/* RPU0 IPI */
 	{
 		.ipi_bit_mask = 0x100,
-		.ipi_reg_base = 0xFF310000,
+		.ipi_reg_base = 0xFF310000U,
 		.secure_only = 0,
 	},
 	/* RPU1 IPI */
 	{
 		.ipi_bit_mask = 0x200,
-		.ipi_reg_base = 0xFF320000,
+		.ipi_reg_base = 0xFF320000U,
 		.secure_only = 0,
 	},
 	/* PMU0 IPI */
 	{
 		.ipi_bit_mask = 0x10000,
-		.ipi_reg_base = 0xFF330000,
+		.ipi_reg_base = 0xFF330000U,
 		.secure_only = IPI_SECURE_MASK,
 	},
 	/* PMU1 IPI */
 	{
 		.ipi_bit_mask = 0x20000,
-		.ipi_reg_base = 0xFF331000,
+		.ipi_reg_base = 0xFF331000U,
 		.secure_only = 0,
 	},
 	/* PMU2 IPI */
 	{
 		.ipi_bit_mask = 0x40000,
-		.ipi_reg_base = 0xFF332000,
+		.ipi_reg_base = 0xFF332000U,
 		.secure_only = IPI_SECURE_MASK,
 	},
 	/* PMU3 IPI */
 	{
 		.ipi_bit_mask = 0x80000,
-		.ipi_reg_base = 0xFF333000,
+		.ipi_reg_base = 0xFF333000U,
 		.secure_only = IPI_SECURE_MASK,
 	},
 	/* PL0 IPI */
 	{
 		.ipi_bit_mask = 0x1000000,
-		.ipi_reg_base = 0xFF340000,
+		.ipi_reg_base = 0xFF340000U,
 		.secure_only = 0,
 	},
 	/* PL1 IPI */
 	{
 		.ipi_bit_mask = 0x2000000,
-		.ipi_reg_base = 0xFF350000,
+		.ipi_reg_base = 0xFF350000U,
 		.secure_only = 0,
 	},
 	/* PL2 IPI */
 	{
 		.ipi_bit_mask = 0x4000000,
-		.ipi_reg_base = 0xFF360000,
+		.ipi_reg_base = 0xFF360000U,
 		.secure_only = 0,
 	},
 	/* PL3 IPI */
 	{
 		.ipi_bit_mask = 0x8000000,
-		.ipi_reg_base = 0xFF370000,
+		.ipi_reg_base = 0xFF370000U,
 		.secure_only = 0,
 	},
 };
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S b/services/std_svc/spm/common/aarch64/spm_helpers.S
similarity index 96%
rename from services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
rename to services/std_svc/spm/common/aarch64/spm_helpers.S
index 2c3aaf7..95e69fb 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
+++ b/services/std_svc/spm/common/aarch64/spm_helpers.S
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <asm_macros.S>
-#include "../spm_mm_private.h"
+#include "spm_common.h"
 
 	.global spm_secure_partition_enter
 	.global spm_secure_partition_exit
diff --git a/services/std_svc/spm/common/include/spm_common.h b/services/std_svc/spm/common/include/spm_common.h
new file mode 100644
index 0000000..68805fc
--- /dev/null
+++ b/services/std_svc/spm/common/include/spm_common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_COMMON_H
+#define SPM_COMMON_H
+
+#include <context.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define SP_C_RT_CTX_X19		0x0
+#define SP_C_RT_CTX_X20		0x8
+#define SP_C_RT_CTX_X21		0x10
+#define SP_C_RT_CTX_X22		0x18
+#define SP_C_RT_CTX_X23		0x20
+#define SP_C_RT_CTX_X24		0x28
+#define SP_C_RT_CTX_X25		0x30
+#define SP_C_RT_CTX_X26		0x38
+#define SP_C_RT_CTX_X27		0x40
+#define SP_C_RT_CTX_X28		0x48
+#define SP_C_RT_CTX_X29		0x50
+#define SP_C_RT_CTX_X30		0x58
+
+#define SP_C_RT_CTX_SIZE	0x60
+#define SP_C_RT_CTX_ENTRIES	(SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/* Assembly helpers */
+uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
+void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPM_COMMON_H */
diff --git a/services/std_svc/spm/common/spm.mk b/services/std_svc/spm/common/spm.mk
new file mode 100644
index 0000000..9aa96be
--- /dev/null
+++ b/services/std_svc/spm/common/spm.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+        $(error "Error: SPM is only supported on aarch64.")
+endif
+
+INCLUDES	+=	-Iservices/std_svc/spm/common/include
+
+SPM_SOURCES	:=	$(addprefix services/std_svc/spm/common/,\
+			${ARCH}/spm_helpers.S)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/el3_spmc/logical_sp.c b/services/std_svc/spm/el3_spmc/logical_sp.c
new file mode 100644
index 0000000..e080832
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/logical_sp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include "spmc.h"
+
+/*******************************************************************************
+ * Validate any logical partition descriptors before we initialise.
+ * Initialization of said partitions will be taken care of during SPMC boot.
+ ******************************************************************************/
+int el3_sp_desc_validate(void)
+{
+	struct el3_lp_desc *lp_array;
+
+	/*
+	 * Assert the number of descriptors is less than maximum allowed.
+	 * This constant should be define on a per platform basis.
+	 */
+	assert(EL3_LP_DESCS_COUNT <= MAX_EL3_LP_DESCS_COUNT);
+
+	/* Check the array bounds are valid. */
+	assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START);
+
+	/* If no logical partitions are implemented then simply bail out. */
+	if (EL3_LP_DESCS_COUNT == 0U) {
+		return 0;
+	}
+
+	lp_array = get_el3_lp_array();
+
+	for (unsigned int index = 0; index < EL3_LP_DESCS_COUNT; index++) {
+		struct el3_lp_desc *lp_desc = &lp_array[index];
+
+		/* Validate our logical partition descriptors. */
+		if (lp_desc == NULL) {
+			ERROR("Invalid Logical SP Descriptor\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * Ensure the ID follows the convention to indidate it resides
+		 * in the secure world.
+		 */
+		if (!ffa_is_secure_world_id(lp_desc->sp_id)) {
+			ERROR("Invalid Logical SP ID (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure we don't conflict with the SPMC partition ID. */
+		if (lp_desc->sp_id == FFA_SPMC_ID) {
+			ERROR("Logical SP ID clashes with SPMC ID(0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure the UUID is not the NULL UUID. */
+		if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 &&
+		    lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) {
+			ERROR("Invalid UUID for Logical SP (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure init function callback is registered. */
+		if (lp_desc->init == NULL) {
+			ERROR("Missing init function for Logical SP(0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure that LP only supports receiving direct requests. */
+		if (lp_desc->properties &
+		    ~(FFA_PARTITION_DIRECT_REQ_RECV)) {
+			ERROR("Invalid partition properties (0x%x)\n",
+			      lp_desc->properties);
+			return -EINVAL;
+		}
+
+		/* Ensure direct request function callback is registered. */
+		if (lp_desc->direct_req == NULL) {
+			ERROR("No Direct Req handler for Logical SP (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure that all partition IDs are unique. */
+		for (unsigned int inner_idx = index + 1;
+		     inner_idx < EL3_LP_DESCS_COUNT; inner_idx++) {
+			if (lp_desc->sp_id == lp_array[inner_idx].sp_id) {
+				ERROR("Duplicate SP ID Detected (0x%x)\n",
+				      lp_desc->sp_id);
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
new file mode 100644
index 0000000..0915d0b
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_H
+#define SPMC_H
+
+#include <stdint.h>
+
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <services/el3_spmc_logical_sp.h>
+#include "spm_common.h"
+
+/*
+ * Ranges of FF-A IDs for Normal world and Secure world components. The
+ * convention matches that used by other SPMCs i.e. Hafnium and OP-TEE.
+ */
+#define FFA_NWD_ID_BASE		0x0
+#define FFA_NWD_ID_LIMIT	0x7FFF
+#define FFA_SWD_ID_BASE		0x8000
+#define FFA_SWD_ID_LIMIT	SPMD_DIRECT_MSG_ENDPOINT_ID - 1
+#define FFA_SWD_ID_MASK		0x8000
+
+/* ID 0 is reserved for the normal world entity, (Hypervisor or OS Kernel). */
+#define FFA_NWD_ID		U(0)
+/* First ID is reserved for the SPMC */
+#define FFA_SPMC_ID		U(FFA_SWD_ID_BASE)
+/* SP IDs are allocated after the SPMC ID */
+#define FFA_SP_ID_BASE		(FFA_SPMC_ID + 1)
+/* Align with Hafnium implementation */
+#define INV_SP_ID		0x7FFF
+
+/* FF-A warm boot types. */
+#define FFA_WB_TYPE_S2RAM	0
+#define FFA_WB_TYPE_NOTS2RAM	1
+
+/*
+ * Runtime states of an execution context as per the FF-A v1.1 specification.
+ */
+enum sp_runtime_states {
+	RT_STATE_WAITING,
+	RT_STATE_RUNNING,
+	RT_STATE_PREEMPTED,
+	RT_STATE_BLOCKED
+};
+
+/*
+ * Runtime model of an execution context as per the FF-A v1.1 specification. Its
+ * value is valid only if the execution context is not in the waiting state.
+ */
+enum sp_runtime_model {
+	RT_MODEL_DIR_REQ,
+	RT_MODEL_RUN,
+	RT_MODEL_INIT,
+	RT_MODEL_INTR
+};
+
+enum sp_runtime_el {
+	EL1 = 0,
+	S_EL0,
+	S_EL1
+};
+
+enum sp_execution_state {
+	SP_STATE_AARCH64 = 0,
+	SP_STATE_AARCH32
+};
+
+enum mailbox_state {
+	/* There is no message in the mailbox. */
+	MAILBOX_STATE_EMPTY,
+
+	/* There is a message that has been populated in the mailbox. */
+	MAILBOX_STATE_FULL,
+};
+
+struct mailbox {
+	enum mailbox_state state;
+
+	/* RX/TX Buffers. */
+	void *rx_buffer;
+	const void *tx_buffer;
+
+	/* Size of RX/TX Buffer. */
+	uint32_t rxtx_page_count;
+
+	/* Lock access to mailbox. */
+	spinlock_t lock;
+};
+
+/*
+ * Execution context members for an SP. This is a bit like struct
+ * vcpu in a hypervisor.
+ */
+struct sp_exec_ctx {
+	/*
+	 * Store the stack address to restore C runtime context from after
+	 * returning from a synchronous entry into the SP.
+	 */
+	uint64_t c_rt_ctx;
+
+	/* Space to maintain the architectural state of an SP. */
+	cpu_context_t cpu_ctx;
+
+	/* Track the current runtime state of the SP. */
+	enum sp_runtime_states rt_state;
+
+	/* Track the current runtime model of the SP. */
+	enum sp_runtime_model rt_model;
+};
+
+/*
+ * Structure to describe the cumulative properties of an SP.
+ */
+struct secure_partition_desc {
+	/*
+	 * Execution contexts allocated to this endpoint. Ideally,
+	 * we need as many contexts as there are physical cpus only
+	 * for a S-EL1 SP which is MP-pinned.
+	 */
+	struct sp_exec_ctx ec[PLATFORM_CORE_COUNT];
+
+	/* ID of the Secure Partition. */
+	uint16_t sp_id;
+
+	/* Runtime EL. */
+	enum sp_runtime_el runtime_el;
+
+	/* Partition UUID. */
+	uint32_t uuid[4];
+
+	/* Partition Properties. */
+	uint32_t properties;
+
+	/* Supported FF-A Version. */
+	uint32_t ffa_version;
+
+	/* Execution State. */
+	enum sp_execution_state execution_state;
+
+	/* Mailbox tracking. */
+	struct mailbox mailbox;
+
+	/* Secondary entrypoint. Only valid for a S-EL1 SP. */
+	uintptr_t secondary_ep;
+};
+
+/*
+ * This define identifies the only SP that will be initialised and participate
+ * in FF-A communication. The implementation leaves the door open for more SPs
+ * to be managed in future but for now it is reasonable to assume that either a
+ * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
+ * to identify which SP descriptor to initialise and manage during SP runtime.
+ */
+#define ACTIVE_SP_DESC_INDEX	0
+
+/*
+ * Structure to describe the cumulative properties of the Hypervisor and
+ * NS-Endpoints.
+ */
+struct ns_endpoint_desc {
+	/*
+	 * ID of the NS-Endpoint or Hypervisor.
+	 */
+	uint16_t ns_ep_id;
+
+	/*
+	 * Mailbox tracking.
+	 */
+	struct mailbox mailbox;
+
+	/*
+	 * Supported FF-A Version
+	 */
+	uint32_t ffa_version;
+};
+
+/* Setup Function for different SP types. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+			  entry_point_info_t *ep_info);
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+		       entry_point_info_t *ep_info);
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+			      entry_point_info_t *ep_info);
+
+/*
+ * Helper function to perform a synchronous entry into a SP.
+ */
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
+
+/*
+ * Helper function to obtain the descriptor of the current SP on a physical cpu.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void);
+
+/*
+ * Helper function to obtain the execution context of an SP on a
+ * physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
+
+/*
+ * Helper function to obtain the index of the execution context of an SP on a
+ * physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp);
+
+uint64_t spmc_ffa_error_return(void *handle, int error_code);
+
+/*
+ * Ensure a partition ID does not clash and follows the secure world convention.
+ */
+bool is_ffa_secure_id_valid(uint16_t partition_id);
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void);
+
+#endif /* SPMC_H */
diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk
new file mode 100644
index 0000000..8067c74
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+        $(error "Error: SPMC is only supported on aarch64.")
+endif
+
+SPMC_SOURCES	:=	$(addprefix services/std_svc/spm/el3_spmc/,	\
+			spmc_main.c				\
+			spmc_setup.c				\
+			logical_sp.c)
+
+# Specify platform specific logical partition implementation.
+SPMC_LP_SOURCES  := $(addprefix ${PLAT_DIR}/, \
+                    ${PLAT}_el3_spmc_logical_sp.c)
+
+
+SPMC_SOURCES += $(SPMC_LP_SOURCES)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
new file mode 100644
index 0000000..35def25
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
+#include <services/spmd_svc.h>
+#include "spmc.h"
+
+#include <platform_def.h>
+
+/*
+ * Allocate a secure partition descriptor to describe each SP in the system that
+ * does not reside at EL3.
+ */
+static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT];
+
+/*
+ * Allocate an NS endpoint descriptor to describe each VM and the Hypervisor in
+ * the system that interacts with a SP. It is used to track the Hypervisor
+ * buffer pair, version and ID for now. It could be extended to track VM
+ * properties when the SPMC supports indirect messaging.
+ */
+static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT];
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void)
+{
+	return (struct el3_lp_desc *) EL3_LP_DESCS_START;
+}
+
+/*
+ * Helper function to obtain the descriptor of the last SP to whom control was
+ * handed to on this physical cpu. Currently, we assume there is only one SP.
+ * TODO: Expand to track multiple partitions when required.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void)
+{
+	return &(sp_desc[ACTIVE_SP_DESC_INDEX]);
+}
+
+/*
+ * Helper function to obtain the execution context of an SP on the
+ * current physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp)
+{
+	return &(sp->ec[get_ec_index(sp)]);
+}
+
+/* Helper function to get pointer to SP context from its ID. */
+struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
+{
+	/* Check for SWd Partitions. */
+	for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+		if (sp_desc[i].sp_id == id) {
+			return &(sp_desc[i]);
+		}
+	}
+	return NULL;
+}
+
+/******************************************************************************
+ * This function returns to the place where spmc_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 void spmc_sp_synchronous_exit(struct sp_exec_ctx *ec, uint64_t rc)
+{
+	/*
+	 * The SPM must have initiated the original request through a
+	 * synchronous entry into the secure partition. Jump back to the
+	 * original C runtime context with the value of rc in x0;
+	 */
+	spm_secure_partition_exit(ec->c_rt_ctx, rc);
+
+	panic();
+}
+
+/*******************************************************************************
+ * Return FFA_ERROR with specified error code.
+ ******************************************************************************/
+uint64_t spmc_ffa_error_return(void *handle, int error_code)
+{
+	SMC_RET8(handle, FFA_ERROR,
+		 FFA_TARGET_INFO_MBZ, error_code,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ);
+}
+
+/******************************************************************************
+ * Helper function to validate a secure partition ID to ensure it does not
+ * conflict with any other FF-A component and follows the convention to
+ * indicate it resides within the secure world.
+ ******************************************************************************/
+bool is_ffa_secure_id_valid(uint16_t partition_id)
+{
+	struct el3_lp_desc *el3_lp_descs = get_el3_lp_array();
+
+	/* Ensure the ID is not the invalid partition ID. */
+	if (partition_id == INV_SP_ID) {
+		return false;
+	}
+
+	/* Ensure the ID is not the SPMD ID. */
+	if (partition_id == SPMD_DIRECT_MSG_ENDPOINT_ID) {
+		return false;
+	}
+
+	/*
+	 * Ensure the ID follows the convention to indicate it resides
+	 * in the secure world.
+	 */
+	if (!ffa_is_secure_world_id(partition_id)) {
+		return false;
+	}
+
+	/* Ensure we don't conflict with the SPMC partition ID. */
+	if (partition_id == FFA_SPMC_ID) {
+		return false;
+	}
+
+	/* Ensure we do not already have an SP context with this ID. */
+	if (spmc_get_sp_ctx(partition_id)) {
+		return false;
+	}
+
+	/* Ensure we don't clash with any Logical SP's. */
+	for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+		if (el3_lp_descs[i].sp_id == partition_id) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*******************************************************************************
+ * This function either forwards the request to the other world or returns
+ * with an ERET depending on the source of the call.
+ * We can assume that the destination is for an entity at a lower exception
+ * level as any messages destined for a logical SP resident in EL3 will have
+ * already been taken care of by the SPMC before entering this function.
+ ******************************************************************************/
+static uint64_t spmc_smc_return(uint32_t smc_fid,
+				bool secure_origin,
+				uint64_t x1,
+				uint64_t x2,
+				uint64_t x3,
+				uint64_t x4,
+				void *handle,
+				void *cookie,
+				uint64_t flags,
+				uint16_t dst_id)
+{
+	/* If the destination is in the normal world always go via the SPMD. */
+	if (ffa_is_normal_world_id(dst_id)) {
+		return spmd_smc_handler(smc_fid, x1, x2, x3, x4,
+					cookie, handle, flags);
+	}
+	/*
+	 * If the caller is secure and we want to return to the secure world,
+	 * ERET directly.
+	 */
+	else if (secure_origin && ffa_is_secure_world_id(dst_id)) {
+		SMC_RET5(handle, smc_fid, x1, x2, x3, x4);
+	}
+	/* If we originated in the normal world then switch contexts. */
+	else if (!secure_origin && ffa_is_secure_world_id(dst_id)) {
+		return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2,
+					     x3, x4, handle);
+	} else {
+		/* Unknown State. */
+		panic();
+	}
+
+	/* Shouldn't be Reached. */
+	return 0;
+}
+
+/*******************************************************************************
+ * FF-A ABI Handlers.
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Helper function to validate arg2 as part of a direct message.
+ ******************************************************************************/
+static inline bool direct_msg_validate_arg2(uint64_t x2)
+{
+	/*
+	 * We currently only support partition messages, therefore ensure x2 is
+	 * not set.
+	 */
+	if (x2 != (uint64_t) 0) {
+		VERBOSE("Arg2 MBZ for partition messages (0x%lx).\n", x2);
+		return false;
+	}
+	return true;
+}
+
+/*******************************************************************************
+ * Handle direct request messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_req_smc_handler(uint32_t smc_fid,
+				       bool secure_origin,
+				       uint64_t x1,
+				       uint64_t x2,
+				       uint64_t x3,
+				       uint64_t x4,
+				       void *cookie,
+				       void *handle,
+				       uint64_t flags)
+{
+	uint16_t dst_id = ffa_endpoint_destination(x1);
+	struct el3_lp_desc *el3_lp_descs;
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+
+	/* Check if arg2 has been populated correctly based on message type. */
+	if (!direct_msg_validate_arg2(x2)) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	el3_lp_descs = get_el3_lp_array();
+
+	/* Check if the request is destined for a Logical Partition. */
+	for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
+		if (el3_lp_descs[i].sp_id == dst_id) {
+			return el3_lp_descs[i].direct_req(
+					smc_fid, secure_origin, x1, x2, x3, x4,
+					cookie, handle, flags);
+		}
+	}
+
+	/*
+	 * If the request was not targeted to a LSP and from the secure world
+	 * then it is invalid since a SP cannot call into the Normal world and
+	 * there is no other SP to call into. If there are other SPs in future
+	 * then the partition runtime model would need to be validated as well.
+	 */
+	if (secure_origin) {
+		VERBOSE("Direct request not supported to the Normal World.\n");
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Check if the SP ID is valid. */
+	sp = spmc_get_sp_ctx(dst_id);
+	if (sp == NULL) {
+		VERBOSE("Direct request to unknown partition ID (0x%x).\n",
+			dst_id);
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/*
+	 * Check that the target execution context is in a waiting state before
+	 * forwarding the direct request to it.
+	 */
+	idx = get_ec_index(sp);
+	if (sp->ec[idx].rt_state != RT_STATE_WAITING) {
+		VERBOSE("SP context on core%u is not waiting (%u).\n",
+			idx, sp->ec[idx].rt_model);
+		return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
+	}
+
+	/*
+	 * Everything checks out so forward the request to the SP after updating
+	 * its state and runtime model.
+	 */
+	sp->ec[idx].rt_state = RT_STATE_RUNNING;
+	sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
+	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+			       handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * Handle direct response messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
+					bool secure_origin,
+					uint64_t x1,
+					uint64_t x2,
+					uint64_t x3,
+					uint64_t x4,
+					void *cookie,
+					void *handle,
+					uint64_t flags)
+{
+	uint16_t dst_id = ffa_endpoint_destination(x1);
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+
+	/* Check if arg2 has been populated correctly based on message type. */
+	if (!direct_msg_validate_arg2(x2)) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Check that the response did not originate from the Normal world. */
+	if (!secure_origin) {
+		VERBOSE("Direct Response not supported from Normal World.\n");
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/*
+	 * Check that the response is either targeted to the Normal world or the
+	 * SPMC e.g. a PM response.
+	 */
+	if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) {
+		VERBOSE("Direct response to invalid partition ID (0x%x).\n",
+			dst_id);
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Obtain the SP descriptor and update its runtime state. */
+	sp = spmc_get_sp_ctx(ffa_endpoint_source(x1));
+	if (sp == NULL) {
+		VERBOSE("Direct response to unknown partition ID (0x%x).\n",
+			dst_id);
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Sanity check state is being tracked correctly in the SPMC. */
+	idx = get_ec_index(sp);
+	assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+	/* Ensure SP execution context was in the right runtime model. */
+	if (sp->ec[idx].rt_model != RT_MODEL_DIR_REQ) {
+		VERBOSE("SP context on core%u not handling direct req (%u).\n",
+			idx, sp->ec[idx].rt_model);
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	/* Update the state of the SP execution context. */
+	sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+	/*
+	 * If the receiver is not the SPMC then forward the response to the
+	 * Normal world.
+	 */
+	if (dst_id == FFA_SPMC_ID) {
+		spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+		/* Should not get here. */
+		panic();
+	}
+
+	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+			       handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * This function handles the FFA_MSG_WAIT SMC to allow an SP to relinquish its
+ * cycles.
+ ******************************************************************************/
+static uint64_t msg_wait_handler(uint32_t smc_fid,
+				 bool secure_origin,
+				 uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *cookie,
+				 void *handle,
+				 uint64_t flags)
+{
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+
+	/*
+	 * Check that the response did not originate from the Normal world as
+	 * only the secure world can call this ABI.
+	 */
+	if (!secure_origin) {
+		VERBOSE("Normal world cannot call FFA_MSG_WAIT.\n");
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	/* Get the descriptor of the SP that invoked FFA_MSG_WAIT. */
+	sp = spmc_get_current_sp_ctx();
+	if (sp == NULL) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/*
+	 * Get the execution context of the SP that invoked FFA_MSG_WAIT.
+	 */
+	idx = get_ec_index(sp);
+
+	/* Ensure SP execution context was in the right runtime model. */
+	if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	/* Sanity check the state is being tracked correctly in the SPMC. */
+	assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+	/*
+	 * Perform a synchronous exit if the partition was initialising. The
+	 * state is updated after the exit.
+	 */
+	if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+		spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+		/* Should not get here */
+		panic();
+	}
+
+	/* Update the state of the SP execution context. */
+	sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+	/* Resume normal world if a secure interrupt was handled. */
+	if (sp->ec[idx].rt_model == RT_MODEL_INTR) {
+		/* FFA_MSG_WAIT can only be called from the secure world. */
+		unsigned int secure_state_in = SECURE;
+		unsigned int secure_state_out = NON_SECURE;
+
+		cm_el1_sysregs_context_save(secure_state_in);
+		cm_el1_sysregs_context_restore(secure_state_out);
+		cm_set_next_eret_context(secure_state_out);
+		SMC_RET0(cm_get_context(secure_state_out));
+	}
+
+	/* Forward the response to the Normal world. */
+	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+			       handle, cookie, flags, FFA_NWD_ID);
+}
+
+static uint64_t ffa_error_handler(uint32_t smc_fid,
+				 bool secure_origin,
+				 uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *cookie,
+				 void *handle,
+				 uint64_t flags)
+{
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+
+	/* Check that the response did not originate from the Normal world. */
+	if (!secure_origin) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	/* Get the descriptor of the SP that invoked FFA_ERROR. */
+	sp = spmc_get_current_sp_ctx();
+	if (sp == NULL) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Get the execution context of the SP that invoked FFA_ERROR. */
+	idx = get_ec_index(sp);
+
+	/*
+	 * We only expect FFA_ERROR to be received during SP initialisation
+	 * otherwise this is an invalid call.
+	 */
+	if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+		ERROR("SP 0x%x failed to initialize.\n", sp->sp_id);
+		spmc_sp_synchronous_exit(&sp->ec[idx], x2);
+		/* Should not get here. */
+		panic();
+	}
+
+	return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * This function will parse the Secure Partition Manifest. From manifest, it
+ * will fetch details for preparing Secure partition image context and secure
+ * partition image boot arguments if any.
+ ******************************************************************************/
+static int sp_manifest_parse(void *sp_manifest, int offset,
+			     struct secure_partition_desc *sp,
+			     entry_point_info_t *ep_info)
+{
+	int32_t ret, node;
+	uint32_t config_32;
+
+	/*
+	 * Look for the mandatory fields that are expected to be present in
+	 * the SP manifests.
+	 */
+	node = fdt_path_offset(sp_manifest, "/");
+	if (node < 0) {
+		ERROR("Did not find root node.\n");
+		return node;
+	}
+
+	ret = fdt_read_uint32_array(sp_manifest, node, "uuid",
+				    ARRAY_SIZE(sp->uuid), sp->uuid);
+	if (ret != 0) {
+		ERROR("Missing Secure Partition UUID.\n");
+		return ret;
+	}
+
+	ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32);
+	if (ret != 0) {
+		ERROR("Missing SP Exception Level information.\n");
+		return ret;
+	}
+
+	sp->runtime_el = config_32;
+
+	ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32);
+	if (ret != 0) {
+		ERROR("Missing Secure Partition FF-A Version.\n");
+		return ret;
+	}
+
+	sp->ffa_version = config_32;
+
+	ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32);
+	if (ret != 0) {
+		ERROR("Missing Secure Partition Execution State.\n");
+		return ret;
+	}
+
+	sp->execution_state = config_32;
+
+	ret = fdt_read_uint32(sp_manifest, node,
+			      "execution-ctx-count", &config_32);
+
+	if (ret != 0) {
+		ERROR("Missing SP Execution Context Count.\n");
+		return ret;
+	}
+
+	/*
+	 * Ensure this field is set correctly in the manifest however
+	 * since this is currently a hardcoded value for S-EL1 partitions
+	 * we don't need to save it here, just validate.
+	 */
+	if (config_32 != PLATFORM_CORE_COUNT) {
+		ERROR("SP Execution Context Count (%u) must be %u.\n",
+			config_32, PLATFORM_CORE_COUNT);
+		return -EINVAL;
+	}
+
+	/*
+	 * Look for the optional fields that are expected to be present in
+	 * an SP manifest.
+	 */
+	ret = fdt_read_uint32(sp_manifest, node, "id", &config_32);
+	if (ret != 0) {
+		WARN("Missing Secure Partition ID.\n");
+	} else {
+		if (!is_ffa_secure_id_valid(config_32)) {
+			ERROR("Invalid Secure Partition ID (0x%x).\n",
+			      config_32);
+			return -EINVAL;
+		}
+		sp->sp_id = config_32;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function gets the Secure Partition Manifest base and maps the manifest
+ * region.
+ * Currently only one Secure Partition manifest is considered which is used to
+ * prepare the context for the single Secure Partition.
+ ******************************************************************************/
+static int find_and_prepare_sp_context(void)
+{
+	void *sp_manifest;
+	uintptr_t manifest_base;
+	uintptr_t manifest_base_align;
+	entry_point_info_t *next_image_ep_info;
+	int32_t ret;
+	struct secure_partition_desc *sp;
+
+	next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+	if (next_image_ep_info == NULL) {
+		WARN("No Secure Partition image provided by BL2.\n");
+		return -ENOENT;
+	}
+
+	sp_manifest = (void *)next_image_ep_info->args.arg0;
+	if (sp_manifest == NULL) {
+		WARN("Secure Partition manifest absent.\n");
+		return -ENOENT;
+	}
+
+	manifest_base = (uintptr_t)sp_manifest;
+	manifest_base_align = page_align(manifest_base, DOWN);
+
+	/*
+	 * Map the secure partition manifest region in the EL3 translation
+	 * regime.
+	 * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base
+	 * alignment the region of 1 PAGE_SIZE from manifest align base may
+	 * not completely accommodate the secure partition manifest region.
+	 */
+	ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align,
+				      manifest_base_align,
+				      PAGE_SIZE * 2,
+				      MT_RO_DATA);
+	if (ret != 0) {
+		ERROR("Error while mapping SP manifest (%d).\n", ret);
+		return ret;
+	}
+
+	ret = fdt_node_offset_by_compatible(sp_manifest, -1,
+					    "arm,ffa-manifest-1.0");
+	if (ret < 0) {
+		ERROR("Error happened in SP manifest reading.\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Store the size of the manifest so that it can be used later to pass
+	 * the manifest as boot information later.
+	 */
+	next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest);
+	INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1);
+
+	/*
+	 * Select an SP descriptor for initialising the partition's execution
+	 * context on the primary CPU.
+	 */
+	sp = spmc_get_current_sp_ctx();
+
+	/* Initialize entry point information for the SP */
+	SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1,
+		       SECURE | EP_ST_ENABLE);
+
+	/* Parse the SP manifest. */
+	ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info);
+	if (ret != 0) {
+		ERROR("Error in Secure Partition manifest parsing.\n");
+		return ret;
+	}
+
+	/* Check that the runtime EL in the manifest was correct. */
+	if (sp->runtime_el != S_EL1) {
+		ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
+		return -EINVAL;
+	}
+
+	/* Perform any common initialisation. */
+	spmc_sp_common_setup(sp, next_image_ep_info);
+
+	/* Perform any initialisation specific to S-EL1 SPs. */
+	spmc_el1_sp_setup(sp, next_image_ep_info);
+
+	/* Initialize the SP context with the required ep info. */
+	spmc_sp_common_ep_commit(sp, next_image_ep_info);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+static int32_t logical_sp_init(void)
+{
+	int32_t rc = 0;
+	struct el3_lp_desc *el3_lp_descs;
+
+	/* Perform initial validation of the Logical Partitions. */
+	rc = el3_sp_desc_validate();
+	if (rc != 0) {
+		ERROR("Logical Partition validation failed!\n");
+		return rc;
+	}
+
+	el3_lp_descs = get_el3_lp_array();
+
+	INFO("Logical Secure Partition init start.\n");
+	for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+		rc = el3_lp_descs[i].init();
+		if (rc != 0) {
+			ERROR("Logical SP (0x%x) Failed to Initialize\n",
+			      el3_lp_descs[i].sp_id);
+			return rc;
+		}
+		VERBOSE("Logical SP (0x%x) Initialized\n",
+			      el3_lp_descs[i].sp_id);
+	}
+
+	INFO("Logical Secure Partition init completed.\n");
+
+	return rc;
+}
+
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec)
+{
+	uint64_t rc;
+
+	assert(ec != NULL);
+
+	/* Assign the context of the SP to this CPU */
+	cm_set_context(&(ec->cpu_ctx), SECURE);
+
+	/* Restore the context assigned above */
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_next_eret_context(SECURE);
+
+	/* Invalidate TLBs at EL1. */
+	tlbivmalle1();
+	dsbish();
+
+	/* Enter Secure Partition */
+	rc = spm_secure_partition_enter(&ec->c_rt_ctx);
+
+	/* Save secure state */
+	cm_el1_sysregs_context_save(SECURE);
+
+	return rc;
+}
+
+/*******************************************************************************
+ * SPMC Helper Functions.
+ ******************************************************************************/
+static int32_t sp_init(void)
+{
+	uint64_t rc;
+	struct secure_partition_desc *sp;
+	struct sp_exec_ctx *ec;
+
+	sp = spmc_get_current_sp_ctx();
+	ec = spmc_get_sp_ec(sp);
+	ec->rt_model = RT_MODEL_INIT;
+	ec->rt_state = RT_STATE_RUNNING;
+
+	INFO("Secure Partition (0x%x) init start.\n", sp->sp_id);
+
+	rc = spmc_sp_synchronous_entry(ec);
+	if (rc != 0) {
+		/* Indicate SP init was not successful. */
+		ERROR("SP (0x%x) failed to initialize (%lu).\n",
+		      sp->sp_id, rc);
+		return 0;
+	}
+
+	ec->rt_state = RT_STATE_WAITING;
+	INFO("Secure Partition initialized.\n");
+
+	return 1;
+}
+
+static void initalize_sp_descs(void)
+{
+	struct secure_partition_desc *sp;
+
+	for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+		sp = &sp_desc[i];
+		sp->sp_id = INV_SP_ID;
+		sp->mailbox.rx_buffer = NULL;
+		sp->mailbox.tx_buffer = NULL;
+		sp->mailbox.state = MAILBOX_STATE_EMPTY;
+		sp->secondary_ep = 0;
+	}
+}
+
+static void initalize_ns_ep_descs(void)
+{
+	struct ns_endpoint_desc *ns_ep;
+
+	for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) {
+		ns_ep = &ns_ep_desc[i];
+		/*
+		 * Clashes with the Hypervisor ID but will not be a
+		 * problem in practice.
+		 */
+		ns_ep->ns_ep_id = 0;
+		ns_ep->ffa_version = 0;
+		ns_ep->mailbox.rx_buffer = NULL;
+		ns_ep->mailbox.tx_buffer = NULL;
+		ns_ep->mailbox.state = MAILBOX_STATE_EMPTY;
+	}
+}
+
+/*******************************************************************************
+ * Initialize SPMC attributes for the SPMD.
+ ******************************************************************************/
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs)
+{
+	spmc_attrs->major_version = FFA_VERSION_MAJOR;
+	spmc_attrs->minor_version = FFA_VERSION_MINOR;
+	spmc_attrs->exec_state = MODE_RW_64;
+	spmc_attrs->spmc_id = FFA_SPMC_ID;
+}
+
+/*******************************************************************************
+ * Initialize contexts of all Secure Partitions.
+ ******************************************************************************/
+int32_t spmc_setup(void)
+{
+	int32_t ret;
+
+	/* Initialize endpoint descriptors */
+	initalize_sp_descs();
+	initalize_ns_ep_descs();
+
+	/* Setup logical SPs. */
+	ret = logical_sp_init();
+	if (ret != 0) {
+		ERROR("Failed to initialize Logical Partitions.\n");
+		return ret;
+	}
+
+	/* Perform physical SP setup. */
+
+	/* Disable MMU at EL1 (initialized by BL2) */
+	disable_mmu_icache_el1();
+
+	/* Initialize context of the SP */
+	INFO("Secure Partition context setup start.\n");
+
+	ret = find_and_prepare_sp_context();
+	if (ret != 0) {
+		ERROR("Error in SP finding and context preparation.\n");
+		return ret;
+	}
+
+	/* Register init function for deferred init.  */
+	bl31_register_bl32_init(&sp_init);
+
+	INFO("Secure Partition setup done.\n");
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Secure Partition Manager SMC handler.
+ ******************************************************************************/
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+			  bool secure_origin,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags)
+{
+	switch (smc_fid) {
+
+	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+		return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
+					      x3, x4, cookie, handle, flags);
+
+	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+		return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
+					       x3, x4, cookie, handle, flags);
+
+	case FFA_MSG_WAIT:
+		return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+					cookie, handle, flags);
+
+	case FFA_ERROR:
+		return ffa_error_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+					cookie, handle, flags);
+
+	default:
+		WARN("Unsupported FF-A call 0x%08x.\n", smc_fid);
+		break;
+	}
+	return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
new file mode 100644
index 0000000..7b23c9e
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <services/ffa_svc.h>
+#include "spm_common.h"
+#include "spmc.h"
+
+#include <platform_def.h>
+
+/*
+ * We are assuming that the index of the execution
+ * context used is the linear index of the current physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp)
+{
+	return plat_my_core_pos();
+}
+
+/* S-EL1 partition specific initialisation. */
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+		       entry_point_info_t *ep_info)
+{
+	/* Sanity check input arguments. */
+	assert(sp != NULL);
+	assert(ep_info != NULL);
+
+	/* Initialise the SPSR for S-EL1 SPs. */
+	ep_info->spsr =	SPSR_64(MODE_EL1, MODE_SP_ELX,
+				DISABLE_ALL_EXCEPTIONS);
+
+	/*
+	 * Check whether setup is being performed for the primary or a secondary
+	 * execution context. In the latter case, indicate to the SP that this
+	 * is a warm boot.
+	 * TODO: This check would need to be reworked if the same entry point is
+	 * used for both primary and secondary initialisation.
+	 */
+	if (sp->secondary_ep != 0U) {
+		/*
+		 * Sanity check that the secondary entry point is still what was
+		 * originally set.
+		 */
+		assert(sp->secondary_ep == ep_info->pc);
+		ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
+	}
+}
+
+/* Common initialisation for all SPs. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+			  entry_point_info_t *ep_info)
+{
+	uint16_t sp_id;
+
+	/* Assign FF-A Partition ID if not already assigned. */
+	if (sp->sp_id == INV_SP_ID) {
+		sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
+		/*
+		 * Ensure we don't clash with previously assigned partition
+		 * IDs.
+		 */
+		while (!is_ffa_secure_id_valid(sp_id)) {
+			sp_id++;
+
+			if (sp_id == FFA_SWD_ID_LIMIT) {
+				ERROR("Unable to determine valid SP ID.\n");
+				panic();
+			}
+		}
+		sp->sp_id = sp_id;
+	}
+
+	/*
+	 * We currently only support S-EL1 partitions so ensure this is the
+	 * case.
+	 */
+	assert(sp->runtime_el == S_EL1);
+
+	/*
+	 * Clear the general purpose registers. These should be populated as
+	 * required.
+	 */
+	zeromem(&ep_info->args, sizeof(ep_info->args));
+}
+
+/*
+ * Initialise the SP context now we have populated the common and EL specific
+ * entrypoint information.
+ */
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+			      entry_point_info_t *ep_info)
+{
+	cpu_context_t *cpu_ctx;
+
+	cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
+	print_entry_point_info(ep_info);
+	cm_setup_context(cpu_ctx, ep_info);
+}
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
similarity index 97%
rename from services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
rename to services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
index be4084c..836f75c 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
+++ b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
similarity index 78%
rename from services/std_svc/spm_mm/spm_mm.mk
rename to services/std_svc/spm/spm_mm/spm_mm.mk
index a87bdd8..78ef0c9 100644
--- a/services/std_svc/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,11 +17,10 @@
         $(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS")
 endif
 
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm_mm/,	\
-			${ARCH}/spm_mm_helpers.S			\
+SPM_MM_SOURCES	:=	$(addprefix services/std_svc/spm/spm_mm/,	\
 			${ARCH}/spm_mm_shim_exceptions.S		\
-			spm_mm_main.c				\
-			spm_mm_setup.c				\
+			spm_mm_main.c					\
+			spm_mm_setup.c					\
 			spm_mm_xlat.c)
 
 
diff --git a/services/std_svc/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_main.c
rename to services/std_svc/spm/spm_mm/spm_mm_main.c
index 14c0038..e71e65b 100644
--- a/services/std_svc/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@
 #include <services/spm_mm_svc.h>
 #include <smccc_helpers.h>
 
+#include "spm_common.h"
 #include "spm_mm_private.h"
 
 /*******************************************************************************
diff --git a/services/std_svc/spm_mm/spm_mm_private.h b/services/std_svc/spm/spm_mm/spm_mm_private.h
similarity index 88%
rename from services/std_svc/spm_mm/spm_mm_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_private.h
index 45b4789..0eff1c0 100644
--- a/services/std_svc/spm_mm/spm_mm_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #define SPM_MM_PRIVATE_H
 
 #include <context.h>
+#include "spm_common.h"
 
 /*******************************************************************************
  * Constants that allow assembler code to preserve callee-saved registers of the
@@ -51,9 +52,6 @@
 	spinlock_t state_lock;
 } sp_context_t;
 
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
 
 void spm_sp_setup(sp_context_t *sp_ctx);
 
diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_setup.c
rename to services/std_svc/spm/spm_mm/spm_mm_setup.c
index 9d681c2..04dc212 100644
--- a/services/std_svc/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -19,6 +19,7 @@
 #include <plat/common/platform.h>
 #include <services/spm_mm_partition.h>
 
+#include "spm_common.h"
 #include "spm_mm_private.h"
 #include "spm_mm_shim_private.h"
 
diff --git a/services/std_svc/spm_mm/spm_mm_shim_private.h b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
similarity index 90%
rename from services/std_svc/spm_mm/spm_mm_shim_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_shim_private.h
index 0c8d894..f69c748 100644
--- a/services/std_svc/spm_mm/spm_mm_shim_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/services/std_svc/spm_mm/spm_mm_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_xlat.c
rename to services/std_svc/spm/spm_mm/spm_mm_xlat.c
index eae597c..6261016 100644
--- a/services/std_svc/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 27a8382..5b131cd 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -24,6 +24,7 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
 #include <services/spmd_svc.h>
 #include <smccc_helpers.h>
 #include "spmd_private.h"
@@ -34,7 +35,8 @@
 static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
 
 /*******************************************************************************
- * SPM Core attribute information read from its manifest.
+ * SPM Core attribute information is read from its manifest if the SPMC is not
+ * at EL3. Else, it is populated from the SPMC directly.
  ******************************************************************************/
 static spmc_manifest_attribute_t spmc_attrs;
 
@@ -88,7 +90,9 @@
 				 uint64_t x2,
 				 uint64_t x3,
 				 uint64_t x4,
-				 void *handle);
+				 void *cookie,
+				 void *handle,
+				 uint64_t flags);
 
 /******************************************************************************
  * Builds an SPMD to SPMC direct message request.
@@ -385,8 +389,23 @@
  ******************************************************************************/
 int spmd_setup(void)
 {
-	void *spmc_manifest;
 	int rc;
+	void *spmc_manifest;
+
+	/*
+	 * If the SPMC is at EL3, then just initialise it directly. The
+	 * shenanigans of when it is at a lower EL are not needed.
+	 */
+	if (is_spmc_at_el3()) {
+		/* Allow the SPMC to populate its attributes directly. */
+		spmc_populate_attrs(&spmc_attrs);
+
+		rc = spmc_setup();
+		if (rc != 0) {
+			ERROR("SPMC initialisation failed 0x%x.\n", rc);
+		}
+		return rc;
+	}
 
 	spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 	if (spmc_ep_info == NULL) {
@@ -417,15 +436,15 @@
 }
 
 /*******************************************************************************
- * Forward SMC to the other security state
+ * Forward FF-A SMCs to the other security state.
  ******************************************************************************/
-static uint64_t spmd_smc_forward(uint32_t smc_fid,
-				 bool secure_origin,
-				 uint64_t x1,
-				 uint64_t x2,
-				 uint64_t x3,
-				 uint64_t x4,
-				 void *handle)
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+			       bool secure_origin,
+			       uint64_t x1,
+			       uint64_t x2,
+			       uint64_t x3,
+			       uint64_t x4,
+			       void *handle)
 {
 	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
@@ -458,6 +477,28 @@
 }
 
 /*******************************************************************************
+ * Forward SMCs to the other security state.
+ ******************************************************************************/
+static uint64_t spmd_smc_forward(uint32_t smc_fid,
+				 bool secure_origin,
+				 uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *cookie,
+				 void *handle,
+				 uint64_t flags)
+{
+	if (is_spmc_at_el3() && !secure_origin) {
+		return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+					cookie, handle, flags);
+	}
+	return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
+				     handle);
+
+}
+
+/*******************************************************************************
  * Return FFA_ERROR with specified error code
  ******************************************************************************/
 static uint64_t spmd_ffa_error_return(void *handle, int error_code)
@@ -484,6 +525,10 @@
  *****************************************************************************/
 static bool spmd_is_spmc_message(unsigned int ep)
 {
+	if (is_spmc_at_el3()) {
+		return false;
+	}
+
 	return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID)
 		&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
 }
@@ -502,6 +547,35 @@
 }
 
 /*******************************************************************************
+ * This function forwards FF-A SMCs to either the main SPMD handler or the
+ * SPMC at EL3, depending on the origin security state, if enabled.
+ ******************************************************************************/
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+			      uint64_t x1,
+			      uint64_t x2,
+			      uint64_t x3,
+			      uint64_t x4,
+			      void *cookie,
+			      void *handle,
+			      uint64_t flags)
+{
+	if (is_spmc_at_el3()) {
+		/*
+		 * If we have an SPMC at EL3 allow handling of the SMC first.
+		 * The SPMC will call back through to SPMD handler if required.
+		 */
+		if (is_caller_secure(flags)) {
+			return spmc_smc_handler(smc_fid,
+						is_caller_secure(flags),
+						x1, x2, x3, x4, cookie,
+						handle, flags);
+		}
+	}
+	return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+				handle, flags);
+}
+
+/*******************************************************************************
  * This function handles all SMCs in the range reserved for FFA. Each call is
  * either forwarded to the other security state or handled by the SPM dispatcher
  ******************************************************************************/
@@ -542,7 +616,8 @@
 		}
 
 		return spmd_smc_forward(smc_fid, secure_origin,
-					x1, x2, x3, x4, handle);
+					x1, x2, x3, x4, cookie,
+					handle, flags);
 		break; /* not reached */
 
 	case FFA_VERSION:
@@ -553,9 +628,11 @@
 		 * If caller is non secure and SPMC was initialized,
 		 * return SPMC's version.
 		 * Sanity check to "input_version".
+		 * If the EL3 SPMC is enabled, ignore the SPMC state as
+		 * this is not used.
 		 */
 		if ((input_version & FFA_VERSION_BIT31_MASK) ||
-			(ctx->state == SPMC_STATE_RESET)) {
+		    (!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
 			ret = FFA_ERROR_NOT_SUPPORTED;
 		} else if (!secure_origin) {
 			gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
@@ -610,7 +687,8 @@
 			 */
 			return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
 						FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-						FFA_PARAM_MBZ, gpregs);
+						FFA_PARAM_MBZ, cookie, gpregs,
+						flags);
 		} else {
 			ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
 					       FFA_VERSION_MINOR);
@@ -630,7 +708,8 @@
 		/* Forward SMC from Normal world to the SPM Core */
 		if (!secure_origin) {
 			return spmd_smc_forward(smc_fid, secure_origin,
-						x1, x2, x3, x4, handle);
+						x1, x2, x3, x4, cookie,
+						handle, flags);
 		}
 
 		/*
@@ -726,7 +805,8 @@
 		} else {
 			/* Forward direct message to the other world */
 			return spmd_smc_forward(smc_fid, secure_origin,
-				x1, x2, x3, x4, handle);
+						x1, x2, x3, x4, cookie,
+						handle, flags);
 		}
 		break; /* Not reached */
 
@@ -736,7 +816,8 @@
 		} else {
 			/* Forward direct message to the other world */
 			return spmd_smc_forward(smc_fid, secure_origin,
-				x1, x2, x3, x4, handle);
+						x1, x2, x3, x4, cookie,
+						handle, flags);
 		}
 		break; /* Not reached */
 
@@ -755,6 +836,7 @@
 	case FFA_NOTIFICATION_INFO_GET:
 	case FFA_NOTIFICATION_INFO_GET_SMC64:
 	case FFA_MSG_SEND2:
+	case FFA_RX_ACQUIRE:
 #endif
 	case FFA_MSG_RUN:
 		/*
@@ -791,7 +873,8 @@
 		 */
 
 		return spmd_smc_forward(smc_fid, secure_origin,
-					x1, x2, x3, x4, handle);
+					x1, x2, x3, x4, cookie,
+					handle, flags);
 		break; /* not reached */
 
 	case FFA_MSG_WAIT:
@@ -814,7 +897,8 @@
 		}
 
 		return spmd_smc_forward(smc_fid, secure_origin,
-					x1, x2, x3, x4, handle);
+					x1, x2, x3, x4, cookie,
+					handle, flags);
 		break; /* not reached */
 
 	case FFA_NORMAL_WORLD_RESUME:
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 4cd6a74..4c298c9 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -58,12 +58,6 @@
  */
 #define FFA_NS_ENDPOINT_ID			U(0)
 
-/* Mask and shift to check valid secure FF-A Endpoint ID. */
-#define SPMC_SECURE_ID_MASK			U(1)
-#define SPMC_SECURE_ID_SHIFT			U(15)
-
-#define SPMD_DIRECT_MSG_ENDPOINT_ID		U(FFA_ENDPOINT_ID_MAX - 1)
-
 /* Define SPMD target function IDs for framework messages to the SPMC */
 #define SPMD_FWK_MSG_BIT			BIT(31)
 #define SPMD_FWK_MSG_PSCI			U(0)
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index bfe26ca..b1e3db9 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -17,6 +17,7 @@
 #include <services/rmmd_svc.h>
 #include <services/sdei.h>
 #include <services/spm_mm_svc.h>
+#include <services/spmc_svc.h>
 #include <services/spmd_svc.h>
 #include <services/std_svc.h>
 #include <services/trng_svc.h>
@@ -147,8 +148,8 @@
 	 * dispatcher and return its return value
 	 */
 	if (is_ffa_fid(smc_fid)) {
-		return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
-					handle, flags);
+		return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					    handle, flags);
 	}
 #endif
 
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
old mode 100755
new mode 100644
index 82d5c1b..f4045d3
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -46,112 +46,187 @@
 }
 
 """
-
-import getopt
 import json
 import os
 import re
 import sys
 import uuid
+from spactions import SpSetupActions
 
-with open(sys.argv[2],'r') as in_file:
-    data = json.load(in_file)
-json_file = os.path.abspath(sys.argv[2])
-json_dir = os.path.dirname(json_file)
-gen_file = os.path.abspath(sys.argv[1])
-out_dir = os.path.abspath(sys.argv[3])
-dtb_dir = out_dir + "/fdts/"
 MAX_SP = 8
-dualroot = sys.argv[4].lower() == "dualroot"
-split = int(MAX_SP / 2)
-print(dtb_dir)
-platform_count = 1
-sip_count = 1
+UUID_LEN = 4
 
-with open(gen_file, 'w') as out_file:
-    for idx, key in enumerate(data.keys()):
+# Some helper functions to access args propagated to the action functions in
+# SpSetupActions framework.
+def check_sp_mk_gen(args :dict):
+    if "sp_gen_mk" not in args.keys():
+        raise Exception(f"Path to file sp_gen.mk needs to be in 'args'.")
 
-        pkg_num = idx + 1
+def check_out_dir(args :dict):
+    if "out_dir" not in args.keys() or not os.path.isdir(args["out_dir"]):
+        raise Exception("Define output folder with \'out_dir\' key.")
 
-        if (pkg_num > MAX_SP):
-            print("WARNING: Too many secure partitions\n")
-            exit(-1)
+def check_sp_layout_dir(args :dict):
+    if "sp_layout_dir" not in args.keys() or not os.path.isdir(args["sp_layout_dir"]):
+        raise Exception("Define output folder with \'sp_layout_dir\' key.")
 
-        if dualroot:
-            owner = data[key].get('owner')
-            if owner == "Plat":
-                if (platform_count > split):
-                    print("WARNING: Maximum Secure partitions by Plat " +
-                    "have been exceeded (" + str(split) + ")\n")
-                    exit(-1)
-                pkg_num = split + platform_count
-                platform_count += 1
-            elif (sip_count > split):
-                print("WARNING: Maximum Secure partitions by SiP " +
-                "have been exceeded (" + str(split) + ")\n")
-                exit(-1)
-            else:
-                pkg_num = sip_count
-                sip_count += 1
+def write_to_sp_mk_gen(content, args :dict):
+    check_sp_mk_gen(args)
+    with open(args["sp_gen_mk"], "a") as f:
+        f.write(f"{content}\n")
 
-        """
-        Append FDT_SOURCES
-        """
-        dts = os.path.join(json_dir, data[key]['pm'])
-        dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
-        out_file.write("FDT_SOURCES += " + dts + "\n")
+def get_sp_manifest_full_path(sp_node, args :dict):
+    check_sp_layout_dir(args)
+    return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["pm"]))
 
-        """
-        Update SPTOOL_ARGS
-        """
-        dst = out_dir + "/" + key + ".pkg"
-        src = [ json_dir + "/" + data[key]['image'] , dtb  ]
-        out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
+def get_sp_img_full_path(sp_node, args :dict):
+    check_sp_layout_dir(args)
+    return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["image"]))
 
-        if "uuid" in data[key]:
-            """
-            Extract the UUID from the JSON file if the SP entry has a 'uuid' field
-            """
-            uuid_std = uuid.UUID(data[key]['uuid'])
-        else:
-            """
-            Extract uuid from partition manifest
-            """
-            pm_file = open(dts)
-            for line in pm_file:
-                if "uuid" in line:
-                    # re.findall returns a list of string tuples.
-                    # uuid_hex is the first item in this list representing the four
-                    # uuid hex integers from the manifest uuid field. The heading
-                    # '0x' of the hexadecimal representation is stripped out.
-                    # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
-                    # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
-                    uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
+def get_sp_pkg(sp, args :dict):
+    check_out_dir(args)
+    return os.path.join(args["out_dir"], f"{sp}.pkg")
+
+def is_line_in_sp_gen(line, args :dict):
+    with open(args["sp_gen_mk"], "r") as f:
+        sppkg_rule = [l for l in f if line in l]
+    return len(sppkg_rule) is not 0
+
+def get_file_from_layout(node):
+    ''' Helper to fetch a file path from sp_layout.json. '''
+    if type(node) is dict and "file" in node.keys():
+        return node["file"]
+    return node
 
-            # uuid_hex is a list of four hex string values
-            if len(uuid_hex) != 4:
-                print("ERROR: malformed UUID")
-                exit(-1)
+def get_offset_from_layout(node):
+    ''' Helper to fetch an offset from sp_layout.json. '''
+    if type(node) is dict and "offset" in node.keys():
+        return int(node["offset"], 0)
+    return None
 
-            # The uuid field in SP manifest is the little endian representation
-            # mapped to arguments as described in SMCCC section 5.3.
-            # Convert each unsigned integer value to a big endian representation
-            # required by fiptool.
-            y=list(map(bytearray.fromhex, uuid_hex))
-            z=(int.from_bytes(y[0], byteorder='little', signed=False),
-            int.from_bytes(y[1], byteorder='little', signed=False),
-            int.from_bytes(y[2], byteorder='little', signed=False),
-            int.from_bytes(y[3], byteorder='little', signed=False))
-            uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+def get_image_offset(node):
+    ''' Helper to fetch image offset from sp_layout.json '''
+    return get_offset_from_layout(node["image"])
+
+def get_pm_offset(node):
+    ''' Helper to fetch pm offset from sp_layout.json '''
+    return get_offset_from_layout(node["pm"])
+
+@SpSetupActions.sp_action(global_action=True)
+def check_max_sps(sp_layout, _, args :dict):
+    ''' Check validate the maximum number of SPs is respected. '''
+    if len(sp_layout.keys()) > MAX_SP:
+        raise Exception(f"Too many SPs in SP layout file. Max: {MAX_SP}")
+    return args
+
+@SpSetupActions.sp_action
+def gen_fdt_sources(sp_layout, sp, args :dict):
+    ''' Generate FDT_SOURCES values for a given SP. '''
+    manifest_path = get_sp_manifest_full_path(sp_layout[sp], args)
+    write_to_sp_mk_gen(f"FDT_SOURCES += {manifest_path}", args)
+    return args
 
-        """
-        Append FIP_ARGS
-        """
-        out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n")
+@SpSetupActions.sp_action
+def gen_sptool_args(sp_layout, sp, args :dict):
+    ''' Generate Sp Pkgs rules. '''
+    sp_pkg = get_sp_pkg(sp, args)
+    sp_dtb_name = os.path.basename(get_file_from_layout(sp_layout[sp]["pm"]))[:-1] + "b"
+    sp_dtb = os.path.join(args["out_dir"], f"fdts/{sp_dtb_name}")
 
-        """
-        Append CRT_ARGS
-        """
+    # Do not generate rule if already there.
+    if is_line_in_sp_gen(f'{sp_pkg}:', args):
+        return args
+    write_to_sp_mk_gen(f"SP_PKGS += {sp_pkg}\n", args)
+
+    sptool_args = f" -i {get_sp_img_full_path(sp_layout[sp], args)}:{sp_dtb}"
+    pm_offset = get_pm_offset(sp_layout[sp])
+    sptool_args += f" --pm-offset {pm_offset}" if pm_offset is not None else ""
+    image_offset = get_image_offset(sp_layout[sp])
+    sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
+    sptool_args += f" -o {sp_pkg}"
+    sppkg_rule = f'''
+{sp_pkg}:
+\t$(Q)echo Generating {sp_pkg}
+\t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
+'''
+    write_to_sp_mk_gen(sppkg_rule, args)
+    return args
+
+@SpSetupActions.sp_action(global_action=True, exec_order=1)
+def check_dualroot(sp_layout, _, args :dict):
+    ''' Validate the amount of SPs from SiP and Platform owners. '''
+    if not args.get("dualroot"):
+        return args
+    args["split"] =  int(MAX_SP / 2)
+    owners = [sp_layout[sp].get("owner") for sp in sp_layout]
+    args["plat_max_count"] = owners.count("Plat")
+    # If it is owned by the platform owner, it is assigned to the SiP.
+    args["sip_max_count"] = len(sp_layout.keys()) - args["plat_max_count"]
+    if  args["sip_max_count"] > args["split"] or args["sip_max_count"] > args["split"]:
+        print(f"WARN: SiP Secure Partitions should not be more than {args['split']}")
+    # Counters for gen_crt_args.
+    args["sip_count"] = 1
+    args["plat_count"] = 1
+    return args
+
+@SpSetupActions.sp_action
+def gen_crt_args(sp_layout, sp, args :dict):
+    ''' Append CRT_ARGS. '''
+    # If "dualroot" is configured, 'sp_pkg_idx' depends on whether the SP is owned
+    # by the "SiP" or the "Plat".
+    if args.get("dualroot"):
+        # If the owner is not specified as "Plat", default to "SiP".
+        if sp_layout[sp].get("owner") == "Plat":
+            if args["plat_count"] > args["plat_max_count"]:
+                raise ValueError("plat_count can't surpass plat_max_count in args.")
+            sp_pkg_idx = args["plat_count"] + args["split"]
+            args["plat_count"] += 1
+        else:
+            if args["sip_count"] > args["sip_max_count"]:
+                raise ValueError("sip_count can't surpass sip_max_count in args.")
+            sp_pkg_idx = args["sip_count"]
+            args["sip_count"] += 1
+    else:
+        sp_pkg_idx = [k for k in sp_layout.keys()].index(sp) + 1
+    write_to_sp_mk_gen(f"CRT_ARGS += --sp-pkg{sp_pkg_idx} {get_sp_pkg(sp, args)}\n", args)
+    return args
+
+@SpSetupActions.sp_action
+def gen_fiptool_args(sp_layout, sp, args :dict):
+    ''' Generate arguments for the FIP Tool. '''
+    if "uuid" in sp_layout[sp]:
+        # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
+        uuid_std = uuid.UUID(data[key]['uuid'])
+    else:
+        with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
+            uuid_lines = [l for l in pm_f if 'uuid' in l]
+        assert(len(uuid_lines) is 1)
+        # The uuid field in SP manifest is the little endian representation
+        # mapped to arguments as described in SMCCC section 5.3.
+        # Convert each unsigned integer value to a big endian representation
+        # required by fiptool.
+        uuid_parsed = re.findall("0x([0-9a-f]+)", uuid_lines[0])
+        y = list(map(bytearray.fromhex, uuid_parsed))
+        z = [int.from_bytes(i, byteorder='little', signed=False) for i in y]
+        uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+    write_to_sp_mk_gen(f"FIP_ARGS += --blob uuid={str(uuid_std)},file={get_sp_pkg(sp, args)}\n", args)
+    return args
+
+def init_sp_actions(sys):
+    sp_layout_file = os.path.abspath(sys.argv[2])
+    with open(sp_layout_file) as json_file:
+        sp_layout = json.load(json_file)
+    # Initialize arguments for the SP actions framework
+    args = {}
+    args["sp_gen_mk"] = os.path.abspath(sys.argv[1])
+    args["sp_layout_dir"] = os.path.dirname(sp_layout_file)
+    args["out_dir"] = os.path.abspath(sys.argv[3])
+    args["dualroot"] = sys.argv[4] == "dualroot"
+    #Clear content of file "sp_gen.mk".
+    with open(args["sp_gen_mk"], "w"):
+        None
+    return args, sp_layout
 
-        out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
-        out_file.write("\n")
+if __name__ == "__main__":
+    args, sp_layout = init_sp_actions(sys)
+    SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/spactions.py b/tools/sptool/spactions.py
new file mode 100644
index 0000000..ff28ebb
--- /dev/null
+++ b/tools/sptool/spactions.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+'''
+This is a python module for defining and executing SP setup actions, targeting
+a system deploying an SPM implementation.
+Each action consists of a function, that processes the SP layout json file and
+other provided arguments.
+At the core of this is the SpSetupActions which provides a means to register
+the functions into a table of actions, and execute them all when invoking
+SpSetupActions.run_actions.
+Registering the function is done by using the decorator '@SpSetupActions.sp_action'
+at function definition.
+
+Functions can be called:
+- once only, or per SP defined in the SP layout file;
+- following an order, from lowest to highest of their execution order.
+More information in the doc comments below.
+'''
+import bisect
+
+DEFAULT_ACTION_ORDER = 100
+
+class _ConfiguredAction:
+    """
+    Wraps action function with its configuration.
+    """
+    def __init__(self, action, exec_order=DEFAULT_ACTION_ORDER, global_action=True, log_calls = False):
+        self.exec_order = exec_order
+        self.__name__ = action.__name__
+        def logged_action(action):
+            def inner_logged_action(sp_layout, sp, args :dict):
+                print(f"Calling {action.__name__} -> {sp}")
+                return action(sp_layout, sp, args)
+            return inner_logged_action
+        self.action = logged_action(action) if log_calls is True else action
+        self.global_action = global_action
+
+    def __lt__(self, other):
+        """
+        To allow for ordered inserts in a list of actions.
+        """
+        return self.exec_order < other.exec_order
+
+    def __call__(self, sp_layout, sp, args :dict):
+        """
+        Calls action function.
+        """
+        return self.action(sp_layout, sp, args)
+
+    def __repr__(self) -> str:
+        """
+        Pretty format to show debug information about the action.
+        """
+        return f"func: {self.__name__}; global:{self.global_action}; exec_order: {self.exec_order}"
+
+class SpSetupActions:
+    actions = []
+
+    def sp_action(in_action = None, global_action = False, log_calls=False, exec_order=DEFAULT_ACTION_ORDER):
+        """
+        Function decorator that registers and configures action.
+
+        :param in_action - function to register
+        :param global_action - make the function global, i.e. make it be
+        only called once.
+        :param log_calls - at every call to action, a useful log will be printed.
+        :param exec_order - action's calling order.
+        """
+        def append_action(action):
+            action = _ConfiguredAction(action, exec_order, global_action, log_calls)
+            bisect.insort(SpSetupActions.actions, action)
+            return action
+        if in_action is not None:
+            return append_action(in_action)
+        return append_action
+
+    def run_actions(sp_layout: dict, args: dict, verbose=False):
+        """
+        Executes all actions in accordance to their registering configuration:
+        - If set as "global" it will be called once.
+        - Actions are called respecting the order established by their "exec_order" field.
+
+        :param sp_layout - dictionary containing the SP layout information.
+        :param args - arguments to be propagated through the call of actions.
+        :param verbose - prints actions information in order of execution.
+        """
+        args["called"] = [] # for debug purposes
+        def append_called(action, sp, args :dict):
+            args["called"].append(f"{action.__name__} -> {sp}")
+            return args
+
+        for action in SpSetupActions.actions:
+            if verbose:
+                print(f"Calling {action}")
+            if action.global_action:
+                scope = "global"
+                args = action(sp_layout, scope, args)
+                args = append_called(action, scope, args)
+            else:
+                # Functions that are not global called for each SP defined in
+                # the SP layout.
+                for sp in sp_layout.keys():
+                    args = action(sp_layout, sp, args)
+                    args = append_called(action, sp, args)
+
+if __name__ == "__main__":
+    # Executing this module will have the following test code/playground executed
+    sp_layout = {
+        "partition1" : {
+            "boot-info": True,
+            "image": {
+                "file": "partition.bin",
+                "offset":"0x2000"
+            },
+            "pm": {
+                "file": "cactus.dts",
+                "offset":"0x1000"
+            },
+            "owner": "SiP"
+        },
+        "partition2" : {
+            "image": "partition.bin",
+            "pm": "cactus-secondary.dts",
+            "owner": "Plat"
+        },
+        "partition3" : {
+            "image": "partition.bin",
+            "pm": "cactus-tertiary.dts",
+            "owner": "Plat"
+        },
+        "partition4" : {
+            "image": "ivy.bin",
+            "pm": "ivy.dts",
+            "owner": "Plat"
+        }
+    }
+
+    #Example of how to use this module
+    @SpSetupActions.sp_action(global_action=True)
+    def my_action1(sp_layout, _, args :dict):
+        print(f"inside function my_action1{sp_layout}\n\n args:{args})")
+        return args # Always return args in action function.
+    @SpSetupActions.sp_action(exec_order=1)
+    def my_action2(sp_layout, sp_name, args :dict):
+        print(f"inside function my_action2; SP: {sp_name} {sp_layout} args:{args}")
+        return args
+
+    # Example arguments to be propagated through the functions.
+    # 'args' can be extended in the action functions.
+    args = dict()
+    args["arg1"] = 0xEEE
+    args["arg2"] = 0xFF
+    SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c
deleted file mode 100644
index 38baa2c..0000000
--- a/tools/sptool/sptool.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sptool.h"
-
-#define PAGE_SIZE		4096
-
-/*
- * Entry describing Secure Partition package.
- */
-struct sp_pkg_info {
-	/* Location of the files in the host's RAM. */
-	void *img_data, *pm_data;
-
-	/* Size of the files. */
-	uint32_t img_size, pm_size;
-
-	/* Location of the binary files inside the package output file */
-	uint32_t img_offset, pm_offset;
-};
-
-/*
- * List of input provided by user
- */
-struct arg_list {
-	char *usr_input;
-	struct arg_list *next;
-};
-
-/* Align an address to a power-of-two boundary. */
-static unsigned int align_to(unsigned int address, unsigned int boundary)
-{
-	unsigned int mask = boundary - 1U;
-
-	if ((address & mask) != 0U)
-		return (address + boundary) & ~mask;
-	else
-		return address;
-}
-
-/* Allocate a memory area of 'size' bytes and zero it. */
-static void *xzalloc(size_t size, const char *msg)
-{
-	void *d;
-
-	d = malloc(size);
-	if (d == NULL) {
-		fprintf(stderr, "error: malloc: %s\n", msg);
-		exit(1);
-	}
-
-	memset(d, 0, size);
-
-	return d;
-}
-
-/*
- * Write 'size' bytes from 'buf' into the specified file stream.
- * Exit the program on error.
- */
-static void xfwrite(void *buf, size_t size, FILE *fp)
-{
-	if (fwrite(buf, 1, size, fp) != size) {
-		fprintf(stderr, "error: Failed to write to output file.\n");
-		exit(1);
-	}
-}
-
-/*
- * Set the file position indicator for the specified file stream.
- * Exit the program on error.
- */
-static void xfseek(FILE *fp, long offset, int whence)
-{
-	if (fseek(fp, offset, whence) != 0) {
-		fprintf(stderr, "error: Failed to set file to offset 0x%lx (%d).\n",
-		       offset, whence);
-		perror(NULL);
-		exit(1);
-	}
-}
-
-/*
- * Free SP package structure
- */
-static void cleanup(struct sp_pkg_info *sp)
-{
-
-	if (sp != NULL) {
-		if (sp->img_data != NULL) {
-			free(sp->img_data);
-		}
-
-		if (sp->pm_data != NULL) {
-			free(sp->pm_data);
-		}
-
-		free(sp);
-
-	}
-}
-
-/*
- * Free argument list structure
- */
-static void freelist(struct arg_list *head)
-{
-	struct arg_list *tmp;
-
-	while (head != NULL) {
-		tmp = head;
-		head = head->next;
-		free(tmp);
-	}
-}
-
-/*
- * Append user inputs in argument list structure
- */
-static void append_user_input(struct arg_list **head, char *args)
-{
-	struct arg_list *tmp = *head;
-
-	if (tmp == NULL) {
-		tmp = xzalloc(sizeof(struct arg_list),
-				"Failed to allocate arg_list struct");
-		tmp->usr_input = args;
-		*head = tmp;
-	} else {
-		while (tmp->next != NULL) {
-			tmp = tmp->next;
-		}
-		tmp->next = xzalloc(sizeof(struct arg_list),
-				"Failed to allocate arg_list struct");
-		tmp = tmp->next;
-		tmp->usr_input = args;
-	}
-}
-
-/*
- * Allocate a buffer big enough to store the content of the specified file and
- * load the file into it. Fill 'size' with the file size. Exit the program on
- * error.
- */
-static void load_file(const char *path, void **ptr, uint32_t *size)
-{
-	FILE *f = fopen(path, "rb");
-	if (f == NULL) {
-		fprintf(stderr, "error: %s couldn't be opened.\n", path);
-		exit(1);
-	}
-
-	xfseek(f, 0, SEEK_END);
-	*size = ftell(f);
-	if (*size == 0) {
-		fprintf(stderr, "error: Size of %s is 0\n", path);
-		exit(1);
-	}
-
-	rewind(f);
-
-	*ptr = malloc(*size);
-	if (*ptr == NULL) {
-		fprintf(stderr, "error: Not enough memory to load %s\n", path);
-		exit(1);
-	}
-
-	if (fread(*ptr, *size, 1, f) != 1) {
-		fprintf(stderr, "error: Couldn't read %s\n", path);
-		exit(1);
-	}
-
-	fclose(f);
-}
-
-/*
- * Parse the string containing input payloads and fill in the
- * SP Package data structure.
- */
-static void load_sp_pm(char *path, struct sp_pkg_info **sp_out)
-{
-	struct sp_pkg_info *sp_pkg;
-
-	char *split_mark = strstr(path, ":");
-
-	*split_mark = '\0';
-
-	char *sp_path = path;
-	char *pm_path = split_mark + 1;
-
-	sp_pkg = xzalloc(sizeof(struct sp_pkg_info),
-		"Failed to allocate sp_pkg_info struct");
-
-	load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size);
-	printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size);
-
-	load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size);
-	printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size);
-
-	*sp_out = sp_pkg;
-}
-
-/*
- * Write SP package data structure into output file.
- */
-static void output_write(const char *path, struct sp_pkg_info *sp, bool header)
-{
-	struct sp_pkg_header sp_header_info;
-	unsigned int file_ptr = 0;
-
-	FILE *f = fopen(path, "wb");
-	if (f == NULL) {
-		fprintf(stderr, "error: Failed to open %s\n", path);
-		exit(1);
-	}
-
-	/* Reserve Header size */
-	if (header) {
-		file_ptr = sizeof(struct sp_pkg_header);
-	}
-
-	/* Save partition manifest */
-	xfseek(f, file_ptr, SEEK_SET);
-	printf("Writing SP Manifest at offset 0x%x (%u bytes)\n",
-	       file_ptr, sp->pm_size);
-
-	sp->pm_offset = file_ptr;
-	xfwrite(sp->pm_data, sp->pm_size, f);
-
-	/* Save partition image aligned to Page size */
-	file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE);
-	xfseek(f, file_ptr, SEEK_SET);
-	printf("Writing SP Image at offset 0x%x (%u bytes)\n",
-	       file_ptr, sp->img_size);
-
-	sp->img_offset = file_ptr;
-	xfwrite(sp->img_data, sp->img_size, f);
-
-	/* Finally, write header, if needed */
-	if (header) {
-		sp_header_info.magic = SECURE_PARTITION_MAGIC;
-		sp_header_info.version = 0x1;
-		sp_header_info.img_offset = sp->img_offset;
-		sp_header_info.img_size = sp->img_size;
-		sp_header_info.pm_offset = sp->pm_offset;
-		sp_header_info.pm_size = sp->pm_size;
-
-		xfseek(f, 0, SEEK_SET);
-
-		printf("Writing package header\n");
-
-		xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f);
-	}
-
-	/* All information has been written now */
-	printf("\nsptool: Built Secure Partition blob %s\n", path);
-
-	fclose(f);
-}
-
-static void usage(void)
-{
-	printf("usage: sptool ");
-#ifdef VERSION
-	printf(VERSION);
-#else
-	/* If built from sptool directory, VERSION is not set. */
-	printf("version unknown");
-#endif
-	printf(" [<args>]\n\n");
-
-	printf("This tool takes as input set of image binary files and the\n"
-	       "partition manifest blobs as input and generates set of\n"
-	       "output package files\n"
-	       "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n"
-	       "                      -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n");
-	printf("Commands supported:\n");
-	printf("  -o <path>            Set output file path.\n");
-	printf("  -i <sp_path:pm_path> Add Secure Partition image and\n"
-	       "                       Manifest blob (specified in two paths\n"
-	       "                       separated by a colon).\n");
-	printf("  -n                   Generate package without header\n");
-	printf("  -h                   Show this message.\n");
-	exit(1);
-}
-
-int main(int argc, char *argv[])
-{
-	struct sp_pkg_info *sp_pkg = NULL;
-	struct arg_list *in_head = NULL;
-	struct arg_list *out_head = NULL;
-	struct arg_list *in_list = NULL;
-	struct arg_list *out_list = NULL;
-	unsigned int match_counter = 0;
-	bool need_header = true;
-
-	int ch;
-
-	if (argc <= 1) {
-		fprintf(stderr, "error: File paths must be provided.\n\n");
-		usage();
-		return 1;
-	}
-
-	while ((ch = getopt(argc, argv, "hni:o:")) != -1) {
-		switch (ch) {
-		case 'i':
-			append_user_input(&in_head, optarg);
-			match_counter++;
-			break;
-		case 'o':
-			append_user_input(&out_head, optarg);
-			match_counter--;
-			break;
-		case 'n':
-			need_header = false;
-			break;
-		case 'h':
-		default:
-			usage();
-		}
-	}
-
-	if (match_counter) {
-		fprintf(stderr, "error: Input/Output count mismatch.\n\n");
-		freelist(in_head);
-		freelist(out_head);
-		usage();
-		return 1;
-	}
-
-	in_list = in_head;
-	out_list = out_head;
-	while (in_list != NULL) {
-		load_sp_pm(in_list->usr_input, &sp_pkg);
-		output_write(out_list->usr_input, sp_pkg, need_header);
-		in_list = in_list->next;
-		out_list = out_list->next;
-	}
-
-	argc -= optind;
-	argv += optind;
-
-	cleanup(sp_pkg);
-	freelist(in_head);
-	freelist(out_head);
-
-	return 0;
-}
diff --git a/tools/sptool/sptool.py b/tools/sptool/sptool.py
new file mode 100755
index 0000000..ae7df92
--- /dev/null
+++ b/tools/sptool/sptool.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+#
+# Copyright 2022 The Hafnium Authors.
+#
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/BSD-3-Clause.
+
+"""
+Script which generates a Secure Partition package.
+https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager.html#secure-partition-packages
+"""
+
+import argparse
+from collections import namedtuple
+import sys
+from shutil import copyfileobj
+import os
+
+HF_PAGE_SIZE = 0x1000 # bytes
+HEADER_ELEMENT_BYTES = 4 # bytes
+MANIFEST_IMAGE_SPLITTER=':'
+PM_OFFSET_DEFAULT = "0x1000"
+IMG_OFFSET_DEFAULT = "0x4000"
+
+def split_dtb_bin(i : str):
+    return i.split(MANIFEST_IMAGE_SPLITTER)
+
+def align_to_page(n):
+    return HF_PAGE_SIZE * \
+          (round(n / HF_PAGE_SIZE) + \
+           (1 if n % HF_PAGE_SIZE else 0))
+
+def to_bytes(value):
+    return int(value).to_bytes(HEADER_ELEMENT_BYTES, 'little')
+
+class SpPkg:
+    def __init__(self, pm_path : str, img_path : str, pm_offset: int,
+                 img_offset: int):
+        if not os.path.isfile(pm_path) or not os.path.isfile(img_path):
+            raise Exception(f"Parameters should be path.  \
+                              manifest: {pm_path}; img: {img_path}")
+        self.pm_path = pm_path
+        self.img_path = img_path
+        self._SpPkgHeader = namedtuple("SpPkgHeader",
+                             ("magic", "version",
+                              "pm_offset", "pm_size",
+                              "img_offset", "img_size"))
+
+        if pm_offset >= img_offset:
+            raise ValueError("pm_offset must be smaller than img_offset")
+
+        is_hfpage_aligned = lambda val : val % HF_PAGE_SIZE == 0
+        if not is_hfpage_aligned(pm_offset) or not is_hfpage_aligned(img_offset):
+           raise ValueError(f"Offsets provided need to be page aligned: pm-{pm_offset}, img-{img_offset}")
+
+        if img_offset - pm_offset < self.pm_size:
+            raise ValueError(f"pm_offset and img_offset do not fit the specified file:{pm_path})")
+
+        self.pm_offset = pm_offset
+        self.img_offset = img_offset
+
+    def __str__(self):
+        return \
+        f'''--SP package Info--
+        header:{self.header}
+        pm: {self.pm_path}
+        img: {self.img_path}
+        '''
+
+    @property
+    def magic(self):
+        return "SPKG".encode()
+
+    @property
+    def version(self):
+        return 0x2
+
+    @property
+    def pm_size(self):
+        return os.path.getsize(self.pm_path)
+
+    @property
+    def img_size(self):
+        return os.path.getsize(self.img_path)
+
+    @property
+    def header(self):
+        return self._SpPkgHeader(
+                self.magic,
+                self.version,
+                self.pm_offset,
+                self.pm_size,
+                self.img_offset,
+                self.img_size)
+
+    @property
+    def header_size(self):
+        return len(self._SpPkgHeader._fields)
+
+    def generate(self, f_out : str):
+        with open(f_out, "wb+") as output:
+            for h in self.header:
+                to_write = h if type(h) is bytes else to_bytes(h)
+                output.write(to_write)
+            output.seek(self.pm_offset)
+            with open(self.pm_path, "rb") as pm:
+                copyfileobj(pm, output)
+            output.seek(self.img_offset)
+            with open(self.img_path, "rb") as img:
+                copyfileobj(img, output)
+
+def Main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-i", required=True,
+                        help="path to partition's image and manifest separated by a colon.")
+    parser.add_argument("--pm-offset", required=False, default=PM_OFFSET_DEFAULT,
+                        help="set partitition manifest offset.")
+    parser.add_argument("--img-offset", required=False, default=IMG_OFFSET_DEFAULT,
+                        help="set partition image offset.")
+    parser.add_argument("-o", required=True, help="set output file path.")
+    parser.add_argument("-v", required=False, action="store_true",
+                        help="print package information.")
+    args = parser.parse_args()
+
+    if not os.path.exists(os.path.dirname(args.o)):
+        raise Exception("Provide a valid output file path!\n")
+
+    image_path, manifest_path = split_dtb_bin(args.i)
+    pm_offset = int(args.pm_offset, 0)
+    img_offset = int(args.img_offset, 0)
+    pkg = SpPkg(manifest_path, image_path, pm_offset, img_offset)
+    pkg.generate(args.o)
+
+    if args.v is True:
+        print(pkg)
+
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(Main())