Merge "chore(fvp): use correct dts for dynamiq cores" into integration
diff --git a/.editorconfig b/.editorconfig
index 12f786d..1b29c88 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -70,3 +70,6 @@
 # [PEP8] Maximum Line Length
 #	"Limit all lines to a maximum of 79 characters."
 max_line_length = 79
+
+[.git/COMMIT_EDITMSG]
+max_line_length = 72
diff --git a/Makefile b/Makefile
index 179e07a..51c7b2e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 11
+VERSION_MINOR			:= 12
 # VERSION_PATCH is only used for LTS releases
 VERSION_PATCH			:= 0
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
@@ -23,7 +23,6 @@
 
 MAKE_HELPERS_DIRECTORY := make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}build-rules.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 
@@ -99,15 +98,15 @@
 
 # Variables for use with Certificate Generation Tool
 CRTTOOLPATH		?=	tools/cert_create
-CRTTOOL			?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
+CRTTOOL			?=	${CRTTOOLPATH}/cert_create$(.exe)
 
 # Variables for use with Firmware Encryption Tool
 ENCTOOLPATH		?=	tools/encrypt_fw
-ENCTOOL			?=	${ENCTOOLPATH}/encrypt_fw${BIN_EXT}
+ENCTOOL			?=	${ENCTOOLPATH}/encrypt_fw$(.exe)
 
 # Variables for use with Firmware Image Package
 FIPTOOLPATH		?=	tools/fiptool
-FIPTOOL			?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
+FIPTOOL			?=	${FIPTOOLPATH}/fiptool$(.exe)
 
 # Variables for use with sptool
 SPTOOLPATH		?=	tools/sptool
@@ -256,10 +255,12 @@
 				-Wlogical-op
 
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
-TF_CFLAGS		+= 	$(call cc_option, --param=min-pagesize=0)
+TF_CFLAGS_MIN_PAGE_SIZE	:=	$(call cc_option, --param=min-pagesize=0)
+TF_CFLAGS		+=	$(TF_CFLAGS_MIN_PAGE_SIZE)
 
 ifeq ($(HARDEN_SLS), 1)
-        TF_CFLAGS_aarch64       +=      $(call cc_option, -mharden-sls=all)
+        TF_CFLAGS_MHARDEN_SLS	:=      $(call cc_option, -mharden-sls=all)
+        TF_CFLAGS_aarch64	+=      $(TF_CFLAGS_MHARDEN_SLS)
 endif
 
 else
@@ -281,7 +282,7 @@
 				-ffreestanding -Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
 				-ffunction-sections -fdata-sections		\
-				-ffreestanding -fno-builtin -fno-common		\
+				-ffreestanding -fno-common			\
 				-Os -std=gnu99
 
 ifeq (${SANITIZE_UB},on)
@@ -512,6 +513,12 @@
 endif
 
 ################################################################################
+# Include the platform specific Makefile after the SPD Makefile (the platform
+# makefile may use all previous definitions in this file)
+################################################################################
+include ${PLAT_MAKEFILE_FULL}
+
+################################################################################
 # Process BRANCH_PROTECTION value and set
 # Pointer Authentication and Branch Target Identification flags
 ################################################################################
@@ -556,12 +563,6 @@
 endif
 
 ################################################################################
-# Include the platform specific Makefile after the SPD Makefile (the platform
-# makefile may use all previous definitions in this file)
-################################################################################
-include ${PLAT_MAKEFILE_FULL}
-
-################################################################################
 # Setup arch_features based on ARM_ARCH_MAJOR, ARM_ARCH_MINOR provided from
 # platform.
 ################################################################################
@@ -597,19 +598,6 @@
 ################################################################################
 # FEAT_RME
 ifeq (${ENABLE_RME},1)
-	# RME doesn't support BRBE
-	ENABLE_BRBE_FOR_NS := 0
-
-	# RME doesn't support PIE
-	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)
@@ -654,6 +642,13 @@
 endif
 
 ################################################################################
+# Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
+################################################################################
+ifneq (${ENABLE_FEAT_D128}, 0)
+        BL_COMMON_SOURCES       +=      lib/extensions/sysreg128/sysreg128.S
+endif
+
+################################################################################
 # Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
 # up with appropriate march values for compiler.
 ################################################################################
@@ -881,6 +876,10 @@
 	CRYPTO_SUPPORT := 0
 endif #($(MEASURED_BOOT)-$(TRUSTED_BOARD_BOOT))
 
+ifneq ($(filter 1 2 3,$(CRYPTO_SUPPORT)),)
+CRYPTO_LIB := $(BUILD_PLAT)/lib/libmbedtls.a
+endif
+
 # SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled.
 ifeq ($(SDEI_SUPPORT)-$(SDEI_IN_FCONF),0-1)
         $(error "SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled")
@@ -950,8 +949,29 @@
 	ifeq (${ENABLE_FEAT_RNG_TRAP},1)
                 $(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
 	endif
+
+	ifneq (${ENABLE_FEAT_FPMR},0)
+                $(error "ENABLE_FEAT_FPMR cannot be used with ARCH=aarch32")
+	endif
+
+	ifeq (${ARCH_FEATURE_AVAILABILITY},1)
+                $(error "ARCH_FEATURE_AVAILABILITY cannot be used with ARCH=aarch32")
+	endif
+	# FEAT_MOPS is only supported on AArch64
+	ifneq (${ENABLE_FEAT_MOPS},0)
+		$(error "ENABLE_FEAT_MOPS cannot be used with ARCH=aarch32")
+	endif
 endif #(ARCH=aarch32)
 
+ifneq (${ENABLE_FEAT_FPMR},0)
+	ifeq (${ENABLE_FEAT_FGT},0)
+                $(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_FGT")
+	endif
+	ifeq (${ENABLE_FEAT_HCX},0)
+                $(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_HCX")
+	endif
+endif #(ENABLE_FEAT_FPMR)
+
 ifneq (${ENABLE_SME_FOR_NS},0)
 	ifeq (${ENABLE_SVE_FOR_NS},0)
                 $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
@@ -1020,6 +1040,10 @@
         $(info DRTM_SUPPORT is an experimental feature)
 endif
 
+ifeq (${HOB_LIST},1)
+        $(warning HOB_LIST is an experimental feature)
+endif
+
 ifeq (${TRANSFER_LIST},1)
         $(info TRANSFER_LIST is an experimental feature)
 endif
@@ -1177,6 +1201,7 @@
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
 	DICE_PROTECTION_ENVIRONMENT \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	OVERRIDE_LIBC \
@@ -1184,11 +1209,13 @@
 	PROGRAMMABLE_RESET_ADDRESS \
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
+	ARCH_FEATURE_AVAILABILITY \
 	RESET_TO_BL31 \
 	SAVE_KEYS \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_RWDATA_REGION \
 	SEPARATE_SIMD_SECTION \
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
@@ -1231,6 +1258,7 @@
 	PLATFORM_REPORT_CTX_MEM_USE \
 	EARLY_CONSOLE \
 	PRESERVE_DSU_PMU_REGS \
+	HOB_LIST \
 )))
 
 # Numeric_Flags
@@ -1256,18 +1284,24 @@
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
 	ENABLE_FEAT_FGT2 \
+	ENABLE_FEAT_FPMR \
 	ENABLE_FEAT_HCX \
+	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MOPS \
 	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_RNG \
 	ENABLE_FEAT_RNG_TRAP \
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
 	ENABLE_FEAT_SB \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
+	ENABLE_FEAT_D128 \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_MPAM \
@@ -1331,6 +1365,7 @@
 	ENABLE_PMF \
 	ENABLE_PSCI_STAT \
 	ENABLE_RME \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	ENABLE_RUNTIME_INSTRUMENTATION \
 	ENABLE_SME_FOR_NS \
 	ENABLE_SME2_FOR_NS \
@@ -1357,12 +1392,14 @@
 	PROGRAMMABLE_RESET_ADDRESS \
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
+	ARCH_FEATURE_AVAILABILITY \
 	RESET_TO_BL31 \
 	RME_GPT_BITLOCK_BLOCK \
 	RME_GPT_MAX_BLOCK \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_RWDATA_REGION \
 	SEPARATE_SIMD_SECTION \
 	RECLAIM_INIT_CODE \
 	SPD_${SPD} \
@@ -1411,19 +1448,25 @@
 	ENABLE_MPMM_FCONF \
 	ENABLE_FEAT_FGT \
 	ENABLE_FEAT_FGT2 \
+	ENABLE_FEAT_FPMR \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_CSV2_2 \
 	ENABLE_FEAT_CSV2_3 \
+	ENABLE_FEAT_LS64_ACCDATA \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
+	ENABLE_FEAT_D128 \
 	ENABLE_FEAT_GCS \
+	ENABLE_FEAT_MOPS \
 	ENABLE_FEAT_MTE2 \
 	FEATURE_DETECTION \
 	TWED_DELAY \
@@ -1438,6 +1481,7 @@
 	PLATFORM_REPORT_CTX_MEM_USE \
 	EARLY_CONSOLE \
 	PRESERVE_DSU_PMU_REGS \
+	HOB_LIST \
 )))
 
 ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
@@ -1490,7 +1534,6 @@
 ################################################################################
 
 .PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp tl fwu_fip certtool dtbs memmap doc enctool
-.SUFFIXES:
 
 all: msg_start
 
@@ -1608,29 +1651,17 @@
 
 clean:
 	$(s)echo "  CLEAN"
-	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
-ifdef UNIX_MK
+	$(q)rm -rf $(BUILD_PLAT)
 	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
-else
-# Clear the MAKEFLAGS as we do not want
-# to pass the gnumake flags to nmake.
-	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
-endif #(UNIX_MK)
 	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
 	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
 	$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 realclean distclean:
 	$(s)echo "  REALCLEAN"
-	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
-	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
-ifdef UNIX_MK
+	$(q)rm -rf $(BUILD_BASE)
+	$(q)rm -rf $(CURDIR)/cscope.*
 	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
-else
-# Clear the MAKEFLAGS as we do not want
-# 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 #(UNIX_MK)
 	$(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
@@ -1715,25 +1746,14 @@
 fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME}
 
 ${FIPTOOL}: FORCE
-ifdef UNIX_MK
 	$(q)${MAKE} PLAT=${PLAT} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
-else
-# Clear the MAKEFLAGS as we do not want
-# to pass the gnumake flags to nmake.
-	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
-endif #(UNIX_MK)
 
-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=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
+$(BUILD_PLAT)/romlib/romlib.bin $(BUILD_PLAT)/lib/libwrappers.a $&: $(BUILD_PLAT)/lib/libfdt.a $(BUILD_PLAT)/lib/libc.a $(CRYPTO_LIB)
+	$(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} CRYPTO_SUPPORT=${CRYPTO_SUPPORT} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
 
 memmap: all
-ifdef UNIX_MK
 	$(q)PYTHONPATH=${CURDIR}/tools/memory \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
-else
-	$(q)set PYTHONPATH=${CURDIR}/tools/memory && \
-		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
-endif
 
 tl: ${BUILD_PLAT}/tl.bin
 ${BUILD_PLAT}/tl.bin: ${HW_CONFIG}
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index e47b082..7423805 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -229,7 +229,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
@@ -237,7 +236,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch64
 
@@ -245,7 +243,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b 	handle_interrupt_exception
 end_vector_entry fiq_aarch64
 
@@ -258,7 +255,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_lower_el_async_ea
 #else
 	b	report_unhandled_exception
@@ -279,7 +275,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
@@ -287,7 +282,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch32
 
@@ -295,7 +289,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry fiq_aarch32
 
@@ -308,7 +301,6 @@
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_lower_el_async_ea
 #else
 	b	report_unhandled_exception
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 8698dff..867dedb 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -19,6 +19,12 @@
 #else /* SEPARATE_NOBITS_REGION */
 #   define NOBITS RAM
 #endif /* SEPARATE_NOBITS_REGION */
+
+#if SEPARATE_RWDATA_REGION
+    RAM_RW (rw): ORIGIN = BL31_RWDATA_BASE, LENGTH = BL31_RWDATA_LIMIT - BL31_RWDATA_BASE
+#else /* SEPARATE_RWDATA_REGION */
+#define RAM_RW RAM
+#endif /* SEPARATE_RWDATA_REGION */
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
@@ -136,10 +142,36 @@
     . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
 #endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
 
-    __RW_START__ = .;
+#if SEPARATE_RWDATA_REGION
+    . = BL31_RWDATA_BASE;
+    ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE),
+           "BL31_RWDATA_BASE address is not aligned on a page boundary.")
+
+    /*
+     * Define a linker symbol to mark the start of the RW memory area for this
+     * image.
+     */
+    __RW_START__ = . ;
+
+    DATA_SECTION >RAM_RW AT>RAM
+    __DATA_RAM_START__ = __DATA_START__;
+    __DATA_RAM_END__ = __DATA_END__;
+    __DATA_ROM_START__ = LOADADDR(.data);
+
+    . = ALIGN(PAGE_SIZE);
+    __RW_END__ = .;
+
+    RELA_SECTION >RAM
+#else /* SEPARATE_RWDATA_REGION */
+    /*
+     * Define a linker symbol to mark the start of the RW memory area for this
+     * image.
+     */
+    __RW_START__ = . ;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
+#endif /* SEPARATE_RWDATA_REGION */
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(
@@ -151,7 +183,9 @@
 #if SEPARATE_NOBITS_REGION
     . = ALIGN(PAGE_SIZE);
 
+#if !SEPARATE_RWDATA_REGION
     __RW_END__ = .;
+#endif /* SEPARATE_RWDATA_REGION */
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
@@ -203,7 +237,13 @@
 
     ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
 #else /* SEPARATE_NOBITS_REGION */
+    /*
+     * Define a linker symbol to mark the end of the RW memory area for this
+     * image.
+     */
+#if !SEPARATE_RWDATA_REGION
     __RW_END__ = .;
+#endif /* SEPARATE_RWDATA_REGION */
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 336ad2b..2f9dc65 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -150,6 +150,10 @@
 BL31_SOURCES		+=	lib/extensions/trf/aarch64/trf.c
 endif
 
+ifneq (${ENABLE_FEAT_FPMR},0)
+BL31_SOURCES		+=	lib/extensions/fpmr/fpmr.c
+endif
+
 ifeq (${WORKAROUND_CVE_2017_5715},1)
 BL31_SOURCES		+=	lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S	\
 				lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index 47a555a..984fdaa 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -96,6 +96,14 @@
  *
  * NOTE: This piece of code must be reviewed every release to ensure that
  * we keep up with new ARCH features which introduces a new SPSR bit.
+ *
+ * TF-A 2.12 release review
+ * The latest version available is 2024-09, which has two extra features which
+ * impacts generation of SPSR, since these features are not implemented in TF-A
+ * at the time of release, just log the feature names here to be taken up when
+ * feature support is introduced.
+ *  - FEAT_PAuth_LR (2023 extension)
+ *  - FEAT_UINJ (2024 extension)
  */
 u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
 {
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index 6d8f74b..696cdb2 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -7,7 +7,7 @@
 INCLUDES		+=	-Iinclude/bl32/tsp
 
 ifeq (${SPMC_AT_EL3},1)
-   BL32_SOURCES            +=      bl32/tsp/tsp_ffa_main.c                    \
+   BL32_SOURCES            +=      bl32/tsp/tsp_ffa_main.c		\
 				   bl32/tsp/ffa_helpers.c
 else
    BL32_SOURCES            +=      bl32/tsp/tsp_main.c
@@ -19,6 +19,7 @@
 				bl32/tsp/tsp_interrupt.c		\
 				bl32/tsp/tsp_timer.c			\
 				bl32/tsp/tsp_common.c			\
+				bl32/tsp/tsp_context.c			\
 				common/aarch64/early_exceptions.S	\
 				lib/locks/exclusive/aarch64/spinlock.S
 
diff --git a/bl32/tsp/tsp_context.c b/bl32/tsp/tsp_context.c
new file mode 100644
index 0000000..6307f72
--- /dev/null
+++ b/bl32/tsp/tsp_context.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <bl32/tsp/tsp_el1_context.h>
+#include <common/debug.h>
+
+#define DUMMY_CTX_VALUE		ULL(0xffffffff)
+#define DUMMY_CTX_TCR_VALUE	ULL(0xffff0000)
+#define DUMMY_CTX_TRF_VALUE	ULL(0xf)
+#define DUMMY_CTX_GCS_VALUE	ULL(0xffff0000)
+#define DEFAULT_CTX_VALUE	ULL(0x0)
+
+/**
+ * -------------------------------------------------------
+ * Private Helper functions required to access and modify
+ * EL1 context registers at S-EL1.
+ * -------------------------------------------------------
+ */
+static void modify_el1_common_regs(uint64_t cm_value)
+{
+	/**
+	 * NOTE: Few EL1 registers "SCTLR_EL1, SPSR_EL1, ELR_EL1" are
+	 *       left out consciously as those are important registers for
+	 *       execution in each world and overwriting them with dummy value
+	 *       would cause unintended crash while executing the test.
+	 */
+	write_tcr_el1(cm_value);
+	write_cpacr_el1(cm_value);
+	write_csselr_el1(cm_value);
+	write_esr_el1(cm_value);
+	write_ttbr0_el1(cm_value);
+	write_ttbr1_el1(cm_value);
+	write_mair_el1(cm_value);
+	write_amair_el1(cm_value);
+	write_actlr_el1(cm_value);
+	write_tpidr_el1(cm_value);
+	write_tpidr_el0(cm_value);
+	write_tpidrro_el0(cm_value);
+	write_par_el1(cm_value);
+	write_far_el1(cm_value);
+	write_afsr0_el1(cm_value);
+	write_afsr1_el1(cm_value);
+	write_contextidr_el1(cm_value);
+	write_vbar_el1(cm_value);
+	write_mdccint_el1(cm_value);
+	write_mdscr_el1(cm_value);
+}
+
+static void modify_el1_mte2_regs(uint64_t mte_value)
+{
+	if (is_feat_mte2_supported()) {
+		write_tfsre0_el1(mte_value);
+		write_tfsr_el1(mte_value);
+		write_rgsr_el1(mte_value);
+		write_gcr_el1(mte_value);
+	}
+}
+
+static void modify_el1_ras_regs(uint64_t ras_value)
+{
+	if (is_feat_ras_supported()) {
+		write_disr_el1(ras_value);
+	}
+}
+
+static void modify_el1_s1pie_regs(uint64_t s1pie_value)
+{
+	if (is_feat_s1pie_supported()) {
+		write_pire0_el1(s1pie_value);
+		write_pir_el1(s1pie_value);
+	}
+}
+
+static void modify_el1_s1poe_regs(uint64_t s1poe_value)
+{
+	if (is_feat_s1poe_supported()) {
+		write_por_el1(s1poe_value);
+	}
+}
+
+static void modify_el1_s2poe_regs(uint64_t s2poe_value)
+{
+	if (is_feat_s2poe_supported()) {
+		write_s2por_el1(s2poe_value);
+	}
+}
+
+static void modify_el1_tcr2_regs(uint64_t tcr_value)
+{
+	if (is_feat_tcr2_supported()) {
+		write_tcr2_el1(tcr_value & DUMMY_CTX_TCR_VALUE);
+	}
+}
+
+static void modify_el1_trf_regs(uint64_t trf_value)
+{
+	if (is_feat_trf_supported()) {
+		write_trfcr_el1(trf_value & DUMMY_CTX_TRF_VALUE);
+	}
+}
+
+static void modify_el1_gcs_regs(uint64_t gcs_value)
+{
+	if (is_feat_gcs_supported()) {
+		write_gcscr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcscre0_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcspr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcspr_el0(gcs_value & DUMMY_CTX_GCS_VALUE);
+	}
+}
+
+/**
+ * -----------------------------------------------------
+ * Public API, to modify/restore EL1 ctx registers:
+ * -----------------------------------------------------
+ */
+void modify_el1_ctx_regs(const bool modify_option)
+{
+	uint64_t mask;
+
+	if (modify_option == TSP_CORRUPT_EL1_REGS) {
+		VERBOSE("TSP(S-EL1): Corrupt EL1 Registers with Dummy values\n");
+		mask = DUMMY_CTX_VALUE;
+	} else {
+		VERBOSE("TSP(S-EL1): Restore EL1 Registers with Default values\n");
+		mask = DEFAULT_CTX_VALUE;
+	}
+
+	modify_el1_common_regs(mask);
+	modify_el1_mte2_regs(mask);
+	modify_el1_ras_regs(mask);
+	modify_el1_s1pie_regs(mask);
+	modify_el1_s1poe_regs(mask);
+	modify_el1_s2poe_regs(mask);
+	modify_el1_tcr2_regs(mask);
+	modify_el1_trf_regs(mask);
+	modify_el1_gcs_regs(mask);
+}
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index ae38d69..8c6b2ed 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -11,6 +11,7 @@
 #include <arch_features.h>
 #include <arch_helpers.h>
 #include <bl32/tsp/tsp.h>
+#include <bl32/tsp/tsp_el1_context.h>
 #include <common/bl_common.h>
 #include <common/build_message.h>
 #include <common/debug.h>
@@ -278,6 +279,17 @@
 		/* Toggle the dit bit */
 		write_dit(service_arg0 != 0U ? 0 : DIT_BIT);
 		break;
+	case TSP_MODIFY_EL1_CTX:
+		/*
+		 * Write dummy values to EL1 context registers, to simulate
+		 * their usage in the secure world.
+		 */
+		if (arg1 == TSP_CORRUPT_EL1_REGS) {
+			modify_el1_ctx_regs(TSP_CORRUPT_EL1_REGS);
+		} else {
+			modify_el1_ctx_regs(TSP_RESTORE_EL1_REGS);
+		}
+		break;
 	default:
 		break;
 	}
diff --git a/changelog.yaml b/changelog.yaml
index 5224441..9d1c3a9 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -161,6 +161,18 @@
       - title: DynamIQ Shared Unit (DSU)
         scope: dsu
 
+      - title: Extension to SCTLR_ELx (FEAT_SCTLR2)
+        scope: sctlr2
+
+        deprecated:
+          - feat_sctlr2
+
+      - title: 128-bit Translation Tables (FEAT_D128)
+        scope: d128
+
+      - title: Translation Hardening Extension (FEAT_THE)
+        scope: the
+
   - title: Platforms
     scope: platforms
 
@@ -182,6 +194,9 @@
           - plat/arm
 
         subsections:
+          - title: Common
+            scope: common
+
           - title: A5DS
             scope: a5ds
 
@@ -252,6 +267,7 @@
 
                 deprecated:
                   - board/rdn2
+                  - rdfremont
 
             deprecated:
               - neoverse
@@ -272,6 +288,9 @@
           - title: Corstone-1000
             scope: corstone-1000
 
+            deprecated:
+              - corstone1000
+
           - title: Automotive RD
             scope: automotive_rd
 
@@ -302,6 +321,9 @@
           - title: HiKey960
             scope: hikey960
 
+          - title: Poplar
+            scope: poplar
+
       - title: Intel
         scope: intel
 
@@ -616,6 +638,9 @@
           - title: RK3328
             scope: rk3328
 
+          - title: RK3588
+            scope: rk3588
+
       - title: Socionext
         scope: socionext
 
@@ -649,6 +674,10 @@
           - title: STM32MP2
             scope: stm32mp2
 
+            subsections:
+              - title: STM32MP25
+                scope: stm32mp25
+
       - title: Texas Instruments
         scope: ti
 
@@ -730,6 +759,9 @@
   - title: Services
     scope: services
 
+    deprecated:
+      - std_svc
+
     subsections:
       - title: FF-A
         scope: ff-a
@@ -787,6 +819,28 @@
       - title: ChromeOS
         scope: cros
 
+      - title: Secure Payload Dispatcher
+        scope: spd
+
+        subsections:
+          - title: OP-TEE
+            scope: optee
+
+            deprecated:
+              - lib/optee
+
+          - title: ProvenCore
+            scope: pncd
+
+          - title: Trusted Little Kernel
+            scope: tlkd
+
+          - title: Trusty
+            scope: trusty
+
+          - title: TSP
+            scope: tspd
+
   - title: Libraries
     scope: lib
 
@@ -821,12 +875,6 @@
       - title: MPMM
         scope: mpmm
 
-      - title: OP-TEE
-        scope: optee
-
-        deprecated:
-          - lib/optee
-
       - title: PSCI
         scope: psci
 
@@ -900,6 +948,9 @@
       - title: Console
         scope: console
 
+      - title: Delay Timer
+        scope: delay-timer
+
       - title: Generic Clock
         scope: clk
 
@@ -1332,6 +1383,10 @@
           - title: STM32MP2
             scope: stm32mp2-fdts
 
+            subsections:
+              - title: STM32MP25
+                scope: stm32mp25-fdts
+
       - title: PIE
         scope: pie
 
diff --git a/common/bl_common.c b/common/bl_common.c
index 2a9f32f..2c452aa 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -150,8 +150,7 @@
  * of trust.
  */
 static int load_auth_image_recursive(unsigned int image_id,
-				    image_info_t *image_data,
-				    int is_parent_image)
+				    image_info_t *image_data)
 {
 	int rc;
 	unsigned int parent_id;
@@ -159,7 +158,7 @@
 	/* Use recursion to authenticate parent images */
 	rc = auth_mod_get_parent_id(image_id, &parent_id);
 	if (rc == 0) {
-		rc = load_auth_image_recursive(parent_id, image_data, 1);
+		rc = load_auth_image_recursive(parent_id, image_data);
 		if (rc != 0) {
 			return rc;
 		}
@@ -193,7 +192,7 @@
 {
 #if TRUSTED_BOARD_BOOT
 	if (dyn_is_auth_disabled() == 0) {
-		return load_auth_image_recursive(image_id, image_data, 0);
+		return load_auth_image_recursive(image_id, image_data);
 	}
 #endif
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 9b9f7b4..821ccb8 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -192,6 +192,11 @@
 	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX_SHIFT,
 			     ID_AA64MMFR1_EL1_HCX_MASK);
 }
+static unsigned int read_feat_ls64_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_LS64_SHIFT,
+			     ID_AA64ISAR1_LS64_MASK);
+}
 static unsigned int read_feat_tcr2_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX_SHIFT,
@@ -257,6 +262,36 @@
 
 }
 
+static unsigned int read_feat_the_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_THE_SHIFT,
+			     ID_AA64PFR1_EL1_THE_MASK);
+}
+
+static unsigned int read_feat_sctlr2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+			     ID_AA64MMFR3_EL1_SCTLR2_MASK);
+}
+
+static unsigned int read_feat_d128_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT,
+			     ID_AA64MMFR3_EL1_D128_MASK);
+}
+
+static unsigned int read_feat_fpmr_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_FPMR_SHIFT,
+			     ID_AA64PFR2_EL1_FPMR_MASK);
+}
+
+static unsigned int read_feat_mops_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar2_el1(), ID_AA64ISAR2_EL1_MOPS_SHIFT,
+			     ID_AA64ISAR2_EL1_MOPS_MASK);
+}
+
 /***********************************************************************************
  * TF-A supports many Arm architectural features starting from arch version
  * (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -314,6 +349,8 @@
 	check_feature(ENABLE_FEAT_DIT, read_feat_dit_id_field(), "DIT", 1, 1);
 	check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
 		      "AMUv1", 1, 2);
+	check_feature(ENABLE_FEAT_MOPS, read_feat_mops_id_field(),
+		      "MOPS", 1, 1);
 	check_feature(ENABLE_FEAT_MPAM, read_feat_mpam_version(),
 		      "MPAM", 1, 17);
 	check_feature(CTX_INCLUDE_NEVE_REGS, read_feat_nv_id_field(),
@@ -349,6 +386,7 @@
 
 	/* v8.7 features */
 	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1);
+	check_feature(ENABLE_FEAT_LS64_ACCDATA, read_feat_ls64_id_field(), "LS64", 1, 3);
 
 	/* v8.9 features */
 	check_feature(ENABLE_FEAT_TCR2, read_feat_tcr2_id_field(),
@@ -365,6 +403,10 @@
 		      "CSV2_3", 3, 3);
 	check_feature(ENABLE_FEAT_DEBUGV8P9, read_feat_debugv8p9_id_field(),
 			"DEBUGV8P9", 11, 11);
+	check_feature(ENABLE_FEAT_THE, read_feat_the_id_field(),
+			"THE", 1, 1);
+	check_feature(ENABLE_FEAT_SCTLR2, read_feat_sctlr2_id_field(),
+			"SCTLR2", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
@@ -377,6 +419,12 @@
 		      "SME", 1, 2);
 	check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
 		      "SME2", 2, 2);
+	check_feature(ENABLE_FEAT_FPMR, read_feat_fpmr_id_field(),
+		      "FPMR", 1, 1);
+
+	/* v9.3 features */
+	check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
+		      "D128", 1, 1);
 
 	/* v9.4 features */
 	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
diff --git a/docs/Makefile b/docs/Makefile
index 9fd7d76..68c0958 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -24,4 +24,5 @@
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 .DEFAULT: Makefile
+	$(if $(host-poetry),$(q)poetry -q install --with=docs)
 	$(q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 4d08a7f..12c0f36 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -49,12 +49,14 @@
 :|G|: `laurenw-arm`_
 :|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
 :|G|: `madhukar-Arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
 :|G|: `raghuncstate`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
 :|M|: Yann Gautier <yann.gautier@st.com>
 :|G|: `Yann-lms`_
+:|M|: Govindraj Raja <govindraj.raja@arm.com>
+:|G|: `govindraj-arm`_
 
 LTS Maintainers
 ---------------
@@ -651,8 +653,8 @@
 
 Marvell platform ports and SoC drivers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Konstantin Porotchkin <kostap@marvell.com>
-:|G|: `kostapr`_
+:|M|: Jaiprakash Singh <jaiprakashs@marvell.com>
+:|G|: `sjaypee208`_
 :|F|: docs/plat/marvell/
 :|F|: plat/marvell/
 :|F|: drivers/marvell/
@@ -791,14 +793,14 @@
 
 QTI platform port
 ^^^^^^^^^^^^^^^^^
-:|M|: Saurabh Gorecha <sgorecha@codeaurora.org>
-:|G|: `sgorecha`_
 :|M|: Lachit Patel <lpatel@codeaurora.org>
 :|G|: `lachitp`_
 :|M|: Sreevyshanavi Kare <skare@codeaurora.org>
 :|G|: `sreekare`_
 :|M|: Muhammad Arsath K F <quic_mkf@quicinc.com>
 :|G|: `quic_mkf`_
+:|M|: Saurabh Gorecha <quic_sgorecha@quicinc.com>
+:|G|: `quic_sgorecha`_
 :|M|: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
 :|F|: docs/plat/qti.rst
 :|F|: plat/qti/
@@ -1016,7 +1018,7 @@
 :|G|: `sandrine-bailleux-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
 :|G|: `joannafarley-arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
 :|G|: `raghuncstate`_
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
 :|G|: `vwadekar`_
@@ -1055,6 +1057,7 @@
 .. _divin-raj: https://github.com/divin-raj
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
+.. _govindraj-arm: https://github.com/govindraj-arm
 .. _gprocopciucnxp: https://github.com/gprocopciucnxp
 .. _grandpaul: https://github.com/grandpaul
 .. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
@@ -1101,6 +1104,7 @@
 .. _pangupta: https://github.com/pangupta
 .. _prabhakarlad: https://github.com/prabhakarlad
 .. _quic_mkf: https://github.com/quicmkf
+.. _quic_sgorecha: https://github.com/sgorecha
 .. _raghuncstate: https://github.com/raghuncstate
 .. _raymo200915: https://github.com/raymo200915
 .. _remi-triplefault: https://github.com/repk
@@ -1109,7 +1113,6 @@
 .. _rupsin01: https://github.com/rupsin01
 .. _rutigl: https://github.com/rutigl
 .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
-.. _sgorecha: https://github.com/sgorecha
 .. _shawnguo2: https://github.com/shawnguo2
 .. _sieumunt: https://github.com/sieumunt
 .. _smaeul: https://github.com/smaeul
@@ -1125,6 +1128,7 @@
 .. _vishnu-banavath: https://github.com/vishnu-banavath
 .. _vwadekar: https://github.com/vwadekar
 .. _Yann-lms: https://github.com/Yann-lms
+.. _sjaypee208: https://github.com/sjaypee208
 
 --------------
 
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 7fe58f8..9d6bbf6 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -72,6 +72,8 @@
 +-----------------+---------------------------+------------------------------+
 | v2.12           | 4th week of Nov '24       | 2nd week of Nov '24          |
 +-----------------+---------------------------+------------------------------+
+| v2.13           | 4th week of May '25       | 2nd week of May '25          |
++-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
 --------------------------------
@@ -111,9 +113,9 @@
 +-----------------------+--------------------------------+
 | Build Option          | Deprecated from TF-A Version   |
 +=======================+================================+
-| CTX_INCLUDE_MTE_REGS  | 2.11                           |
+|                       |                                |
 +-----------------------+--------------------------------+
-| ENABLE_FEAT_MTE       | 2.11                           |
+|                       |                                |
 +-----------------------+--------------------------------+
 
 --------------
diff --git a/docs/change-log.md b/docs/change-log.md
index 1e6647f..721e0f3 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,1040 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [2.12.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.11.0..refs/tags/v2.12.0) (2024-11-19)
+
+The threat model for context management and the asymmetric CPU extension support
+feature is not available in the release.
+
+### ⚠ BREAKING CHANGES
+
+- **Bootloader Images**
+
+  - remove unused plat_try_next_boot_source
+
+    **See:** remove unused plat_try_next_boot_source ([2c303e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c303e393befcd063df60806e5208ff09958d573))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Branch Record Buffer Extension (FEAT_BRBE)**
+
+    - allow RME builds with BRBE ([9890eab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9890eab5743629c10a3d7432cdb89b65e11c83b8))
+
+  - **Memory Tagging Extension2**
+
+    - improve ENABLE_FEAT_MTE deprecation warning ([ba65e2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba65e2d1574954cead8b474e692eef608deff4b3))
+    - remove deprecated CTX_INCLUDE_MTE_REGS/FEAT_MTE ([6f2b881](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6f2b8810f6d48bde930d4384df4b6894effcd14f))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - dtb: check for correct error condition ([7300a4d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7300a4d1676f0c929f6a41810f9bc43d4e5334eb))
+    - enable dtb modifications for CPU idle states to the rich OS ([188a988](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/188a9888e7b541299133a75b7632fdda2584833d))
+    - remove unneeded header inclusion ([8bb8f02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8bb8f02d44d1620de6c410f9091c2dd53814479e))
+
+  - **Arm**
+
+    - **FPGA**
+
+      - avoid stripping kernel trampoline ([8292f24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8292f240e5d3fc1391cb463d068a69803b72a9e7))
+
+    - **FVP**
+
+      - add DRAM memory regions that linux kernel can share ([18ec9bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18ec9bdc2d51f0b58d24e4a6520b2922e74e7dd8))
+      - add optee specific mem-size attribute ([75265a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/75265a16c978c75c9737e03101fb4616b0aedf7e))
+      - add secure uart interrupt in device region ([fc3a01a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc3a01aac3a8c4ba2d491e77681567a2727935e3))
+      - enable FEAT_MTE2 ([d081c61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d081c6116e455732b579304268027b9cd98e50ff))
+      - fix the FF-A optee manifest by adding the boot info node ([bf36351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf36351acaa5ecef6243513d68afb083d7aba07e))
+      - update the memory size allocated to optee at EL1 ([4739372](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47393722783c4cc636244388dccd9987ecf97fa9))
+
+    - **Neoverse-RD**
+
+      - **RD-V3**
+
+        - remove NEED_* from RD-V3 makefile ([a3eef39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a3eef39f45d8e82bb306045eaf4a1f3ad37592c7))
+
+    - **TC**
+
+      - add SCP_BL2 to RSE measured boot ([7984154](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79841546a2782c400751bdc5a4d5f8c0263b3812))
+      - add stubs for soc_css_init functions ([f5ae5dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5ae5dcd89497d4c5e5187137a8392d4216a5aaa))
+      - correct CPU PMU binding ([7aca660](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7aca660c4e77477d81623df00fc7ffab2700dcb9))
+      - correct NS timer frame ID for TC ([034cc80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/034cc8087b249f87bfd42b99ac8553756274ee5a))
+      - don't enable TZC on TC3 ([8ce29a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ce29a74a44523ce3e56da09a7b64f415c08a20f))
+      - enable MTE2 unconditionally ([be8eaa5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be8eaa5e62d2a916c6521e1d9c17ec4698bbbb27))
+      - fix the MHUv3 interrupt name in DT ([1bf3325](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1bf33251a8fe774674205df9ea0f49d55233820c))
+      - retain NS timer frame ID for TC2 as 0 ([1ba0880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ba08807a58d977e2cbf0fec5ec49f29652ff997))
+
+    - **Corstone-1000**
+
+      - fix Makefile error reporting ([09bf366](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09bf366bef9bcbf10267ec036b8de7b5b35fd58e))
+      - clean cache and disable interrupt before system reset ([335c4f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/335c4f8b301ffe0fd323a25e9995c3e0b1b8aa1d))
+      - include platform header file ([783e5ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/783e5abe94a10c9aa5c7c750ec1590f0529702fa))
+      - pass spsr value explicitly ([32690ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32690bacb9564263f4ed23e27a1f22ba0a22bc9e))
+      - remove unused NS_SHARED_RAM region ([83c11c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c11c0bd119ffe8f2673aa09e17e1432b226415))
+      - update memory layout comments ([d7417ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7417adc218c1386b30658e83ea8d4f3b7b72697))
+
+  - **Aspeed**
+
+    - **AST2700**
+
+      - fix mpll calculate statement ([aa09622](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa09622233a891cb04c65a5db816e0dc76110e21))
+
+  - **HiSilicon**
+
+    - **Poplar**
+
+      - shutdown wdt0 before powering off ([88bc65d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88bc65d745c0c29f4d2d9a75abe3ea45a235a719))
+      - use sysctrl module to reset ([c961e68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c961e68e7990eb802d6638bc881afa3b7068e60d))
+
+  - **Intel**
+
+    - add cache invalidation during BL31 initialization ([3c640c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3c640c124ec02f3f0e6bbc5b6d364a0b851ba1ad))
+    - add in JTAG ID for Linux FCS ([ea906b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea906b9bb97fa6011ad974838266d5f82efc134d))
+    - add in missing ECC register ([4683946](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4683946015365e1a6e8a7fd8c8c2c72cc6043b02))
+    - add in watchdog for QSPI driver ([6704cba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6704cba25d6386469832fe82e8ec6e0fed79b0ce))
+    - bridge ack timing issue causing fpga config hung ([9a402d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a402d2f0f7e4c62c26903af1482d2f67cfa48c5))
+    - correct macro naming ([815245e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/815245e4deafc375dd62aa26821059a07e7ad2b5))
+    - f2sdram bridge quick write thru failed ([64cf9de](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64cf9deb770ea7eccd5f92a013b67b492978aea0))
+    - fix bridge enable and disable function ([90f5283](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/90f5283ec052f622285ef35210d4bc452e4b905a))
+    - fix CCU for cache maintenance ([f06fdb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f06fdb1469e8855e0b711ba86fde98b44f1d7736))
+    - flush L1/L2/L3/Sys cache before HPS cold reset ([7ac7dad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ac7dadb551ee602299aef91043dc4adbd234a3e))
+    - implement soc and lwsoc bridge control for burst speed ([a8d81d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8d81d61e120f2e5958f996cd59ab5219a8a3cce))
+    - refactor SDMMC driver for Altera products ([beba204](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/beba20403e23ab128711c2c8c9d480a3a40b804c))
+    - remove redundant BIT_32 macro ([7985ade](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7985aded701cc715bff2dd247680b9d0d2ffb42c))
+    - software workaround for bridge timeout ([e08039d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e08039d0e2b3ed69bf2b10592006be8008dcb398))
+    - update Agilex5 BL2 init flow and other misc changes ([b3d2850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3d28508427225f41d55fa3b10fe4f1f1dfbd238))
+    - update Agilex5 warm reset subroutines ([c1253b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1253b2445d6b57851118fb9cb4ee1eac9e122be))
+    - update all the platforms hand-off data offset value ([1838a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1838a39a44a058c6fc14e045fabe433c93e609c4))
+    - update CCU configuration for Agilex5 platform ([09330a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09330a49376306031cf92e26bbd6955ebfe87597))
+    - update mailbox SDM printout message ([569a03c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/569a03c7114f4a5c005a8cf4fa1dcae2b54bec56))
+    - update memcpy to memcpy_s ([e264b55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e264b5573952c72805a14e69e438168c00163e9a))
+    - update outdated code for Linux direct boot ([21a01da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21a01dac879daaded762f2feccccbdf6c07cf451))
+    - update preloaded_bl33_base for legacy product ([f29765f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f29765fd337cc0a405b1ffee945bc6a5db2d7e8b))
+    - update sip smc config addr for agilex5 ([7c72dfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c72dfac962ce1e1f95be4c974b691d667a8eae4))
+    - update the size with addition 0x8000 0000 base ([9978a3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9978a3fd8b97f024a28be798494b608f43ef5e79))
+
+  - **Marvell**
+
+    - **Armada**
+
+      - **A3K**
+
+        - reset GIC before resetting via CM3 secure coprocessor ([5993af4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5993af454fca84d1401d12eabc3c714b6b5dd953))
+
+  - **MediaTek**
+
+    - **MT8188**
+
+      - remove BL32 region protection if SPD sets to none ([207c447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/207c4470492ea5b9554051b9abaf6cc9c1a78f35))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - disable DRAM retention by default on i.MX8MQ ([108146c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/108146ce73573ca761fb2072efef0e0c4e4d50bb))
+
+      - **i.MX 8M**
+
+        - 8mq: enable imx_hab_handler ([af79981](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af799814e2639a03b3453744f06a73e77cb66e86))
+        - ensure domain permissions for the console ([f7434fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7434fa13507b8879922bcf0c55947e9b9606404))
+
+    - **S32G274A**
+
+      - avoid overwriting const fields ([bf01296](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf012960d4f1490897b6a243eb89c70d6e03161f))
+      - workaround for ERR051700 erratum ([b47d085](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b47d085a3bc918d51dae48fa7bb13678f3ae14ba))
+
+  - **QEMU**
+
+    - allocate space for GPT bitlock ([e9bcbd7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9bcbd7b2ee43b3abc89f8e505b9fd5689f91aae))
+    - exclude GPT reserve from BL32_MEM_SIZE ([7604288](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7604288577bab9a1ff02fd69e07a803b808bbfae))
+    - fix build error with spmd ([1b1b40a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b1b40a941b62a845e57ca8d2bf754396b1b5dcb))
+    - fix EL3-SPMC data store alignment ([eee52da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eee52dac2c3e6b7c9ac51624c6200d2201e65bc2))
+    - fix L0 GPT page table mapping ([147b1a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/147b1a6f068bc3db73d0f945137054af83c486f5))
+    - remove validate_ns_entrypoint ([e5362e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5362e29d556df2e4238e798513f670ca3f85aad))
+    - update rmmd_attest_get_platform_token() ([9248ee0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9248ee0cc413a209f93ee330a04890f873fec1ee))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 3**
+
+      - manually populate CNTFRQ reg ([11dff59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11dff5994671bf3ec4f26b7ea930bd4749658aa2))
+      - use correct define for GPIO reg_clr ([9876baf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9876baf180d307fe36ec846c03c05dd8a1b08d53))
+
+  - **Rockchip**
+
+    - add parenthesis for BITS_SHIFT macro ([901e94e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/901e94ed1a0d5e381d857e062c8b8289cfa80a48))
+    - fix "unexpected token" error with clang ([52cdebb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52cdebbcc5d1fffea7af837178a712c8d02bcdde))
+    - xlat: fix compatibility between v1 and v2 ([d43a2e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d43a2e8bf4b4434cf30296cc56fdaf15321e5e8b))
+
+  - **ST**
+
+    - set no-pie option when building ST elf file ([6d26d75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d26d75c374bc9c7aa03d8c745b9f5f9082b18c2))
+    - support device tree DDR sizes higher than 16Gbits for aarch64 ([cd9c92c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd9c92cd16b1beb6199ae7a7c01effb0d49ab448))
+
+    - **STM32MP1**
+
+      - remove unnecessary assert on GPIO_BANK_A value ([5c45768](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5c457689b283437cbf1ba87c48bae9e03a579aa8))
+      - skip OP-TEE header check if image base is NULL ([b452e7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b452e7a8246533a4923d54cc916bdf805f9543da))
+
+    - **STM32MP2**
+
+      - enable timer earlier in BL31 ([16a659d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16a659d73a70ce16662c0e2df4097f3496d65f63))
+      - remove mapping of BL2 DT area ([60d0758](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/60d0758411064ac67df22ade6dba460d31d00c81))
+      - set PLAT_MAX_PWR_LVL to one ([747d85e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/747d85ee77d8d8b2e04a4988f98cb2fc426103a3))
+      - use TOOL_ADD_IMG_PAYLOAD for BL31 DT ([f15f1c6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f15f1c6270d50e06eafb4202dd32326d516960f3))
+
+  - **Xilinx**
+
+    - avoid altering function parameters ([b21e287](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b21e2874f81633892e914f7d53b5bf0fe3b41a18))
+    - dcc to support runtime console scope ([238eb54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/238eb542bb746a776de82236dd25b7ae5876b743))
+    - declare unused parameters as void ([d3bb350](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3bb350c40d202bec31dde04911f1c50d3e71634))
+    - explicitly check operators precedence ([8e9a5a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e9a5a5150c631dec09b9fea610ca3846e0dce9c))
+    - fix comment about MEM_BASE/SIZE ([1e2a5e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1e2a5e2851072803a78a8e998dee1ff4ad5b7f9b))
+    - fix logic to read ipi response ([03fa6f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03fa6f42502a3b6b318a9a73a228a6c751329a8f))
+    - fix OVERRUN coverity violation ([e27b949](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e27b9491f39c4657727d3b1641680a7e5c09a3b4))
+    - handle power down event if SGI not registered ([c3ffa4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3ffa4c5bae5c2be313faa015bfffdb7b46c4122))
+    - map PMC_GPIO device node to interrupt for wakeup source ([692d32b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/692d32b5733b4520093ac059578b2e6c2429b80d))
+    - modify conditions to have boolean type ([e223037](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e223037525ef7b2e3794733ba417cbb848907dda))
+    - optimize logic to read IPI response ([02943d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02943d0d8d05e8a647a72eb11ac9159c6a257aa3))
+    - register for idle callback ([a3b0a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a3b0a3422c3f2b2718a7f8b337d019f470101d4d))
+    - rename variable to avoid conflict ([aba5bf9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aba5bf901d775ffbf77a5034eb91f3667758a4c1))
+    - warn if reserved memory pre-exists in DT ([729477f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/729477fd86fc7c471fe44f81ed58e94d1656571f))
+
+    - **Versal**
+
+      - add const qualifier ([0f9f557](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f9f5575cc2c5de913e4222c149146c149378728))
+      - add external declaration ([16c611f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16c611f8a6f6a6669265fda95115a0ade56078e7))
+      - declare unused parameters as void ([ab9aab3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab9aab38d13a0905804ab5a8480dd31828d5b3ab))
+      - evaluate condition for boolean ([b39c82e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b39c82e9201255f6a396ff9a80cb2c2ec038b588))
+      - explicitly check operators precedence ([0ed8b4b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ed8b4bffc31e52facf27445503ea668e7ba3dc2))
+      - kernel QEMU boot is failing on versal platform ([8e5252f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e5252f3c08d25575fbbcbb8cb4ed3a4b0c9d506))
+      - modify conditions to have boolean type ([1247566](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12475663b53f6e5ffe18343470d653cc092aca48))
+      - remove check for bl32 load address ([4c9ae8a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c9ae8ae1f266f7558c5bcc98491a4fbb69967f5))
+      - variable conflicting with external linkage ([e452826](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e452826ad3aa595f720be2c2500ada2f27d3eaea))
+
+    - **Versal NET**
+
+      - evaluate condition for boolean ([37c46d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/37c46d85d14021fa89186d3221621658410e8720))
+      - declare unused parameters as void ([06f63f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06f63f4b566c86209fbd13142d6c5453a6fd9c8e))
+      - explicitly check operators precedence ([a4ddd24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4ddd24f97953b6c8ad6b9dfddc240067807c502))
+      - ignore the unused function return value ([aa6df8e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa6df8ec32a48d8e57205b6bb93d4bc283d353f2))
+      - modify conditions to have boolean type ([83c3c36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c3c36b1b2869ade53f36cfd9052e6b6a17797b))
+      - remove check for bl32 load address ([c38ced2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c38ced2d279a40298cab6a4c99b046146c3a1917))
+      - variable conflicting with external linkage ([4d2b4e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d2b4e4dd7ed22a41c0569f9b2b2fd5c419a8261))
+
+    - **ZynqMP**
+
+      - add const qualifier ([bb145c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb145c9d9b543d9440b3b4fc48b8210df4b35ce9))
+      - add external declaration ([6c08d1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c08d1df0ccb14fb66ba081bbe57ea17b8b3bb1c))
+      - declare unused parameters as void ([1c43e36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c43e36ac18aeaa6816a0474655d699909d616b1))
+      - evaluate condition for boolean ([aaf6e76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aaf6e7627e11b1b8616d798975e40d71d1e03c8c))
+      - explicitly check operators precedence ([5b54231](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b542313f8af2373549e71266307b8fbbb8788cd))
+      - handle secure SGI at EL1 for OP-TEE ([f5b2fa9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5b2fa90e0c0324f31e72429e7a7382f49a25912))
+      - ignore the unused function return value ([355ccf8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355ccf895e5106d0f7a9b5932f73759277d1ab2a))
+      - modify conditions to have boolean type ([a42e6e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a42e6e44b89fb1be1d3e97e5adc4f7288bb7e69b))
+      - variable conflicting with external linkage ([eda23fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eda23fa5aa065216d9cf86176fbb916b4841c874))
+
+  - **AMD**
+
+    - **Versal Gen 2**
+
+      - add const qualifier ([a0745f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0745f21aa0c5c869a3788e8f2c590bace11ef0b))
+      - add external declaration ([17a8f41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/17a8f41e458e662c878fc8549d7a04a49e88abac))
+      - add ufs specific features support ([b9c20e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9c20e5d144347ca28e17df080b7ee9bf0dd9377))
+      - correct the UFS clock rates ([b048601](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b048601eeeeb34fb1e7642d1ed7f18f9a51d6ae9))
+      - declare unused parameters as void ([851df3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/851df3c8915d5832d9ac1d58dc3420847cacb0a0))
+      - explicitly check operators precedence ([15a9e38](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15a9e381cdfc607e516f86adc118d036ce78aa86))
+      - ospi data integrity cases are failing ([a147362](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a14736268bd5156f657286b535af5d27959dec99))
+      - update check for TRANSFER_LIST macro ([7d09198](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d09198f58cefd10a9ca19305782785632ffa72a))
+      - variable conflicting with external linkage ([ca39fd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca39fd46c1ce0203df7f797fa6bd8a4fc5336c38))
+
+  - **Nuvoton**
+
+    - fix MMU mapping settings ([0a1df64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a1df6411734d1793e06e508f27bcf95f01c703f))
+
+- **Services**
+
+  - **RME**
+
+    - **RMMD**
+
+      - continue boot if rmmd_setup fails ([fdd8a24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdd8a24b9892fa0e67580dc25f7e7ca0b54c870e))
+      - fail gracefully if RME is not enabled ([eacbef4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eacbef4c643a5ee69828a7004abf0097b3d3f728))
+      - handle RMMD manifest loading failure ([0c70781](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c707813e9e734d9a62d5cdc592e68e245f4f557))
+      - ignore SMC FID when RMM image is not present ([adcd74c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/adcd74ca05fe4d7c3c047c0108cb9f136b67be49))
+      - remove the assert check for RMM_BASE ([8cb9c63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8cb9c635775b2f1c413c28ea8610dc81b6e8928f))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - use write_el1_ctx_timer() macro to set cntkctl_el1 value ([19082c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19082c20d98456d147816d8ebf01f4e6721c7b12))
+
+    - **SPMD**
+
+      - remove spmd_handle_spmc_message ([6c378c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c378c2feffd8826542322e8d2cc53fd7f0d8252))
+
+    - **SPM MM**
+
+      - carve out NS buffer TZC400 region ([1922875](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/192287523350dfdc06b794ae2fbc1827ff69ab72))
+
+  - **DRTM**
+
+    - do cache maintenance before launching DLME ([23378ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/23378ae0bdcdaee5764af9ebf5faed7cdb8b2737))
+    - return proper values for DRTM get and set error SMCs ([5e1fa57](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e1fa57459aa27a28bb21be5496fb471350b6046))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - modify the fix for Cortex-A75 erratum 764081 ([7f152ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f152ea6856c7780424ec3e92b181d805a314f43))
+    - workaround for Cortex-A720 erratum 2792132 ([b1bde25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1bde25ed9b302a2203a928457c91693ed7f91a7))
+    - workaround for Cortex-A720 erratum 2844092 ([1214090](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12140908a52230081f85069f0f0a400ddabf44ef))
+    - workaround for Cortex-X4 erratum 2816013 ([1e4480b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1e4480bb54b0f567688cfbea2119aa703fcbb7b8))
+    - workaround for Cortex-X4 erratum 2897503 ([609d08a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/609d08a86db2ddf09f98105b999d57b8e2eecc8b))
+    - workaround for Cortex-X4 erratum 3076789 ([db7eb68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db7eb68817dad1a429a2f6518926791c47091b1c))
+    - workaround for Cortex-A520(2938996) and Cortex-X4(2726228) ([4a97ff5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a97ff5111204a18b4f72d1e1cd3d8285f16289d))
+
+  - **EL3 Runtime**
+
+    - correct CASSERT for cpu data size ([483dc2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/483dc2e43e550cf5d4541a7b164b49edbaa467e6))
+
+  - **PSCI**
+
+    - fix parent parsing in psci_is_last_cpu_to_idle_at_pwrlvl ([01959a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01959a1656a08dacd1d036d0441165d52bf7563e))
+
+  - **ROMlib**
+
+    - prevent race condition on the build directory ([25cde5f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25cde5f810422867bf03b2c0e8354dcee2493e8a))
+    - wrap indirectly included functions ([d95d56b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d95d56bd2bfc87951f35d2badde9db336c0a6489))
+
+  - **GPT**
+
+    - fix GPT library fill_l1_tbl() function ([d024cce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d024cce376f01652b91ebdef286dceffc9ffb063))
+    - fix RME GPT library bug ([6350aea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6350aea2f186c593ef46737f573de5e4833a9433))
+
+  - **Translation Tables**
+
+    - correct attribute retrieval in a RME enabled system ([e3c0869](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3c0869f6fbd8008b556738384e3f3a22cf981c3))
+
+  - **Authentication**
+
+    - check the presence of the policy check function ([491832f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/491832fedf979b6b0c00c5c5411780047f106804))
+    - correct RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID ([759994a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/759994aa3b1ad1e54ef3a998d0685108fec6d27c))
+    - remove the bl2 static c file ([ac106f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac106f208fad311e691b69e116632239c635a81f))
+
+    - **mbedTLS**
+
+      - fix error return code for calc_hash ([885bd91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/885bd91f27fd31d46f33861b94a814fa4537ab5f))
+      - sign verification issue with invalid Key/Signature ([7731465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7731465252bd82ce97620a327f3b5d8905f8bdb1))
+      - add extra hash config to validate ROTPK ([014975c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/014975cea46261d84a934644be2ad53bbdc0dc79))
+
+    - **mbedTLS-PSA**
+
+      - fix P-384 PSA key signature verification ([12a8e95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12a8e95303c051dc5671441a6419741db3b0964e))
+
+  - **GUID Partition Tables Support**
+
+    - fix unaligned access in load_mbr_header() ([21a77e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21a77e08921a13ac4adc523a136d829333a854f1))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - fix GITS_CTLR.Quiescent bit definition ([2da29d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2da29d2d07cdd8c52a1c1d6f26d7d45ac11ef2be))
+        - incorrect impdef power down sequence ([b1925dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1925dcfd97a5d77a796bee8164519b4e8254d8c))
+        - wait rwp when gicr_ctrl.enablelpis from 1 to 0 ([66668c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66668c77cb140c3af1a801b8f56b0c0ec65c4c21))
+
+    - **MHU**
+
+      - fix compilation error with ENABLE_ASSERTIONS=0 option ([e2e8a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2e8a397f88eaedb9d3f16b6b4560eec51aee7e0))
+
+    - **RSE**
+
+      - include lib-psa to resolve build ([654ae70](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/654ae705c35baa1fbd13a0cd8558a64c8454347c))
+
+  - **NXP**
+
+    - **SFP**
+
+      - shift gpio register offsets by 2 ([d30312a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d30312a2dcdbe7aa651f8770d9b00e6ae83baacc))
+
+    - **Clock**
+
+      - broken UART clock initalization ([f8490b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f8490b85b49c92799a792587658eca4cf36fd4f6))
+      - function parameter should not be modified ([8ee0fc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ee0fc31992538823177e764e4522293ea829957))
+
+  - **ST**
+
+    - **Clock**
+
+      - adapt order of CSS on LSE and HSE ([eca5103](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eca510346d9ae7d14eea53ec01554bbde6cb2e69))
+      - display proper PLL number for STM32MP13 ([039b7d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/039b7d4673e5b39056a6c0c40204aad2b0258581))
+      - do not reconfigure LSE ([f4a2bb9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4a2bb986b43fcb1c0c8c45b5d9a93798f655453))
+
+    - **DDR**
+
+      - fix coverity issue in ddrphyinit ([5dd1d54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dd1d5447750e1be9377ae8d1c4fce2608a53a63))
+      - move skipddc_dat definition ([13cc1a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13cc1a506428398cc8cc142015dca10d24840f96))
+
+    - **GPIO**
+
+      - configure each GPIO mux as secure for STM32MP2 ([179a130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/179a130aea4876c7fc89606c65b55f143724eb38))
+
+- **Miscellaneous**
+
+  - **DT Bindings**
+
+    - update STM32MP2 clock and reset bindings ([8522909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85229098ab70dfb65905f9ad7229db6478335a00))
+
+  - **FDTs**
+
+    - reserved memory: detect existing region ([4248806](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42488064e10383247d0c321fe1e7fc13eec0752c))
+
+  - **SDEI**
+
+    - fix a crash when attempting to bind more events than are available ([4096bd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4096bd66c7af0a5661c7926460f2a2ca4162388d))
+
+- **Documentation**
+
+  - fix CPU type for mt8195 ([65ada75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65ada7571781317f16240ee3694bd684fd3bdaf5))
+  - fix the example command for doc build ([9db2b05](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9db2b059eb76eaf51af8e434904caf277b998c99))
+  - point poetry readthedocs virtual env ([5383a88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5383a88b93abead45ab3479536d1b1516d9be3f8))
+  - refactor poetry dependency group ([4a29299](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a29299f2e1640dc9f3136682b914c39930562eb))
+  - replace "ARM-TF" with "TF-A" in diagrams ([c4067a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4067a9df6e9c478a824bd5b0ac44b84d48c9b40))
+
+- **Build System**
+
+  - correct feature assignment for ARM v8.8 compliance ([94ff1d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94ff1d98c95db491137177c2160ef1afe944ff5f))
+  - ensure `$(ROT_KEY)` depends on correct directory rules ([7a95759](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a95759f935202c1f25df10eb32c67bbd69db3c8))
+  - fix incorrectly-escaped armlink preprocessor definitions ([df52e26](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/df52e2600deef3fff250d337d06f55863d1dfd76))
+  - pass the PLAT option during FIP tool compilation ([40469bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40469bf977a615400424cdcd78c350b3310ebd2f))
+  - string split into two lines causing error ([4f32179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f321794ffaacad74258082272163a61f3db8477))
+
+
+- **Tools**
+  - **fiptool**
+
+    - update the fiptool and certtool to fix POSIX build ([ccbfd01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ccbfd01d95b9b35acb3e2ca5f25379ce8fa0ed1c))
+
+- **Dependencies**
+
+  - **checkpatch**
+
+    - detect issues in commit message ([1a72174](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a721748605bc753089bc34c6010aa236c9d0ab7))
+### New Features
+
+- **Architecture**
+
+  - **Fine-grained Traps 2 (FEAT_FGT2).**
+
+    - add support for FEAT_FGT2 ([33e6aaa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33e6aaacf1e8f327b33fe2db1f5e964b0adb41c7))
+
+  - **CPU feature / ID register handling in general**
+
+    - add ENABLE_FEAT_LS64_ACCDATA ([19d52a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19d52a83b755cdf6d9b7defc7eb821eb62e80310))
+    - add new feature state for asymmetric features ([43d1d95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43d1d951ddb3b725d372884f314babb6594fcd47))
+    - upgrade PMU to v8 (FEATURE_DETECTION) ([515d2d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/515d2d46a318fa3c4c172491c6408c032e6a6b15))
+
+  - **Debug Extension (FEAT_Debugv8p9)**
+
+    - add support for FEAT_Debugv8p9 ([83271d5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83271d5a5aae06c23c59a32c30a0fe83fb82e79f))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - introduce spe_disable() function ([651fe50](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/651fe5073c790647305363a4de05cf050e0851de))
+
+  - **Trace Buffer Extension (FEAT_TRBE)**
+
+    - introduce trbe_disable() function ([b36e975](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b36e975ea374589270fc4010aa247e1e56432bda))
+
+  - **Extension to SCTLR_ELx (FEAT_SCTLR2)**
+
+    - enable FEAT_SCTLR2 for Realm world ([b17fecd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b17fecd6cf23f50346d70ec84f5708c95a2db5f8))
+    - add support for FEAT_SCTLR2 ([4ec4e54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4ec4e545c66cb888bfbedcea4030a234421457d7))
+
+  - **128-bit Translation Tables (FEAT_D128)**
+
+    - add support for FEAT_D128 ([3065513](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306551362c15c3be7d118b549c7c99290716d5d6))
+
+  - **Translation Hardening Extension (FEAT_THE)**
+
+    - add support for FEAT_THE ([6d0433f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d0433f04045f52856ecb837efc873a5504d9fa2))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - adjust H616 L2 cache size in DTB ([ee5b26f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee5b26fd0058d5e696cdf83bf389351eab296bf7))
+    - h616: add I2C PMIC support ([0444589](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/044458981f986b03445185b646bebbea1d90f11f))
+    - h616: add support for AXP313 PMIC ([0385136](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03851367dbd46f73708fa35da2b501489e44afa4))
+    - h616: add support for AXP717 PMIC ([646d06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/646d06b2378b39b8dfa713b74f936a2b02782e96))
+
+  - **Arm**
+
+    - **Common**
+
+      - add support for loading CONFIG from BL2 ([973e0b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/973e0b7f2cc9ac64132b2179295c424a88b690ea))
+      - add fw handoff support for RESET_TO_BL31 ([1a0ebff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a0ebff784c11f0b11f203b56eeb3180f994c0b9))
+      - correct the RESET_TO_BL31 x1 handoff arg ([5da68cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5da68cc477adf0f686eeb9b6c8c53c1104805f24))
+      - load dt before updating entry point ([c1c406a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1c406a4de90b859a2e534304e33331ecd3dcef8))
+      - move HW_CONFIG relocation into BL31 ([fe94a21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe94a21a6815fc8623074e7184d87583f2f58940))
+      - remove critical handoff code from assert ([cca1b72](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cca1b72b3bf25dab03d3527c9fbe0f5d368382cc))
+      - makefile invoke CoT dt2c ([0e0fab0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e0fab0ca2190d75dd12b655e043ed8b6053221f))
+      - generate tbbr c file CoT dt2c ([479c833](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/479c833afcfce3afebefdc8eecefea71c09f0bf1))
+      - add COT_DESC_IN_DTB option for Dualroot ([731ac5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/731ac5ea043efb333ea74c8443c10989acce5d94))
+
+    - **FPGA**
+
+      - enable new CPU features ([1920a32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1920a32b7fd32c22f4cef6d948c1d0be4efce0e5))
+
+    - **FVP**
+
+      - change UART0-1 to NS device region ([cd656a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd656a5612e6f6942fd8fb768b5dd948efbc37ac))
+      - add Cactus partition manifest for EL3 SPMC ([5134623](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51346236c3f07fd86bf14f4743517ab1d15bd56c))
+      - add cpu power control ([d38c64d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d38c64d2466006104142ae23a673a9cf2b4170e2))
+      - add Dualroot CoT in DTB support ([0af86f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0af86f08ce5c39e3d53ccd9daa77084acef09fa7))
+      - add flash areas for secure partition ([9fb7676](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fb767630dbb3a54eff17b9b9b83078a7b3e77b7))
+      - add SPM manifest for OP-TEE at S-EL1 without S-EL2/Hafnium ([41d73bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/41d73bffe1cac198ef1f21149ac64f784f5ae8db))
+      - allow SIMD context to be put in TZC DRAM ([b4c23ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b4c23adf58dce011ce5119cfc79f4312cea855f7))
+      - fdts: add stdout-path to the Foundation FVPs ([2faccab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2faccaba80318b48e7ae738a909a38a989ed3c5e))
+      - replace managed-exit with ns-interrupts-action ([887cec9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/887cec9caedb87f824f8f35adbf058e1e83b250e))
+      - scale SP_MIN max size based on SRAM size ([3b5eca9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b5eca9e7a96f7a6f3c764fb981a3b2bfe67e514))
+      - update FF-A version to v1.1 supported by optee ([4f37e1e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f37e1e8b233a2968dd32708eef0a4a44d093b7a))
+      - remove duplicate jumptable entry ([180a3a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/180a3a9ed3e0ee80f4ed4d02d671a7b0fb28db6d))
+
+    - **Neoverse-RD**
+
+      - add a routine to update NT_FW_CONFIG in BL31 ([c6b27c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6b27c4916d41db9a8f6be089970fa5f79634f7c))
+      - add CSS definitions for third gen platforms ([6d52713](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d5271346d38ac9899bc2f8c9fe96b32bcef05c8))
+      - add DRAM layout for third gen platforms ([10eb4c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10eb4c4bee31786800a8d61ef54d68d22db97221))
+      - add firmware definitions for third gen platforms ([e517ccf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e517ccf52cf9f2578d980b5340900fafe3e9a6e6))
+      - add MHUv3 channels on third gen multichip platforms ([47348b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47348b1c53c1000f7b36593aa1641240d0509947))
+      - add MHUv3 doorbell channels on third gen platforms ([46d474f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46d474fc9fc99b1d8c9e8b66514cc380ec10aa9a))
+      - add multichip pas entries ([c72e9dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c72e9dcdd872f3922eb093afbfded0dd78533cc7))
+      - add pas definitions for third gen platforms ([896e9aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/896e9aa98b5cf25a4b5e9d11a58265fdb43dca1e))
+      - add RoS definitions for third gen platforms ([fad5a20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fad5a209a03ae7a893b8e93197ed6e795fe370a6))
+      - add scope for RD-Fremont variants ([84973bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84973bb3cafeb21f7c706335570fbef41ab62179))
+      - add SRAM layout for third gen platforms ([5a37d68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a37d68c78b0c1fcd527e2d6fbc40ecf84dc0f15))
+      - allow RESET_TO_BL31 for third gen platforms ([4abcfd8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4abcfd8b2ce2fd8aad9f4de652a11a0b6a28e8dd))
+      - enable RESET_TO_BL31 for RD-V3 ([527fc46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/527fc46541b85371b01dc55e5ebc1ba92c1b6b47))
+
+      - **RD-V3**
+
+        - add DRAM pas entries in pas table for multichip ([6a9cf0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a9cf0e5aaf6bc97b433e79c74cf4ba435c877b2))
+        - add implementation for GPT setup ([0876c74](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0876c74285377857d34701f9279cc15b60f6ac50))
+        - add support for measured boot at BL1 and BL2 ([6182950](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/61829505d2d40a1b5a3065fda53df7f6b833cdb3))
+        - add support for RD-Fremont ([c0513e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0513e0f8500d8552646f57b2a2e68113c48ad2e))
+        - add support for RD-Fremont-Cfg1 ([6a0cb48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a0cb487fd61e0c583465338bb502833803b8a5a))
+        - add support for RD-Fremont-Cfg2 ([eedb2d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eedb2d820a26300314ac81773fe597938e67698e))
+        - enable AMU if present on the platform ([faf98b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faf98b3fe24926bd556b175ce07c97a63b058b45))
+        - enable MPAM if present on the platform ([e951985](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9519857d36517624f954b85b7f24f677fdc6765))
+        - enable MTE2 if present on the platform ([f801377](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f80137720cbe08c2de1b130b1a4ba44af037fa1d))
+        - enable SVE for SWD and NS ([7e2736b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e2736b0c1fbe5a41cd815da0b625a90f0142a57))
+        - fetch attestation key and token from RSE ([0e323ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e323ec5c4e824c113394f87d1c77103471e8123))
+        - helper to initialize rse-comms with AP-RSE MHUv3 ([2a35fcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a35fcdd9faa056e182a43ea6e53dc529bfc4186))
+        - initialize GPT on GPC SMMU block ([ba35fac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba35fac174ae4a9d52625e709863b6c565608538))
+        - initialize the rse comms driver ([f546113](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f54611376113d7c0cfdfd0eb89752040deb99aff))
+        - integrate DTS files for RD-Fremont variants ([1b96641](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b966414c1a2a38a931eb4499bc209c37c4f39db))
+        - update Root registers page offset for SMMUv3 ([859355f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/859355f27598da4f9ac76c0d12d1f8db4499e131))
+        - set CTX_INCLUDE_SVE_REGS build flag for RD-V3 variants ([1551834](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/155183432afffa8dad4260b0dc4eeef60a8385cd))
+
+    - **TC**
+
+      - add default SLC policy for the gpu ([bebefe0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bebefe0f33411245325c9a25db4eb9d7cbec69fc))
+      - add device tree binding for SPE ([77080f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77080f6aaf7e1cde46a4d48a9e8eb673119dd3ff))
+      - add device tree binding for TC4 ([3cedc47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3cedc47b1d4cf46622b4b5413fab01d3224dc872))
+      - add DSU PMU node for tc3 ([d3ae677](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3ae67771d14e7ffa06793661833654681934d39))
+      - add dts entries for MCN PMU nodes ([1401a42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1401a42c950751170c5cf14106d1872160d7ecea))
+      - add MHUv3 addresses between RSS and AP ([5ab7a2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ab7a2f2eac2b9e398d83ca2a16738f38a18baf6))
+      - add MHUv3 doorbell support on TC3 ([4f65c0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f65c0beaad1a73e45919eb0b450a86c4f58de27))
+      - add MHUv3 DT binding for TC3 ([6c069e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c069e7168445d5fa1e1a49dbfc269faa65bfa62))
+      - add MHUv3 register addresses for TC4 ([36ffe3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36ffe3e1be3fe91e2b709b769eb4f17545f6ce04))
+      - add new TC4 RoS definitions ([e9e83e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9e83e96bb0f7d83dd7e8eae3a3a82f391922bd9))
+      - add NI-Tower PMU node for TC3 ([169eb7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/169eb7daf248e75d40cd72a434aedc70a3d9ebdb))
+      - add PPI partitions in DT binding ([ebc991b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebc991b3a11a01142d8e4d71263c5a9a5f40db1b))
+      - add system generic timer register definition for TC4 ([d6b6a8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6b6a8b7cc9fa872f752640a52b9a752fa50e3a8))
+      - add uart node in spmc manifest ([880dcd0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/880dcd0d791288dab34f9e6668f9491796ef687a))
+      - allow TARGET_VERSION=4 ([e8e1b60](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8e1b60820dcba1f2be151d296a8e81de9bed8ba))
+      - bind DPU SMMU on TC4 ([e365479](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e365479d0d89999f815ea71b1511ff7952b479e2))
+      - bind GPU SMMU on TC4 ([11ec5de](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11ec5de6957206c9b1ec84b78cccf4e876688a84))
+      - bind SCMI over MHUv3 for TC3 ([f2596ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2596ff1a8c0c3daddcd406a18224fce9af0f1fc))
+      - bind SMMU-600 with the DPU on TC3 FPGA ([4c6960c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c6960ca4040e5628874f48576170b6f8f3904a9))
+      - bind SMMU-700 with DPU on TC3 ([0458d3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0458d3acae25aa98f28bc0e0aa578fdce7ae92fa))
+      - change GIC DT property 'interrupt-cells' to 4 ([1300bbc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1300bbce15308868fefda1be9ee7b4fccedde951))
+      - configure MCN rdalloc and wralloc mode ([bb04d02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb04d0232e8eeb593028aa730618be35d32a4f22))
+      - enable el1 access to DSU PMU registers ([de8b9ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de8b9cedccd652c357aff5311f8d7cb9d663514b))
+      - enable Last-level cache (LLC) ([e1b76cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1b76cb06a70b5c3d9b46a71c26e7e889dcee91b))
+      - enable MCN non-secure access to pmu counters on TC3 ([adc91a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/adc91a3440af73e2799023117764c6e1b1fd26fb))
+      - enable SME and SME2 options for TC4 ([9face21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9face2123a5925619d54070d0a9e4e628084eff3))
+      - enable trbe errata flags for Cortex-A520 and X4 ([74dc801](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74dc801d4b284e0b3829ab8ec741e0f2c311a7c2))
+      - make SPE feature asymmetric ([7754b77](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7754b770cff6fb956e0384150c1f84a1a6abc620))
+      - make TCR2 feature asymmetric ([3e8a82a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3e8a82a030735c14eab0d15fa6f65d7c3f90042d))
+      - move flash device to own node ([62269d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62269d47439e34c161f2c4990f9fdc536d82943a))
+      - provide target_locality info of AP FW components ([3201faf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3201faf3563930d90a0eb2fa6fad92f65b01101e))
+      - remove static memory used for fwu ([25a2fe3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25a2fe3b74689614f73138d130ab0cae14269b51))
+      - setup ni-tower non-secure access for TC3 ([89c58a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89c58a5087f12f0e965ce8fdf946038d5799d07d))
+      - specify MHU version based on platform ([04085d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04085d6eb47b67833d0a5444c92c9856b38459f6))
+      - support full-HD resolution for the FVP model ([dd5bf9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd5bf9c5e26ea47988cde76f916495031ecc85c9))
+      - update DT for Drage GPU ([b3a4f8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3a4f8cfcfad1df90273d0e131c2016068c57f61))
+
+    - **Corstone-1000**
+
+      - add multicore support for fvp ([16f4862](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16f48623d8d398ec588a958accb037c6debb7f7b))
+
+    - **Automotive RD**
+
+      - **RD-1 AE**
+
+        - add device tree files ([bb7c7e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb7c7e713074e6254955e9e64386493a7ad810f1))
+        - enabling Trusted Board Boot(TBB) for RD-1 AE ([2638496](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2638496965edd80e43af71a5952e7005d1fd3e8c))
+        - introduce Arm RD-1 AE platform ([f661c74](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f661c74b528f3aee6f30a28a82e8c76ab26f35f7))
+        - introduce BL31 for RD-1 AE platform ([daf934c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/daf934ca918057b13fecfe949315e097ca358329))
+
+  - **Aspeed**
+
+    - **AST2700**
+
+      - set up CPU clock frequency by SCU ([e3d1bbd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3d1bbdb08f643ad54e79c678d9f8cadaf63d4ce))
+
+  - **Intel**
+
+    - add build option for boot source ([ef8b05f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef8b05f559a698cdeca43b3ad287d720f0c22a8a))
+    - add in SHA384 authentication ([cab83c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cab83c34871aa3d20bab81d3fca34c3d746c3db4))
+    - add QSPI get devinfo mailbox cmd ([8fb1b48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fb1b484ac74f945eb483453b3f7e776c13b7b90))
+    - clock manager PLL configuration for Agilex5 platform ([e60bedd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e60bedd5e134e2ad996a0d21a8170caec12c2dd2))
+    - direct boot from TF-A to Linux for Agilex ([b5c3a3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5c3a3fc94b43f273332518024d4955e2c54a995))
+    - enable VAB support for Intel products ([3eb5640](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3eb5640a7d9277eee80b5b31bb30230a374e0fb0))
+    - pinmux and power manager config for Agilex5 platform ([94a546a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94a546acc4d6e659f64266d93d9e74b0a2b86f4f))
+    - update Agilex5 DDR and IOSSM driver ([ce21a1a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce21a1a909f2ec98f83c25dd2ed3b7fedd46c46b))
+    - update BL2 platform specific functions ([fa1e92c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa1e92c6360280447a63422b3844df5abf186577))
+    - update hand-off data to include agilex5 params ([6875d82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6875d823ede6f3668e3c176e97083dea97ab236d))
+
+  - **MediaTek**
+
+    - change log level from INFO to VERBOSE ([5f2f384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f2f384890c44756c6b6d946ae675d72bdadc904))
+    - configure DEV_IRQ as G1S interrupt ([240a1ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/240a1ecd1818e3098d641bd3304acda8b1744809))
+    - move plat_helpers.h to the common folder ([b741293](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b741293f34e394dc544250b3bad39a148e206f6d))
+
+    - **MT8186**
+
+      - add common and MT8186 TRNG driver ([8c1740e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c1740e2f260e662ed13fc04e1702c20b66d459f))
+
+    - **MT8188**
+
+      - add MT8188 TRNG driver ([b88d1f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b88d1f527baa5e2666df465acb85e09a2f8c9f8b))
+      - update SVP region ID and permission ([fc77c69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc77c69a17c6228c29113c695efc6aac1a8f6b18))
+      - update SVP region ID protection flow ([e66c4ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e66c4ea8ae2c586e648e85370c1f04c0b67bbfcb))
+      - update the memory usage for SCP core0 and core1 ([83112aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83112aa24f408fda256c536b0880df46726db593))
+
+    - **MT8192**
+
+      - update memory protect region ([7587cfd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7587cfdd96029247145d992ac042bf3af0c2f20d))
+
+    - **MT8195**
+
+      - update memory protect region ([4224783](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4224783f8403031fc12c340efdc87e3cda30fb22))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - add helper to take params from BL2 ([7eae1db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7eae1db027149e361c84395a14115324d430aa52))
+
+      - **i.MX 8M**
+
+        - **i.MX 8M Nano**
+
+          - optionally take params from BL2 ([c37a877](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c37a877e563fd3953e3ea0dc29570cbd5e13aa36))
+
+        - **i.MX 8M Mini**
+
+          - optionally take params from BL2 ([11d32b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d32b33ea3331adf31fac7fe499176a739178b1))
+
+        - **i.MX 8M Plus**
+
+          - optionally take params from BL2 ([3d9fea9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d9fea941a3be346ea5382c69b06d05ca470903a))
+
+      - **i.MX 9**
+
+        - **i.MX93**
+
+          - optionally take params from BL2 ([02d1813](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02d1813e8701752ec6bb23ad0c1e68be2f4b38e4))
+
+    - **S32G274A**
+
+      - add ncore support ([5071f7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5071f7c7ee0c1ef1498d71f6ac65e71014044498))
+      - enable BL2 early clocks ([66af542](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66af5425a6c28af7f426a82af4ec7ea4049aa6f2))
+      - enable workaround for ERR051700 ([cc6e9b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc6e9b01900b0f4101e012889b19ff225ff55001))
+      - use s32cc clock driver ([f1e4ac5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1e4ac56b53029e67b2cb626b637a4bfe4904866))
+
+  - **QEMU**
+
+    - **SBSA**
+
+      - handle the information of CPU topology ([c891b4d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c891b4d83578db25d24d2a8e3e7e419e65773ac8))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 5**
+
+      - add PCI SMCCC support ([682607f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/682607fbd775e37fb5631508434dab9e60220c9a))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - populate kaslr-seed in next stage DT ([b9e34d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9e34d14c954a9af21deb70acc4579b4494824fb))
+
+  - **Rockchip**
+
+    - add RK3566/RK3568 Socs support ([9fd9f1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fd9f1d024872b440e3906eded28037330b6f422))
+
+    - **RK3588**
+
+      - enable crypto function ([b833bbe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b833bbe6f088e3ee78037515d6c7c5ebb6d9a0cc))
+      - support rk3588 ([e3ec6ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3ec6ff4b24c7daa4dfa82709c23a22829947160))
+      - support SCMI for clock/reset domain ([04150fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04150fee44cc0dec5bbe4cce42e2b626695d6f52))
+
+  - **ST**
+
+    - add FWU with boot from NAND ([795a559](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/795a559bc59887543afa76f05397382befd14fb8))
+    - add stm32mp_is_wakeup_from_standby() ([87cd847](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/87cd847ce5640039068993868d6f853e9035c01a))
+    - manage backup partitions for NAND devices ([ae81d48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae81d48d8366bf2d7e890741bb92262b3d3a1aaa))
+    - manage BL31 FCONF load_info struct ([aa7f6cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa7f6cd8b363fb97efd232991eb9ccedc2316a9d))
+
+    - **STM32MP1**
+
+      - always boot at 650MHz ([f655922](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f65592278869951330325085cf373c3306ccab57))
+      - handle DDR power supplies ([47e6231](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47e62314b6baee0e5647c903b0feeba47f804df0))
+
+      - **STM32MP15**
+
+        - remove OP-TEE shared mem ([8dd2a64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8dd2a64a12b3ee47507aab4fb0294d366a5a5159))
+
+    - **STM32MP2**
+
+      - add BL2 boot first steps ([db77f8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db77f8bf227b1ffc6b282408aeccc4737cb1fc78))
+      - add BL31 device tree support ([27dd11d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/27dd11dbf5a7dc3d9894e6bae9630b4e5aa36d59))
+      - add defines for the PWR peripheral ([6add715](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6add715405bd92e5f5ad59da79c3a23031162544))
+      - add fixed regulators support ([c3a7534](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3a7534167b22d6a14fb0ee224bbb7b49478a479))
+      - add fw-config compilation ([5af9369](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5af9369c6ce0beff681ce1548bb5d614c3a6a85e))
+      - add helper to get DDRDBG base address ([2fd7b23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fd7b230ee8605d109167e1a6f76d87c7fb132f7))
+      - add minimal support for BL31 ([03020b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03020b6688b459da84bdb2a3fb58c99916bfd7f7))
+      - add RETRAM map/unmap capability ([52f530d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52f530d3ab9d27db653670511b238d54e212cf0f))
+      - add RISAB registers description ([631c5f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/631c5f86d5438e92e1d64e7dfdab58e92ad3e24f))
+      - boot BL33 at EL1 or EL2 ([c900760](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c900760d47d9fa9833610f5b831712cec1ba2ef2))
+      - disable unsupported features ([128df96](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/128df96579f4837ed9571a1843a5b842de52ed3c))
+      - display CPU info ([381b2a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/381b2a6b02ef5b0245f200b8c2d42a4a58cf88be))
+      - enable DDR driver ([213a08e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/213a08eb422a69bc7c95579fadf076f5af152f49))
+      - enable DDR sub-system clock ([5e0be8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e0be8c0241e5075b34bd5b14df2df9f048715d3))
+      - get chip ID ([154e6e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/154e6e62fe851b95cd17087a8cdd53bfbb39613b))
+      - handle DDR power supplies ([e2d6e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2d6e5e21adcf9e41a335c31d5c337c65ad0a133))
+      - improve BL31 size management ([64e5a6d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64e5a6df4638af5a5c308c9ebd4aee5a839f7e3e))
+      - initialize gic and delay timer in bl31_plat_arch_setup ([77847f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77847f037df3e28ac221396f118e9fd4189b1894))
+      - introduce DDR type compilation flags ([d07e946](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07e9467d375bd414fefc86dead4a833572a166a))
+      - load FW binaries to DDR ([9a0cad3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a0cad3917e6bb76694e02fd2e099ccb564a6431))
+      - load fw-config file ([a846a23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a846a23596d97b90f203dc39aeef00c0ccd88b9d))
+      - manage DDR FW via FIP ([ae84525](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae84525f44ddfe8abd66644475899fdc19893481))
+      - print board info ([cdaced3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cdaced366844b80024a8871adcbc94fbe31f6f1b))
+
+  - **Texas Instruments**
+
+    - implement DM_MANAGED suspend ([9b7550f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b7550f1f0caaa20acb6140211ac298e74894f22))
+
+  - **Xilinx**
+
+    - add feature check function for TF-A specific APIs ([9a0f5d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a0f5d128ac70da64bc33731c4e4b29007692cc3))
+    - add none console ([6d41398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d41398382430134308a513c027b77ec70b03ae4))
+    - remove PM_IOCTL and PM_QUERY_DATA APIs ([924f8ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/924f8ce2e966d2ffdb2c0f29c72cb3a68d293b45))
+    - update SiP SVC version number ([c26aa08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c26aa08bee58e81710ee9d884247fdf9b23c0022))
+    - update TF-A to passthrough all PLM commands ([4661c8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4661c8f508d3ecdb7a258c71a26f489ea1bffc21))
+
+    - **Versal**
+
+      - add DTB console to platform.mk ([d629db2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d629db247648acdb703d841b4d3d303506af6ff0))
+      - add support for QEMU COSIM platform ([db827f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db827f99a0132389ab18836b9419406b45ccd11c))
+      - dedicate console for boot and runtime ([d533f58](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d533f58d556e729a5705b9f1aaeac467291dc686))
+      - deprecate build time arg VERSAL_PLATFORM ([09ac1ca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09ac1ca27c6497cd1e04e108d4d927500d737991))
+
+    - **Versal NET**
+
+      - add DTB console to platform.mk ([d61ba95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d61ba95eecf61b660cc5161a7e4fd68948775e39))
+      - dedicate console for boot and runtime ([28ad0e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28ad0e0209ac38711d69384da9f706f43e4cc681))
+      - set lower cluster bus qos value ([c6f6202](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6f62027afb2e888b0c5f1eccc42c23bab0885ef))
+
+    - **ZynqMP**
+
+      - add DTB console to platform.mk ([09a02ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09a02ce0bd37585a85f5b3e7f8dd6d7dc82e5f14))
+      - dedicate console for boot and runtime ([4557ab6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4557ab69fe371137d44f8a0ee6bb2129886ab6cd))
+      - enable ENABLE_LTO flag ([19d8756](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19d875677e368e96ca0e96ec59e0c60a092114b4))
+      - move zynqmp platform to xlat tables v2 ([fdda980](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdda980af4b8c8d59374785681a153afda8f71e2))
+
+  - **AMD**
+
+    - populate handoff from TL ([1fbe81f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1fbe81febd4fc69813188ceefb4cbe95a3410ed9))
+
+    - **Versal Gen 2**
+
+      - add dtb & runtime console ([1196474](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11964742d6557c314b6106a8630a3317666c708f))
+      - add dummy implementation for SCMI PD ([095a20a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/095a20a70ce55a08752214fc9eb46bffe4a44a21))
+      - add support for AMD Versal Gen 2 platform ([c97857d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c97857dba2588ce44dd1d9907797f9f4e952fea7))
+      - implement USB_SET_STATE dummy IOCTL ([282bce1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/282bce19bbdb3a95a5365a0385aecfbfa4293ae6))
+      - support dynamic XLAT tables ([9aa71f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9aa71f48bcf98c047e920a8c671b8f5c58b57b74))
+
+- **Bootloader Images**
+
+  - add plat handler for image loading ([a03dafe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a03dafe5164fd3ec81915c49f4e50f0f927726ea))
+
+  - **BL32**
+
+    - setup GPT in BL31 in RESET_TO_BL31 boot flow ([1547e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1547e5e66675ec11bf6dc5958d2d5cff1948cd1f))
+
+- **Services**
+
+  - **RME**
+
+    - **RMMD**
+
+      - el3 token sign during attestation ([6a88ec8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a88ec8b300ca88ba7b6ba8d9626b66a7ee87116))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - support simd context management upon world switch ([59bdcc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bdcc58c3948cd24428c0aef7c478128b2a0bde))
+
+    - **SPM MM**
+
+      - switch to simd_ctx_save/restore APIs ([e6e3486](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6e348689a4b25089145abb798fc2b2aabf6f90b))
+
+  - **Secure Payload Dispatcher**
+
+    - **ProvenCore**
+
+      - switch to simd_ctx_save/restore apis ([a9b64ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a9b64ed969edffe020e2096b5006b27373218ff6))
+
+    - **Trusty**
+
+      - switch to simd_ctx_save/restore apis ([7461025](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74610259856a1df5ca7b9516e74478bb16490a95))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for arcadia cpu ([8fa5460](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fa54607088314aa8e3db1da5649276f2544c75a))
+    - add support for cortex-a720ae ([8118078](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8118078b71583e01a486da01f1bf369b4fde3c59))
+    - add sysreg_bitfield_insert_from_gpr macro ([ad8b514](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad8b51418e3c9e19ddc957424ab19386711ba7ee))
+
+  - **EL3 Runtime**
+
+    - **Context Management**
+      - context switch MDCR_EL3 register ([123002f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/123002f9171384d976d95935b7f566740d69cc68))
+      - introduce EL3/root context ([40e5f7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40e5f7a58f906beef74587a06f7fc35efe20537d))
+      - add Root-Context documentation([0f3cd51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f3cd5150c8f530bb96b84b0ae8129f749835ba3))
+      - enhance the cpu_context memory report ([781e1a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/781e1a44e0cdbd1fd8bbd978a60dcc947eecf29e))
+      - move mpam registers into el2 context ([7d930c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d930c7e599de10bf2418cc93a176122211e7bbb))
+      - convert el1-ctx assembly offset entries to c structure ([42e35d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42e35d2f8c0ec3b931a0da90cb0111369aecea1f))
+      - add explicit context entries for ERRATA_SPECULATIVE_AT ([59b7c0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59b7c0a03fa8adfc9272f959bd8b4228ddd2607a))
+      - remove el1 context when SPMD_SPM_AT_SEL2=1 ([a0674ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0674ab08192e2175afe919f929c9985adc32174))
+      - support for asymmetric feature among cores ([2f41c9a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f41c9a7be46b148d557d3d933547c6e9ad1fd40))
+      - asymmetric feature support for trbe ([721249b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/721249b0c0cce9fbe60175af6ee895e2bb7a6d10))
+      - handle asymmetry for FEAT_TCR2 ([f4303d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4303d05ead1026ce5f97f83558f15159e7d6476))
+      - handle asymmetry for SPE feature ([188f8c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/188f8c4b6040a35adce6f6c15670f2af436df0c3))
+      - test integrity of el1_ctx registers ([7623e08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7623e085cb5396054b72f1ea3f02e8c7a34568b5))
+      - keep actlr_el2 value in the init context ([0aa3284](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0aa3284a45ccf4405cda0bb76f6b16a33e87f222))
+
+    - **SIMD**
+
+      - add data struct for simd ctxt management ([841533d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/841533dd5345dfd7ab78effe1544dc72b6ec840d))
+      - add routines to save, restore sve state ([6d5319a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d5319afecf62f931fe03c12f2dbc398e959c7f0))
+      - add rules to rationalize simd ctxt mgmt ([3524d07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3524d0742e6dd4e8ed9e7a11d8268a9ea2f42c6a))
+      - add sve state to simd ctxt struct ([4242262](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42422622f924b0cf636864e045e38110e97ac126))
+      - introduce simd context helper APIs ([308ebfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/308ebfa18859c89c8b630c1c130e7002095e875f))
+
+  - **GPT**
+
+    - change the default max GPT block size to 512MB ([01faa99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01faa994ceb2635a175f1d299d3b2cd7afd036c0))
+    - add support for large GPT mappings ([ec0088b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec0088bbab9335c5273e57a84b81adf2201a51db))
+    - configure memory size protected by bitlock ([d766084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d766084fc48ed83890c63a7ef773b8fff9e4ea86))
+
+  - **C Standard Library**
+
+    - avoid CWE-190 for GENMASK macros ([1f0b6e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f0b6e756a6d1894f7ec8423fac18671b55c51af))
+    - fix MISRA 12.2 violations for BIT32 and BIT64 macros ([0605b7e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0605b7e8af4980d4e26afc6720dcbf2644633c53))
+
+  - **PSA**
+
+    - introduce generic library for CCA attestation ([98d36e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/98d36e5b02f859866da6782a8ad73b0d26d781e8))
+
+  - **Firmware Handoff**
+
+    - fix register convention r1/x1 value on transfer list ([7475815](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7475815f4b3697f6c61868e4ae6680baee8b93e2))
+    - make tl generation flexible ([2329e22](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2329e22b8bec6fdbb1b5531f3d29569519782a63))
+
+- **Drivers**
+
+  - **Generic Clock**
+
+    - add set_parent callback ([a2c6016](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2c6016f927e4b9a23499005c63f3e46f48ff8a2))
+    - add set_rate callback ([19f9e2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19f9e2e657918d023c9836f8330a967e97a45d7e))
+
+  - **NXP**
+
+    - add clock skeleton for s32cc ([3a580e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a580e9e472a5506da82227e809e0bd472dea1b1))
+    - add Linflex flush callback ([95ac568](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95ac568b6137ee8d3a53d3ec911a7116c90e8d5d))
+
+    - **Clock**
+
+      - add A53 clock objects ([44e2130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44e2130ab9948530cd5eb3fbd1d6d8ead6336845))
+      - add ARM PLL enablement ([b5101c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5101c452e3fefdf4fe13d944372e5ad5d2ea5c4))
+      - add ARM PLL ODIV enablement ([84e8208](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84e82085a1d59624ab7dc14256a152d6d7dd15f2))
+      - add CGM0 instance ([9dbca85](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9dbca85ddf0c9a7c64e4207b74c25a09fd923aba))
+      - add clock objects for ARM DFS ([44ae54a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44ae54af5cadb499cb72cc0edd71711d7a2d019e))
+      - add clock objects for ARM PLL ([a8be748](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8be748a2821355734f603342b2d2cf7105f6a30))
+      - add dependencies for the XBAR clock ([5692f88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5692f881f5064f612719a4f6e7aa3a4abb827439))
+      - add DFS module enablement ([4cd04c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4cd04c50eb4de7dfd65f8811331f0ed3f9f4037c))
+      - add FXOSC clock enablement ([8ab3435](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ab34357497b454b2f5e505d06ce9437da7772e4))
+      - add get_parent callback ([96e069c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96e069cb8ec72b6ac3cac0e7708749cb3fe13abb))
+      - add MC_CGM clock objects ([3fa91a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3fa91a94501ed13587132f6e2aec66a6c054c61e))
+      - add MC_ME utilities ([b8c68ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8c68ad799523229ed7c0a9d025b22f74ffe9eed))
+      - add minimal set of S32CC clock ids ([086ee20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/086ee20fe7ccb9dcbf6e9ee1ce529ae98e6cf977))
+      - add objects needed for DDR clock ([4a2ca71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a2ca718571b3b46cd091cac50c83e9f76c5927b))
+      - add oscillator clock objects ([7c36209](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c36209b29da152cc5e98b6a141fe85d78fca84b))
+      - add partition reset utilities ([11a7c54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11a7c54072f651512948446e432421ba7ee57469))
+      - add partitions objects ([af3020e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af3020e2ae86b71a87d936bb5e7181393874d708))
+      - add PERIPH PLL enablement ([8653352](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8653352ad72e0f95dfd44f2ef9d1b2406dd8dca5))
+      - add set_parent callback ([12e7a2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12e7a2cd2f8f535dfd63834ce78e3fc248ff39f2))
+      - enable the A53 clock ([7004f67](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7004f6782e0c9c7c5875b294af049cd022695cbb))
+      - enable the DDR clock ([8a4f840](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a4f840b1e13b0187b373e014ea314c3dabb122d))
+      - enable the XBAR clock ([b8ad880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8ad8800b2b13d40a6ea1e997e6feb573744665b))
+      - enable UART clock ([e4462da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4462dae81d0674eaf07ad8fa61b25b28a209d0b))
+      - implement set_rate for oscillators ([d937351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d9373519873b11cf7d9cad57742272c80d8967e7))
+      - refactor clock enablement ([5300040](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5300040bfd0acf0e839a9828a1a5341afc936e36))
+      - set parent for ARM PLL and MC_CGM muxes ([83af450](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83af45042debcaf76f2f898984f1b74dedc477e1))
+      - set rate for clock fixed divider ([65739db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65739db28bf0c0d5d4daa8735a2935681f835634))
+      - set rate for clock muxes ([64e0c22](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64e0c2260fa385bdf91d7e3471e10ab251c96644))
+      - set rate for PLL divider objects ([de950ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de950ef04f2bf71924d7ac65e86cfc0cfd97aae3))
+      - set rate for PLL objects ([7ad4e23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ad4e2312f58606ee74ac7c655a655bd85148582))
+      - setup the DDR PLL ([18c2b13](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18c2b137f84fed5929ee5f21cbec9260670814a2))
+
+  - **ST**
+
+    - **Clock**
+
+      - add function to restore generic timer rate ([bfe8a12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfe8a12eea3d51c07570cce65ea7a290db0ab9ce))
+      - add STM32MP2 clock driver ([615f31f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/615f31fe40e5ebf9ecef81eb01abbe52984e093a))
+      - don't gate/ungate an oscillator if it is not wired ([f2aebab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2aebab8591ef9370159fc9ddf976599bdef6349))
+      - update with new bindings ([ae1e503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae1e503763c8bc52eba1a38e320539d61ebe2043))
+      - use early traces ([1a25db1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a25db196d8fb4da379ecea43d0d004470806ee6))
+
+    - **DDR**
+
+      - add STM32MP2 driver ([79629b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79629b1a79bd1ee254077d4e76fea05ba73b9bab))
+
+    - **GPIO**
+
+      - add set GPIO config API ([bfa5f61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfa5f61b579f9eaeead1278efc5997ddd4b5543a))
+
+    - **ST PMIC**
+
+      - add STPMIC2 driver ([817f42f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/817f42f07ede5ef55dab857cde4e9601e349ad75))
+
+    - **Regulator**
+
+      - add enable ramp-delay ([6897ae8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6897ae8d0f4bba1b147f572306782b1aa6b18666))
+      - support regulator_set_voltage for fixed regulator ([156ed97](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/156ed9724f95643dd749b5ed00a7a4b92bab1c71))
+
+    - **Reset**
+
+      - add stm32mp2_reset driver ([f829d7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f829d7df7e261fb8f68e21dbceab8c77ce65aedd))
+      - add system reset management ([d91d10a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d91d10ab39b29339f1c98d95745ba98476fd7e46))
+
+- **Miscellaneous**
+
+  - **DT Bindings**
+
+    - add missing SPIx bus clocks ([c6d50c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6d50c9f933a0e11c419848d30ff018d404c9a42))
+    - describe ST GPIO banks and config ([deb9c86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/deb9c864eac86b4c7a57ec5bf90d301f7f741bd0))
+    - introduce Dualroot CoT DTB ([703df3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/703df3a3ef4aafe30a3522b80ec305a9833f732d))
+    - new RCC DT bindings ([52b253b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52b253bfa2b1788d30339f75cfe39bce387496f3))
+
+  - **FDT Wrappers**
+
+    - add function to read uint64 with default value ([bc8dfca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc8dfca64d07185304a5acfe87a039c8a6649a4c))
+
+  - **FDTs**
+
+    - add DDR4 files for STM32MP2 ([178aef6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/178aef6989395f956b0e149b2b33cdfc0ac2e854))
+
+    - **STM32MP1**
+
+      - move RNG1 to CSI to improve random generation ([d594239](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d594239d4ebf2d44521bc30ec4b59b23f08c5a36))
+      - new RCC DT bindings for STM32MP1 ([4391e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4391e5edea930810e68d087ddeb02d06886d891d))
+      - remove PLL1 settings ([66d7c8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66d7c8bf8ef12f3424fc6da214f9fc65d4cf82b5))
+      - remove RTC clock configuration ([703a581](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/703a581e2522bffe21b421c98994dc02aed2934c))
+
+    - **STM32MP2**
+
+      - add BL31 info in fw-config ([a370c85](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a370c856f1f7655384f8e06f7fd84ded63838c02))
+      - add clock tree for STM32MP257F-EV1 ([293a4f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/293a4f3defe95eddaccd671783e4ff855f1d6f8b))
+      - add fw-config file ([513b5cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/513b5cc83add907f2faa8587e1d24195294c03a5))
+      - add fw-config files for STM32MP257F-EV1 ([83f571e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83f571edb49e35855fa1ab277b3788354d6e707b))
+      - add I2C7 pin muxing ([0a08208](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a0820885d341cc26620c37f6c10ca478955d11f))
+      - add io_policies ([53e8982](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53e89824aa2b4107a583150d1b14b855f25cd63c))
+      - add memory node ([e34839b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e34839b9a275ec9d8487875fc8ef1949a1c41665))
+      - add SD-card and eMMC support on STM32MP257F-EV1 ([1dafb40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1dafb409ba94b3b5c8caba08f691c099e5a7433d))
+      - add sdmmc nodes in SoC DT file ([3879761](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3879761fc206d8b3c04f0fb48d811efc267c025f))
+      - add sdmmc pins definition ([6a85f67](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a85f6710fb03474d3724667e806ab7deff84814))
+      - add UART and I2C nodes for STM32MP2 ([c7cfe27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7cfe27a2412cceef6e1e217798d2f3fc43abded))
+      - describe stpmic2 power supplies ([e974670](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e97467068a2defaea92ec6acaf76b9f416de02a1))
+      - remove pins-are-numbered ([a1a50ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1a50ef1e2f7c5aac89c65b8a7bc67b1f502f21d))
+      - update STM32MP257F-EV1 DT ([f0d6dcb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0d6dcb2bf5e3d382c908a28d1dc670b4914d366))
+
+      - **STM32MP25**
+
+        - add DDR power supplies ([7323c7f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7323c7f9a30391f14dca7ae0627e1a3ce32b3515))
+        - add DDRCTRL and DDRPHY settings in DDR node ([56ac99a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56ac99a04cac9f29e75153c6bf84e37d2f746f0b))
+
+- **Documentation**
+
+  - add DPE to RSE design doc ([e4582e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4582e424799c6072e03d1c6244109eb069ac4bd))
+  - add RMM option in build-options.rst ([1b7f51e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b7f51ea1662810dea4112a543f2309fe44fdca6))
+  - add RSE provided mboot backends to the threat model ([3849d27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3849d272e3b1317ad660df37f1501cb11827e600))
+  - add STM32MP2 docs links ([21b6260](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21b6260ec8d83fc9dbbfca22ef3addcf2018da9f))
+  - update mboot threat model ([07c2d18](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07c2d18f4ef6cd1ce61326e0e85d93abe8f2f4ed))
+
+- **Build System**
+
+  - add ability to define platform specific defaults ([1b2fb6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b2fb6adb53de652d3fe69984731a62da122e0da))
+  - add ctags recipes for indexing assembly files ([54b773e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54b773e18336b2b01b52686799192808b5aa2751))
+
+- **Tools**
+
+  - **Transfer List Compiler**
+
+    - add command gen-header ([9b05c37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b05c3739c44418f47c2b50980fe24651a1eed1f))
+    - add host tool for static TL generation ([6ac31f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ac31f3e76021fed1951d8b62105e6708123f8e3))
+    - add support for tox ([38487c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38487c7fd3f337298ceb60657a6bca5f11816b56))
+    - add creating transfer lists from yaml files ([3112099](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/311209934e78b1d7005ae48c95b0d45c08c1c728))
+    - add option to input attr as string of flag names ([4dcbba9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4dcbba98cee2260e4c4f680f6a7fda5a98fdc7d5))
+    - add option to input text instead of tag id number ([792e8e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/792e8e896f81fff3e0d75dca5f633903fa18f55e))
+
+  - **Chain of Trust device tree to C source file**
+
+    - standalone CoT dt2c tool ([4274d6f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4274d6f885f9df1845d5a6a0b4145cd2f289f4bb))
+    - fix various breakages ([73f7b7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/73f7b7ddbe9c86520c47a9ceb9dc95f224aa0bc6))
+    - use processed Device Tree source file as input ([e19977d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e19977d664027bb16324b1b5e1aaa0ca097e637b))
+    - update documentation for cot-dt2c ([b95f398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b95f398ebd58785f29b96d94d14aec1301f42355))
+
+
 ## [2.11.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.10.0..refs/tags/v2.11.0) (2024-05-17)
 
 ### ⚠ BREAKING CHANGES
@@ -5560,6 +6594,7 @@
       - bump BL2 stack size ([d22f1d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d22f1d358731f0f55f2f392fa587f0fa8d315aa5))
       - provide boot files via semihosting ([749d0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/749d0fa80d1c7ca30b4092a381a06deeeaf1747f))
       - OP-TEE SP manifest per latest SPMC changes ([b7bc51a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7bc51a7a747bf40d219b2041e5b3ce56737a71b))
+      - mock support for CCA NV ctr ([7423e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7423e5e893179d37061a67f8eafda24e649a79ea))
 
     - **FVP-R**
 
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
index 266b82a..6a76ada 100644
--- a/docs/components/context-management-library.rst
+++ b/docs/components/context-management-library.rst
@@ -244,25 +244,22 @@
 	typedef struct cpu_context {
 	gp_regs_t gpregs_ctx;
 	el3_state_t el3state_ctx;
-	el1_sysregs_t el1_sysregs_ctx;
-
-	#if CTX_INCLUDE_EL2_REGS
-	el2_sysregs_t el2_sysregs_ctx;
-	#endif
-
-	#if CTX_INCLUDE_FPREGS
-	fp_regs_t fpregs_ctx;
-	#endif
 
 	cve_2018_3639_t cve_2018_3639_ctx;
+
+	#if ERRATA_SPECULATIVE_AT
+	errata_speculative_at_t errata_speculative_at_ctx;
+	#endif
+
 	#if CTX_INCLUDE_PAUTH_REGS
 	pauth_t pauth_ctx;
 	#endif
 
-	#if CTX_INCLUDE_MPAM_REGS
-	mpam_t	mpam_ctx;
+	#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+	el2_sysregs_t el2_sysregs_ctx;
+	#else
+	el1_sysregs_t el1_sysregs_ctx;
 	#endif
-
 	} cpu_context_t;
 
 Context Memory Allocation
@@ -509,6 +506,55 @@
 identical values across all cores for the individual Non-secure, Secure, and
 Realm worlds.
 
+Root-Context (EL3-Execution-Context)
+====================================
+
+EL3/Root Context is the execution environment while the CPU is running at EL3.
+
+Previously, while the CPU is in execution at EL3, the system registers persist
+with the values of the incoming world. This implies that if the CPU is entering
+EL3 from NS world, the EL1 and EL2 system registers which might be modified in
+lower exception levels NS(EL2/EL1) will carry forward those values to EL3.
+Further the EL3 registers also hold on to the values configured for Non-secure
+world, written during the previous ERET from EL3 to NS(EL2/EL1).
+Same policy is followed with respect to other worlds (Secure/Realm) depending on
+the system configuration.
+
+The firmware at EL3 has traditionally operated within the context of the incoming
+world (Secure/Non-Secure/Realm). This becomes problematic in scenarios where the
+EL3/Root world must explicitly use architectural features that depend on system
+registers configured for lower exception levels.
+A good example of this is the PAuth regs. The Root world would need to program
+its own PAuth Keys while executing in EL3 and this needs to be restored in entry
+to EL3 from any world.
+Therefore, Root world should maintain its own distinct settings to access
+features for its own execution at EL3.
+
+Register values which are currently known to be of importance during EL3 execution,
+is referred to as the EL3/Root context.
+This includes ( MDCR_EL3.SDD, SCR_EL3.{EA, SIF}, PMCR_EL0.DP, PSTATE.DIT)
+EL3 Context ensures, CPU executes under fixed EL3 system register settings
+which is not affected by settings of other worlds.
+
+Root Context needs to be setup as early as possible before we try and access/modify
+architectural features at EL3. Its a simple restore operation ``setup_el3_execution_context``
+that overwrites the selected bits listed above. EL3 never changes its mind about
+what those values should be, sets it as required for EL3. Henceforth, a Root
+context save operation is not required.
+
+The figure below illustrates the same with NS-world as a reference while entering
+EL3.
+
+|Root Context Sequence|
+
+.. code:: c
+
+	# EL3/Root_Context routine
+	.macro setup_el3_execution_context
+
+EL3 execution context needs to setup at both boot time (cold and warm boot)
+entrypaths and at all the possible exception handlers routing to EL3 at runtime.
+
 *Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
 
 .. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png
@@ -516,6 +562,7 @@
 .. |CPU Data Structure| image:: ../resources/diagrams/percpu-data-struct.png
 .. |Context Init ColdBoot| image:: ../resources/diagrams/context_init_coldboot.png
 .. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png
+.. |Root Context Sequence| image:: ../resources/diagrams/root_context_sequence.png
 .. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states
 .. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states
 .. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 03703bc..79e1d2c 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,7 +52,7 @@
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.3 version of Boot Interface ABI and RMM-EL3
+This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
 services specification and the 0.3 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
@@ -259,6 +259,8 @@
    0xC40001B1,``RMM_GTSI_UNDELEGATE``
    0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
    0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
+   0xC40001B4,``RMM_EL3_FEATURES``
+   0xC40001B5,``RMM_EL3_TOKEN_SIGN``
 
 RMM_RMI_REQ_COMPLETE command
 ============================
@@ -505,6 +507,170 @@
    ``E_RMM_UNK``,An unknown error occurred whilst processing the command
    ``E_RMM_OK``,No errors detected
 
+RMM_EL3_FEATURES command
+========================
+
+This command provides a mechanism to discover features and ABIs supported by the
+RMM-EL3 interface, for a given version. This command is helpful when there are
+platform specific optional RMM-EL3 interfaces and features exposed by vendor
+specific EL3 firmware, and a generic RMM that can modify its behavior based on
+discovery of EL3 features.
+
+The features can be discovered by specifying the feature register index that
+has fields defined to indicate presence or absence of features and other
+relevant information. The feature register index is specified in the
+``feat_reg_idx`` parameter. Each feature register is a 64 bit register.
+
+This command is available from v0.4 of the RMM-EL3 interface.
+
+The following is the register definition for feature register index 0 for
+v0.4 of the interface:
+
+RMM-EL3 Feature Resister 0
+--------------------------
+
+.. code-block:: none
+
+    63      32      31      16       15      8       7       1       0
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+    |       |       |       |       |       |       |       |       |
+    |       |       |       |       |       |       |       |       |
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+                                                             ^
+                                                             |
+                                                 RMMD_EL3_TOKEN_SIGN
+
+**Bit Fields:**
+
+- **Bit 0**: `RMMD_EL3_TOKEN_SIGN`
+    - When set to 1, the `RMMD_EL3_TOKEN_SIGN` feature is enabled.
+    - When cleared (0), the feature is disabled.
+- **Bits [1:63]**: Reserved (must be zero)
+
+FID
+---
+
+``0xC40001B4``
+
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   feat_reg_idx,x1,[63:0],UInt64, "Feature register index. For v0.4, a value of 0 is the only
+   acceptable value"
+
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status
+   feat_reg,x1,[63:0],Value,Value of the register as defined above
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_FEATURES
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,``feat_reg_idx`` is out of valid range
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_OK``,No errors detected
+
+RMM_EL3_TOKEN_SIGN command
+==========================
+
+This command is an optional command that can be discovered using the RMM_EL3_FEATURES command.
+This command is used to send requests related to realm attestation token signing requests to EL3.
+The command supports 3 opcodes:
+
+   - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP
+   - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP
+   - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+The above opcodes can be used to send realm attestation token signing requests to EL3 and get their
+response, so that the realm attestation token can be constructed.
+
+This command is useful when the RMM may not have access to the private portion of the realm
+attestation key and needs signing services from EL3 or CCA HES, or other platform specific
+mechanisms to perform signing.
+
+The RMM-EL3 interface for this command is modeled as two separate queues, one for signing requests
+and one for retrieving the signed responses. It is possible that the queue in EL3 is full or EL3 is busy and
+unable to service the RMM requests, in which case the RMM is expected to retry the push operation
+for requests and pop operation for responses.
+
+FID
+---
+
+``0xC40001B5``
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   opcode,x1,[63:0],UInt64,"
+   Opcode that is one of:
+
+    - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP: 0x1 -
+      Opcode to push a token signing request to EL3 using struct el3_token_sign_request as described above
+    - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP: 0x2 -
+      Opcode to pull a token signing response from EL3 using struct el3_token_sign_response as described above
+    - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP: 0x3 -
+      Opcode to get the realm attestation public key
+
+   "
+   buf_pa,x2,[63:0],Address,"PA where the request structure is stored for the opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, the response structure needs to be populated for the opcode RMM_EL3_TOKEN_SIGN_PULL_RESP_OP, or where the public key must be populated for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP. The PA must belong to the RMM-EL3 shared buffer"
+   buf_size,x3,[63:0],Size,Size in bytes of the input buffer in ``buf_pa``. ``buf_pa + buf_size`` must lie within the shared buffer
+   ecc_curve,x4,[63:0],Enum,Type of the elliptic curve to which the requested attestation key belongs to. See :ref:`ecc_curves`. This parameter is valid on for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status. Valid for all opcodes listed in input values
+   retval1,x1,[63:0],Value, "If opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP, then returns length of
+   public key returned. Otherwise, reserved"
+
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_TOKEN_SIGN
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,"if opcode is invalid or buffer address and length passed to the EL3 are not in valid range
+   corresponding to the RMM-EL3 shared buffer, or if the curve used for opcode
+   RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP is not the ECC P384 curve"
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_AGAIN``,"For opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, if the request is not queued since
+   the EL3 queue is full, or if the response is not ready yet, for other opcodes"
+   ``E_RMM_OK``,No errors detected
+
+
 RMM-EL3 world switch register save restore convention
 _____________________________________________________
 
@@ -654,3 +820,55 @@
 | flags     |   40   |   uint64_t    | Additional flags (RES0)                |
 +-----------+--------+---------------+----------------------------------------+
 
+.. _el3_token_sign_request_struct:
+
+EL3 Token Sign Request structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation toekn signing request.
+
++-------------+--------+---------------+-----------------------------------------+
+|   Name      | Offset |     Type      |               Description               |
++=============+========+===============+=========================================+
+| sig_alg_id  |   0    |   uint32_t    | Algorithm idenfier for the sign request.|
+|             |        |               | - 0x0: ECC SECP384R1 (ECDSA)            |
+|             |        |               | - Other values reserved                 |
++-------------+--------+---------------+-----------------------------------------+
+| rec_granule |   8    |   uint64_t    | Identifier used by RMM to associate     |
+|             |        |               | a signing request to a realm. Must not  |
+|             |        |               | be interpreted or modified.             |
++-------------+--------+---------------+-----------------------------------------+
+| req_ticket  |   16   |   uint64_t    | Value used by RMM to associate request  |
+|             |        |               | and responses. Must not be interpreted  |
+|             |        |               | or modified.                            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_alg_id |   24   |   uint32_t    | Hash algorithm for data in `hash_buf`   |
+|             |        |               | - 0x1: SHA2-384                         |
+|             |        |               | - All other values reserved.            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_buf    |   32   |   uint8_t[]   | TBS (to-be-signed) Hash of length       |
+|             |        |               | defined by hash algorithm `hash_alg_id` |
++-------------+--------+---------------+-----------------------------------------+
+
+.. _el3_token_sign_response_struct:
+
+EL3 Token Sign Response structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation token signing response.
+
++---------------+--------+---------------+-----------------------------------------+
+|   Name        | Offset |     Type      |               Description               |
++===============+========+===============+=========================================+
+| rec_granule   |   0    |   uint64_t    | Identifier used by RMM to associate     |
+|               |        |               | a signing request to a realm. Must not  |
+|               |        |               | be interpreted or modified.             |
++---------------+--------+---------------+-----------------------------------------+
+| req_ticket    |   8    |   uint64_t    | Value used by RMM to associate request  |
+|               |        |               | and responses. Must not be interpreted  |
+|               |        |               | or modified.                            |
++---------------+--------+---------------+-----------------------------------------+
+| sig_len       |   16   |   uint16_t    | Length of the `signature_buf` field     |
++---------------+--------+---------------+-----------------------------------------+
+| signature_buf |   18   |   uint8_t[]   | Signature                               |
++---------------+--------+---------------+-----------------------------------------+
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 220c3ce..a181204 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -110,7 +110,7 @@
 - Only Arm's FVP platform is supported to use with the TF-A reference software
   stack.
 - When ``SPMD_SPM_AT_SEL2=1``, the reference software stack assumes enablement
-  of FEAT_PAuth, FEAT_BTI and FEAT_MTE architecture extensions.
+  of FEAT_PAuth, FEAT_BTI and FEAT_MTE2 architecture extensions.
 - ``(*) CTX_INCLUDE_EL2_REGS``, this flag is |TF-A| internal and informational
   in this table. When set, it provides the generic support for saving/restoring
   EL2 registers required when S-EL2 firmware is present.
diff --git a/docs/conf.py b/docs/conf.py
index 3f9655b..3a7264f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,8 +14,8 @@
 
 project = "Trusted Firmware-A"
 author = "Trusted Firmware-A contributors"
-version = "2.11.0"
-release = "2.11.0"
+version = "2.12.0"
+release = "2.12.0"
 
 # -- General configuration ---------------------------------------------------
 
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 6dc2245..9c04a8b 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -232,22 +232,42 @@
 .. code:: c
 
     void (*init)(void);
-    int (*verify_signature)(void *data_ptr, unsigned int data_len,
+    int (*verify_signature)(
+                            /* Data to verify. */
+                            void *data_ptr, unsigned int data_len,
+                            /* Bit string of the signature in DER format. */
                             void *sig_ptr, unsigned int sig_len,
+                            /* ASN1 SignatureAlgorithm struct. */
                             void *sig_alg, unsigned int sig_alg_len,
+                            /* ASN1 SubjectPublicKeyInfo struct. */
                             void *pk_ptr, unsigned int pk_len);
-    int (*calc_hash)(enum crypto_md_algo alg, void *data_ptr,
-                     unsigned int data_len,
-                     unsigned char output[CRYPTO_MD_MAX_SIZE])
-    int (*verify_hash)(void *data_ptr, unsigned int data_len,
-                       void *digest_info_ptr, unsigned int digest_info_len);
-    int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
-                        size_t len, const void *key, unsigned int key_len,
-                        unsigned int key_flags, const void *iv,
-                        unsigned int iv_len, const void *tag,
-                        unsigned int tag_len);
+    int (*calc_hash)(
+                            /* SHA256, SHA384 and SHA512 can be used. */
+                            enum crypto_md_algo alg
+                            /* Data to hash. */
+                            void *data_ptr, unsigned int data_len,
+                            /* Buffer to store the output. */
+                            unsigned char output[CRYPTO_MD_MAX_SIZE]);
+    int (*verify_hash)(
+                            /* Data to verify. */
+                            void *data_ptr, unsigned int data_len,
+                            /* ASN1 DigestInfo struct. */
+                            void *digest_info_ptr, unsigned int digest_info_len);
+    int (*auth_decrypt)(
+                            /* Currently AES-GCM is the only supported alg. */
+                            enum crypto_dec_algo dec_algo,
+                            /* Data to decrypt. */
+                            void *data_ptr, size_t len,
+                            /* Decryption key. */
+                            const void *key, unsigned int key_len,
+                            unsigned int key_flags,
+                            /* Initialization vector. */
+                            const void *iv, unsigned int iv_len,
+                            /* Authentication tag. */
+                            const void *tag, unsigned int tag_len);
 
-These functions are registered in the CM using the macro:
+The above functions return values from the enum ``crypto_ret_value``.
+The functions are registered in the CM using the macro:
 
 .. code:: c
 
@@ -262,10 +282,21 @@
 ``_name`` must be a string containing the name of the CL. This name is used for
 debugging purposes.
 
-Crypto module provides a function ``_calc_hash`` to calculate and
-return the hash of the given data using the provided hash algorithm.
-This function is mainly used in the ``MEASURED_BOOT`` and ``DRTM_SUPPORT``
-features to calculate the hashes of various images/data.
+The ``_init`` function is used to perform any initialization required for
+the specific CM and CL.
+
+The ``_verify_signature`` function is used to verify certificates,
+and ``_verify_hash`` is used to verify raw images.
+
+The ``_calc_hash`` function is mainly used in the ``MEASURED_BOOT``
+and ``DRTM_SUPPORT`` features to calculate the hashes of various images/data.
+
+The ``_auth_decrypt`` function uses an authentication tag to perform
+authenticated decryption, providing guarantees on the authenticity
+of encrypted data. This function is used when the optional encrypted
+firmware feature is enabled, that is when ``ENCRYPT_BL31`` or
+``ENCRYPT_BL32`` are set to ``1`` and ``DECRYPTION_SUPPORT`` is
+set to ``aes_gcm``.
 
 Optionally, a platform function can be provided to convert public key
 (_convert_pk). It is only used if the platform saves a hash of the ROTPK.
@@ -970,30 +1001,44 @@
 The cryptographic library
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The cryptographic module relies on a library to perform the required operations,
-i.e. verify a hash or a digital signature. Arm platforms will use a library
-based on mbed TLS, which can be found in
-``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
-authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-below functions:
+The cryptographic module relies on a library to perform essential operations
+such as verifying a hash or a digital signature.
+Arm platforms use a library based on mbedTLS located at
+``drivers/auth/mbedtls/mbedtls_crypto.c``.
+Additionally, an experimental alternative library based on PSA Crypto
+is available at ``drivers/auth/mbedtls/mbedtls_psa_crypto.c``. In future,
+``mbedtls_psa_crypto.c`` will replace ``mbedtls_crypto.c`` as the default Arm
+CM. Both libraries are registered in the authentication framework using
+the macro ``REGISTER_CRYPTO_LIB()``. These libraries implement the following
+exported functions, their implementations are compared side-by-side below:
 
-.. code:: c
+.. list-table:: Comparison of exported CM function implementations
+   :widths: 20 40 40
+   :header-rows: 1
 
-    void init(void);
-    int verify_signature(void *data_ptr, unsigned int data_len,
-                         void *sig_ptr, unsigned int sig_len,
-                         void *sig_alg, unsigned int sig_alg_len,
-                         void *pk_ptr, unsigned int pk_len);
-    int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
-                             unsigned int data_len,
-                             unsigned char output[CRYPTO_MD_MAX_SIZE])
-    int verify_hash(void *data_ptr, unsigned int data_len,
-                    void *digest_info_ptr, unsigned int digest_info_len);
-    int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
-                     size_t len, const void *key, unsigned int key_len,
-                     unsigned int key_flags, const void *iv,
-                     unsigned int iv_len, const void *tag,
-                     unsigned int tag_len)
+   * - CM function
+     - ``mbedtls_crypto.c``
+     - ``mbedtls_psa_crypto.c``
+   * - ``init``
+     - Initialize the heap for mbedTLS.
+     - Initialize the heap for mbedTLS and call ``psa_crypto_init``.
+   * - ``verify_signature``
+     - Use mbedTLS to parse the ASN1 inputs, and then use the mbedTLS pk module to verify the signature.
+     - Use mbedTLS to parse the ASN1 inputs, use the mbedTLS pk module to parse the key,
+       import it into the PSA key system and then use ``psa_verify_message`` to verify the signature.
+   * - ``calc_hash``
+     - Use the ``mbedtls_md`` API to calculate the hash of the given data.
+     - Use ``psa_hash_compute`` to calculate the hash of the given data.
+   * - ``verify_hash``
+     - Use the ``mbedtls_md`` API to calculate the hash of the given data,
+       and then compare it against the data which is to be verified.
+     - Call ``psa_hash_compare``, which both calculates the hash of the given data and
+       compares this hash against the data to be verified.
+   * - ``auth_decrypt``
+     - Use the ``mbedtls_gcm`` API to decrypt the data, and then verify the returned
+       tag by comparing it to the inputted tag.
+     - Load the key into the PSA key store, and then use ``psa_aead_verify`` to
+       decrypt and verify the tag.
 
 The mbedTLS library algorithm support is configured by both the
 ``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables.
@@ -1017,6 +1062,6 @@
 
 --------------
 
-*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index fda43dc..369ec6f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -33,6 +33,11 @@
    This build option should be set to 1 if the target platform contains at
    least 1 CPU that requires this mitigation. Defaults to 1.
 
+-  ``WORKAROUND_CVE_2024_5660``: Enables mitigation for `CVE-2024-5660`.
+   The fix is to disable hardware page aggregation by setting CPUECTLR_EL1[46]
+   in EL3 FW. This build option should be set to 1 if the target platform contains
+   at least 1 CPU that requires this mitigation. Defaults to 1.
+
 .. _arm_cpu_macros_errata_workarounds:
 
 CPU Errata Workarounds
@@ -843,6 +848,9 @@
 - ``ERRATA_X4_2897503``: This applies errata 2897503 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
+- ``ERRATA_X4_2923985``: This applies errata 2923985 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
 - ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index caf367b..1cc1ba6 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -54,16 +54,34 @@
       On Juno board, the default value corresponds to an ECDSA-SECP256R1 public
       key hash, whose private part is not currently available.
 
-   -  ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in
-      ``plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin``. Enforce
-      generation of the new hash if ``ROT_KEY`` is specified.
+   -  ``ARM_ROTPK_LOCATION=devel_rsa``: the ROTPK is a hash of the
+      RSA public key corresponding to the private key specified by
+      ``ROT_KEY``. If ``ROT_KEY`` is not specified, the private key is
+      the development key ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``.
+      There are also 3k and 4k RSA development keys in ``plat/arm/board/common/rotpk/``.
+      The hashing algorithm is selected by ``HASH_ALG``; sha256 is used if
+      ``HASH_ALG`` is not specified.
 
-   -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in
-      ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce
-      generation of the new hash if ``ROT_KEY`` is specified.
+   -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: the ROTPK is a hash of the
+      ECDSA public key corresponding to the private key specified by
+      ``ROT_KEY``. If ``ROT_KEY`` is not specified, the private key is
+      the development key ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem`` by default,
+      a 384 bit key ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem`` also exists,
+      and can be specified by ``ROT_KEY``. The hashing algorithm is selected by ``HASH_ALG``;
+      sha256 is used if ``HASH_ALG`` is not specified.
 
-   -  ``ARM_ROTPK_LOCATION=devel_full_dev_rsa_key``: use the key located in
-      ``plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S``.
+   -  ``ARM_ROTPK_LOCATION=devel_full_dev_rsa_key``: the ROTPK is an unhashed
+      RSA public key corresponding to the private key specified by ``ROT_KEY``.
+      If ``ROT_KEY`` is not specified, the private key is the development key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``. There are also
+      3k and 4k RSA development keys in ``plat/arm/board/common/rotpk/``.
+
+   -  ``ARM_ROTPK_LOCATION=devel_full_dev_ecdsa_key``: the ROTPK is an unhashed
+      RSA public key corresponding to the private key specified by ``ROT_KEY``.
+      If ``ROT_KEY`` is not specified, the private key is the development key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem``, a 384 bit key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem`` also exists,
+      and can be specified by ``ROT_KEY``.
 
    Example of command line using RSA development keys:
 
@@ -119,7 +137,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
 .. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index f10d2e7..f3e094c 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -39,7 +39,8 @@
 
 -  A Root of Trust Public Key (ROTPK), or a hash of it.
 
-   On Arm development platforms, a SHA-256 hash of the ROTPK is stored in the
+   On Arm development platforms, a hash of the ROTPK (hash algorithm selected by
+   the ``HASH_ALG`` build option, with sha256 as default) is stored in the
    trusted root-key storage registers. Alternatively, a development ROTPK might
    be used and its hash embedded into the BL1 and BL2 images (only for
    development purposes).
@@ -330,7 +331,7 @@
 
 --------------
 
-*Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
 .. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
index 9dfe494..005903e 100644
--- a/docs/design_documents/measured_boot.rst
+++ b/docs/design_documents/measured_boot.rst
@@ -91,10 +91,10 @@
    and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
    Log driver implemented in TF-A covers later part.
 
-#. RSE
+#. |RSE|
 
-   It is one of physical backend to extend the measurements. Please refer this
-   document :ref:`Runtime Security Engine (RSE)` for more details.
+   It is one of the physical backends to extend the measurements. Please refer
+   this document :ref:`Runtime Security Engine (RSE)` for more details.
 
 Platform Interface
 ------------------
@@ -121,7 +121,7 @@
       void bl2_plat_mboot_init(void);
 
    Initialise all Measured Boot backends supported by the platform
-   (e.g. Event Log buffer, RSE). As these functions do not return any value,
+   (e.g. Event Log buffer, |RSE|). As these functions do not return any value,
    the platform should deal with error management, such as logging the error
    somewhere, or panicking the system if this is considered a fatal error.
 
@@ -147,8 +147,9 @@
 
      - If it is Event Log backend, then record the measurement in TCG Event Log
        format.
-     - If it is a secure crypto-processor (like RSE), then extend the designated
-       PCR (or slot) with the given measurement.
+     - If it is a secure crypto-processor (like |RSE|), then extend the
+       designated PCR (or store it in secure on-chip memory) with the given
+       measurement.
    - This function must return 0 on success, a signed integer error code
      otherwise.
    - On the Arm FVP port, this function measures the given image and then
@@ -223,7 +224,7 @@
    - This function must return 0 on success, a signed integer error code
      otherwise.
    - In TC2 platform, this function is used to calculate the hash of the given
-     key and forward this hash to RSE alongside the measurement of the image
+     key and forward this hash to |RSE| alongside the measurement of the image
      which the key signs.
 
 --------------
diff --git a/docs/design_documents/rse.rst b/docs/design_documents/rse.rst
index 57467f3..dd110ca 100644
--- a/docs/design_documents/rse.rst
+++ b/docs/design_documents/rse.rst
@@ -138,6 +138,11 @@
   process can be requested from RSE. Furthermore, AP can request RSE to
   increase a non-volatile counter. Please refer to the
   ``RSE key management`` [5]_ document for more details.
+- ``DICE Protection Environment``: Securely store the firmware measurements
+  which were computed during the boot process and the associated metadata. It is
+  also capable of representing the boot measurements in the form of a
+  certificate chain, which is queriable. Please refer to the
+  ``DICE Protection Environment (DPE)`` [8]_ document for more details.
 
 Runtime service API
 ^^^^^^^^^^^^^^^^^^^
@@ -355,9 +360,7 @@
 Build time config options
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
-  implementation whether RSE or TPM (or both) backend based measured boot is
-  enabled.
+- ``MEASURED_BOOT``: Enable measured boot.
 - ``MBOOT_RSE_HASH_ALG``: Determine the hash algorithm to measure the images.
   The default value is sha-256.
 
@@ -432,10 +435,6 @@
 need to go through BL31. The RMM dispatcher module of the BL31 is responsible
 for delivering the calls between the two parties.
 
-.. Note::
-     Currently the connection between the RMM dispatcher and the PSA/RSE layer
-     is not yet implemented. RMM dispatcher just returns hard coded data.
-
 Delegated Attestation API
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 Defined here:
@@ -674,6 +673,63 @@
         ]
     }
 
+RSE based DICE Protection Environment
+-------------------------------------
+
+The ``DICE Protection Environment (DPE)`` [8]_ service makes it possible to
+execute |DICE| commands within an isolated execution environment. It provides
+clients with an interface to send DICE commands, encoded as CBOR objects,
+that act on opaque context handles. The |DPE| service performs |DICE|
+derivations and certification on its internal contexts, without exposing the
+|DICE| secrets (private keys and CDIs) outside of the isolated execution
+environment.
+
+|DPE| API
+^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/dice_protection_environment.h``
+
+.. code-block:: c
+
+    dpe_error_t
+    dpe_derive_context(int      context_handle,
+                       uint32_t cert_id,
+                       bool     retain_parent_context,
+                       bool     allow_new_context_to_derive,
+                       bool     create_certificate,
+                       const DiceInputValues *dice_inputs,
+                       int32_t  target_locality,
+                       bool     return_certificate,
+                       bool     allow_new_context_to_export,
+                       bool     export_cdi,
+                       int     *new_context_handle,
+                       int     *new_parent_context_handle,
+                       uint8_t *new_certificate_buf,
+                       size_t   new_certificate_buf_size,
+                       size_t  *new_certificate_actual_size,
+                       uint8_t *exported_cdi_buf,
+                       size_t   exported_cdi_buf_size,
+                       size_t  *exported_cdi_actual_size);
+
+Build time config options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot.
+- ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+  backend when |RSE| based ``MEASURED_BOOT`` is enabled. The default value is
+  ``0``. When set to ``1`` then measurements and additional metadata collected
+  during the measured boot process are sent to the |DPE| for storage and
+  processing.
+- ``DPE_ALG_ID``: Determine the hash algorithm to measure the images. The
+  default value is sha-256.
+
+Example certificate chain
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``plat/arm/board/tc/tc_dpe.h``
+
 RSE OTP Assets Management
 -------------------------
 
@@ -728,13 +784,14 @@
 References
 ----------
 
-.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/readme.html
-.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_comms.html
-.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
-.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
-.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_key_management.html
+.. [1] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/index.html
+.. [2] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_comms.html
+.. [3] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/measured_boot_integration_guide.html
+.. [4] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/delegated_attestation/delegated_attest_integration_guide.html
+.. [5] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_key_management.html
 .. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
 .. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+.. [8] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/dice_protection_environment/dice_protection_environment.html
 
 --------------
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 203bf0f..58321e7 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -351,6 +351,12 @@
    This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_FPMR``: Numerical value to enable support for Floating Point
+   Mode Register feature, allowing access to the FPMR register. FPMR register
+   controls the behaviors of FP8 instructions. It is an optional architectural
+   feature from v9.2 and upwards. This flag can take value of 0 to 2, to align
+   with the ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
    feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
    Read Trap Register) during EL2 to EL3 context save/restore operations.
@@ -372,6 +378,16 @@
    flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
+- ``ENABLE_FEAT_MOPS``: Numeric value to enable FEAT_MOPS (Standardization
+   of memory operations) when INIT_UNUSED_NS_EL2=1.
+   This feature is mandatory from v8.8 and enabling of FEAT_MOPS does not
+   require any settings from EL3 as the controls are present in EL2 registers
+   (HCRX_EL2.{MSCEn,MCE2} and SCTLR_EL2.MSCEn) and in most configurations
+   we expect EL2 to be present. But in case of INIT_UNUSED_NS_EL2=1 ,
+   EL3 should configure the EL2 registers. This flag
+   can take values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_FEAT_MTE2``: Numeric value to enable Memory Tagging Extension2
    if the platform wants to use this feature and MTE2 is enabled at ELX.
    This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
@@ -455,6 +471,31 @@
    the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
+   (Translation Hardening Extension) at EL2 and below, setting the bit
+   SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
+   registers and context switch them.
+   Its an optional architectural feature and is available from v8.8 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_SCTLR2``: Numeric value to enable support for FEAT_SCTLR2
+   (Extension to SCTLR_ELx) at EL2 and below, setting the bit
+   SCR_EL3.SCTLR2En in EL3 to allow access to SCTLR2_ELx registers and
+   context switch them. This feature is OPTIONAL from Armv8.0 implementations
+   and mandatory in Armv8.9 implementations.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_D128``: Numeric value to enable support for FEAT_D128
+   at EL2 and below, setting the bit SCT_EL3.D128En in EL3 to allow access to
+   128 bit version of system registers like PAR_EL1, TTBR0_EL1, TTBR1_EL1,
+   TTBR0_EL2, TTBR1_EL2, TTBR0_EL12, TTBR1_EL12 , VTTBR_EL2, RCWMASK_EL1, and
+   RCWSMASK_EL1. Its an optional architectural feature and is available from
+   9.3 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
@@ -474,6 +515,11 @@
    The flag is automatically disabled when the target
    architecture is AArch32.
 
+-  ``ENABLE_FEAT_LS64_ACCDATA``: Numeric value to enable access and save and
+   restore the ACCDATA_EL1 system register, at EL2 and below. This flag can
+   take the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power
    Mitigation Mechanism supported by certain Arm cores, which allows the SoC
    firmware to detect and limit high activity events to assist in SoC processor
@@ -678,6 +724,10 @@
    invert this behavior. Lower addresses will be printed at the top and higher
    addresses at the bottom.
 
+-  ``INIT_UNUSED_NS_EL2``: This build flag guards code that disables EL2
+   safely in scenario where NS-EL2 is present but unused. This flag is set to 0
+   by default. Platforms without NS-EL2 in use must enable this flag.
+
 -  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
    used for generating the PKCS keys and subsequent signing of the certificate.
    It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular``
@@ -697,9 +747,9 @@
    +---------------------------+------------------------------------+
    |          ecdsa            |         256 (default), 384         |
    +---------------------------+------------------------------------+
-   |  ecdsa-brainpool-regular  |            unavailable             |
+   |  ecdsa-brainpool-regular  |            256 (default)           |
    +---------------------------+------------------------------------+
-   |  ecdsa-brainpool-twisted  |            unavailable             |
+   |  ecdsa-brainpool-twisted  |            256 (default)           |
    +---------------------------+------------------------------------+
 
 -  ``HASH_ALG``: This build flag enables the user to select the secure hash
@@ -818,6 +868,11 @@
 -  ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI
    OS-initiated mode. This option defaults to 0.
 
+-  ``ARCH_FEATURE_AVAILABILITY``: Boolean flag to enable support for the
+   optional SMCCC_ARCH_FEATURE_AVAILABILITY call. This option implicitly
+   interacts with IMPDEF_SYSREG_TRAP and software emulation. This option
+   defaults to 0.
+
 -  ``ENABLE_FEAT_RAS``: Boolean flag to enable Armv8.2 RAS features. RAS features
    are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
    or later CPUs. This flag can take the values 0 or 1. The default value is 0.
@@ -1318,6 +1373,13 @@
    Management Extension. This flag can take the values 0 to 2, to align with
    the ``ENABLE_FEAT`` mechanism. Default value is 0.
 
+-  ``RMMD_ENABLE_EL3_TOKEN_SIGN``: Numeric value to enable support for singing
+   realm attestation token signing requests in EL3. This flag can take the
+   values 0 and 1. The default value is ``0``. When set to ``1``, this option
+   enables additional RMMD SMCs to push and pop requests for signing to
+   EL3 along with platform hooks that must be implemented to service those
+   requests and responses.
+
 -  ``ENABLE_SME_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
    registers so are enabled together. Using this option without
@@ -1374,6 +1436,10 @@
    interface through BL31 as a SiP SMC function.
    Default is disabled (0).
 
+-  ``HOB_LIST``: Setting this to ``1`` enables support for passing boot
+   information using HOB defined in `Platform Initialization specification`_.
+   This defaults to ``0``.
+
 Firmware update options
 ~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1417,3 +1483,4 @@
 .. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
 .. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/releases/tag/v0.9
 .. _PSA Crypto API specification: https://armmbed.github.io/mbed-crypto/html/
+.. _Platform Initialization specification: https://uefi.org/specs/PI/1.8/index.html
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index 50fff57..54e29dd 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -37,25 +37,8 @@
 Building rendered documentation
 -------------------------------
 
-To install Python dependencies using Poetry:
-
-.. code:: shell
-
-    poetry install
-
-Poetry will create a new virtual environment and install all dependencies listed
-in ``pyproject.toml``. You can get information about this environment, such as
-its location and the Python version, with the command:
-
-.. code:: shell
-
-    poetry env info
-
-If you have already sourced a virtual environment, Poetry will respect this and
-install dependencies there.
-
-Once all dependencies are installed, the documentation can be compiled into
-HTML-formatted pages from the project root directory by running:
+The documentation can be compiled into HTML-formatted pages from the project
+root directory by running:
 
 .. code:: shell
 
@@ -129,7 +112,7 @@
         bash -c 'cd /tf-a &&
             apt-get update && apt-get install -y curl plantuml &&
             curl -sSL https://install.python-poetry.org | python3 - &&
-            ~/.local/bin/poetry install && ~/.local/bin/poetry run make doc'
+            ~/.local/bin/poetry run make doc'
 
 The above command fetches the ``sphinxdoc/sphinx`` container from `docker
 hub`_, launches the container, installs documentation requirements and finally
@@ -138,7 +121,7 @@
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _Sphinx: http://www.sphinx-doc.org/en/master/
 .. _Poetry: https://python-poetry.org/docs/
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index de2da2f..32c2b39 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -28,15 +28,15 @@
 ======================== =====================
 Arm Compiler             6.18
 Arm GNU Compiler         13.3
-Clang/LLVM               11.0.0
-Device Tree Compiler     1.4.7
+Clang/LLVM               18.1.8
+Device Tree Compiler     1.6.1
 GNU make                 3.81
-mbed TLS\ [#f1]_         3.6.1
+mbed TLS\ [#f1]_         3.6.2
 Node.js [#f2]_           16
 OpenSSL                  1.0.0
-Poetry [#f2]_            1.3.2
+Poetry                   1.3.2
 QCBOR\ [#f3]_            1.2
-Sphinx\ [#f2]_           2.4.4
+Sphinx\ [#f2]_           5.3.0
 ======================== =====================
 
 .. [#f1] Required for Trusted Board Boot and Measured Boot.
@@ -103,9 +103,11 @@
 ^^^^^^
 
 Required for managing Python dependencies, this will allow you to reliably
-reproduce a Python environment to build documentation and run analysis tools.
-Most importantly, it ensures your system environment will not be affected by
-dependencies in the Python scripts.
+reproduce a Python environment to build documentation and run some of the
+integrated Python tools. Most importantly, it ensures your system environment
+will not be affected by dependencies in the Python scripts.
+
+For installation instructions, see the `official Poetry documentation`_.
 
 .. _prerequisites_software_and_libraries:
 
@@ -191,3 +193,4 @@
 .. _Arm-DS: https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
 .. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
 .. _TrustedFirmware.org: https://www.trustedfirmware.org/
+.. _official Poetry documentation: https://python-poetry.org/docs/#installation
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 80012e7..23a91cd 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -8,6 +8,8 @@
 .. |COT| replace:: :term:`COT`
 .. |CSS| replace:: :term:`CSS`
 .. |CVE| replace:: :term:`CVE`
+.. |DICE| replace:: :term:`DICE`
+.. |DPE| replace:: :term:`DPE`
 .. |DTB| replace:: :term:`DTB`
 .. |DS-5| replace:: :term:`DS-5`
 .. |DSU| replace:: :term:`DSU`
@@ -21,6 +23,7 @@
 .. |FVP| replace:: :term:`FVP`
 .. |FWU| replace:: :term:`FWU`
 .. |GIC| replace:: :term:`GIC`
+.. |HES| replace:: :term:`HES`
 .. |ISA| replace:: :term:`ISA`
 .. |Linaro| replace:: :term:`Linaro`
 .. |MMU| replace:: :term:`MMU`
@@ -31,12 +34,14 @@
 .. |OEN| replace:: :term:`OEN`
 .. |OP-TEE| replace:: :term:`OP-TEE`
 .. |OTE| replace:: :term:`OTE`
+.. |PCR| replace:: :term:`PCR`
 .. |PDD| replace:: :term:`PDD`
 .. |PAUTH| replace:: :term:`PAUTH`
 .. |PMF| replace:: :term:`PMF`
 .. |PSCI| replace:: :term:`PSCI`
 .. |RAS| replace:: :term:`RAS`
 .. |ROT| replace:: :term:`ROT`
+.. |RSE| replace:: :term:`RSE`
 .. |SCMI| replace:: :term:`SCMI`
 .. |SCP| replace:: :term:`SCP`
 .. |SDEI| replace:: :term:`SDEI`
@@ -55,6 +60,7 @@
 .. |SVE| replace:: :term:`SVE`
 .. |TBB| replace:: :term:`TBB`
 .. |TBBR| replace:: :term:`TBBR`
+.. |TCB| replace:: :term:`TCB`
 .. |TCG| replace:: :term:`TCG`
 .. |TEE| replace:: :term:`TEE`
 .. |TF-A| replace:: :term:`TF-A`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index c02e938..f19897c 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -100,6 +100,9 @@
    GIC
       Generic Interrupt Controller
 
+   HES
+      Arm CCA Hardware Enforced Security
+
    ISA
       Instruction Set Architecture
 
@@ -136,6 +139,9 @@
    OTE
       Open-source Trusted Execution Environment
 
+   PCR
+      Platform Configuration Register
+
    PDD
       Platform Design Document
 
@@ -162,6 +168,9 @@
    ROT
       Root of Trust
 
+   RSE
+      Runtime Security Engine
+
    SCMI
       System Control and Management Interface
 
diff --git a/docs/license.rst b/docs/license.rst
index 9e0298b..e35b9bb 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -110,6 +110,14 @@
    -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/parser.py``
    -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/__init__.py``
 
+-  Some source files originating from the `edk2`_ project.
+   These files are licensed under the BSD-2-Clause. Any contributions to this
+   code must also be made under the terms of BSD-2-Clause.
+   These files are:
+
+   -  ``lib/hob/hob.c``
+   -  ``include/lib/hob/mmram.h``
+   -  ``include/lib/hob/mpinfo.h``
 
 .. _FreeBSD: http://www.freebsd.org
 .. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
@@ -117,3 +125,4 @@
 .. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
 .. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
 .. _pydevicetree: https://pypi.org/project/pydevicetree/
+.. _edk2: https://github.com/tianocore/edk2
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index 43a7d59..9640a24 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -31,8 +31,8 @@
 
 The following source trees and binaries were used:
 
-- `TF-A v2.11-rc0`_
-- `TFTF v2.11-rc0`_
+- `TF-A v2.12-rc0`_
+- `TFTF v2.12-rc0`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
 <Runtime Instrumentation Methodology>`
@@ -73,6 +73,25 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        parallel (v2.12)
+
+    +---------+------+-------------------+------------------+--------------------+
+    | Cluster | Core |     Powerdown     |      Wakeup      |    Cache Flush     |
+    +---------+------+-------------------+------------------+--------------------+
+    |    0    |  0   |  244.52 (-65.43%) | 26.92 (-32.60%)  |   5.54 (-96.70%)   |
+    +---------+------+-------------------+------------------+--------------------+
+    |    0    |  1   | 526.18 (+105.12%) |      416.1       | 138.52 (+2011.59%) |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  0   |       104.34      | 27.02 (-94.62%)  |        5.32        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  1   |       384.98      | 23.06 (-85.40%)  |        4.48        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  2   |  812.44 (+45.94%) |      126.78      |        4.54        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  3   |       986.84      | 77.22 (+176.58%) |       79.76        |
+    +---------+------+-------------------+------------------+--------------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         parallel (v2.11)
 
     +---------+------+-------------------+--------------------+-------------+
@@ -92,23 +111,23 @@
     +---------+------+-------------------+--------------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.10)
+        serial (v2.12)
 
-    +---------+------+-------------------+--------+-------------+
-    | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  0   | 242.66 (+132.03%) | 245.1  |     5.4     |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  1   |  522.08 (+35.87%) | 26.24  |    138.32   |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  0   |  104.36 (-57.33%) |  27.1  |     5.32    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  1   |  382.56 (-42.95%) | 23.34  |     4.42    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  2   |       807.74      | 271.54 |     4.64    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  3   |       981.36      | 221.8  |    79.48    |
-    +---------+------+-------------------+--------+-------------+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   236.36  | 27.94 (-31.52%) |    138.0    |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   236.58  | 27.86 (-31.72%) |    138.2    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   280.68  |      27.02      |     77.6    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |   101.4   |      22.52      |     4.42    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   100.92  |      22.68      |     4.4     |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   100.96  |      22.54      |     4.38    |
+    +---------+------+-----------+-----------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         serial (v2.11)
@@ -129,29 +148,31 @@
     |    1    |  3   |   107.52  | 21.86  |     4.46    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.10)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.84  |  27.1  |    138.36   |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   236.96  |  27.1  |    138.32   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   280.06  | 26.94  |     77.5    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.76  | 23.42  |     4.36    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.02  | 23.42  |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.08  |  23.2  |     4.4     |
-    +---------+------+-----------+--------+-------------+
-
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
+        parallel (v2.12)
+
+    +--------------------------------------------------------------------+
+    |                  test_rt_instr_cpu_susp_parallel                   |
+    +---------+------+-------------------+-----------------+-------------+
+    | Cluster | Core |     Powerdown     |      Wakeup     | Cache Flush |
+    +---------+------+-------------------+-----------------+-------------+
+    |    0    |  0   |       663.12      | 19.66 (-39.21%) |     8.26    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    0    |  1   |       804.18      | 19.24 (-40.65%) |     8.1     |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  0   |  105.58 (-58.80%) |      19.68      |     7.42    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  1   |  245.02 (-39.67%) |       19.8      |     6.82    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  2   |  383.82 (-30.83%) |      18.84      |     7.06    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  3   | 523.36 (+391.23%) |       19.0      |     7.3     |
+    +---------+------+-------------------+-----------------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
         parallel (v2.11)
 
     +---------+------+-------------------+--------+-------------+
@@ -170,24 +191,23 @@
     |    1    |  3   |  408.16 (+66.94%) | 19.82  |     7.38    |
     +---------+------+-------------------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.10)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.12)
 
-    +---------+------+-------------------+--------+-------------+
-    | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  0   |       801.04      | 18.66  |     8.22    |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  1   |       661.28      | 19.08  |     7.88    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  0   |  105.9 (-72.51%)  |  20.3  |     7.58    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  1   | 383.58 (+261.32%) |  20.4  |     7.42    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  2   |       523.52      |  20.1  |     7.74    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  3   |       244.5       | 20.16  |     7.56    |
-    +---------+------+-------------------+--------+-------------+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   100.04  | 20.32 (-38.50%) |     5.62    |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   99.78   |  20.6 (-36.10%) |     5.42    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   278.28  |      19.52      |     4.32    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |    97.3   |      19.44      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   97.56   |      19.52      |     4.32    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   97.52   |      19.46      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
@@ -207,30 +227,30 @@
     |    1    |  3   |   104.32  | 19.18  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   99.84   | 18.86  |     5.54    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   100.2   | 18.82  |     5.66    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   278.12  | 20.56  |     4.48    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   96.68   | 20.62  |     4.3     |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   96.94   | 20.14  |     4.42    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   96.68   | 20.46  |     4.32    |
-    +---------+------+-----------+--------+-------------+
-
 ``CPU_OFF`` on all non-lead CPUs
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.12)
+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   236.3   | 30.88 (-29.30%) |    137.76   |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   236.66  |  30.5 (-29.23%) |    138.02   |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   175.9   |       27.0      |    77.86    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |   100.96  |      27.56      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   101.04  |      26.48      |     4.38    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   101.08  |      26.74      |     4.4     |
+    +---------+------+-----------+-----------------+-------------+
+
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
     +---------+------+-----------+--------+-------------+
@@ -249,29 +269,27 @@
     |    1    |  3   |   107.74  |  25.8  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
-
-    +---------------------------------------------------+
-    |       test_rt_instr_cpu_off_serial (latest)       |
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.04  | 30.02  |    137.9    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   235.38  |  29.7  |    137.72   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   175.18  | 26.96  |    77.26    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.56  | 28.34  |     4.32    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.38  | 26.82  |     4.3     |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.86  | 26.98  |     4.42    |
-    +---------+------+-----------+--------+-------------+
-
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.12)
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     1.0      |
+    +-------------+--------+--------------+
+    |      0      |   1    |     1.02     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.52     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     0.92     |
+    +-------------+--------+--------------+
+
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.11)
 
     +-------------+--------+--------------+
@@ -290,24 +308,6 @@
     |      1      |   3    |     1.02     |
     +-------------+--------+--------------+
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.10)
-
-    +-------------+--------+----------------------+
-    |   Cluster   |  Core  |       Latency        |
-    +-------------+--------+----------------------+
-    |      0      |   0    |    1.1 (-25.68%)     |
-    +-------------+--------+----------------------+
-    |      0      |   1    |         1.06         |
-    +-------------+--------+----------------------+
-    |      1      |   0    |         0.58         |
-    +-------------+--------+----------------------+
-    |      1      |   1    |         0.88         |
-    +-------------+--------+----------------------+
-    |      1      |   2    |         0.92         |
-    +-------------+--------+----------------------+
-    |      1      |   3    |         0.9          |
-    +-------------+--------+----------------------+
-
 Annotated Historic Results
 --------------------------
 
@@ -530,5 +530,5 @@
 
 .. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
-.. _TF-A v2.11-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.11-rc0
-.. _TFTF v2.11-rc0: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/?h=v2.11-rc0
+.. _TF-A v2.12-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.12-rc0
+.. _TFTF v2.12-rc0: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/?h=v2.12-rc0
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
index c1c4dd6..178d8e6 100644
--- a/docs/perf/psci-performance-n1sdp.rst
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -6,8 +6,8 @@
 
 The following source trees and binaries were used:
 
-- `TF-A v2.11-rc0`_
-- `TFTF v2.11-rc0`_
+- `TF-A v2.12-rc0`_
+- `TFTF v2.12-rc0`_
 - SCP/MCP `Prebuilt Images`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
@@ -92,6 +92,20 @@
 ``CPU_SUSPEND`` to deepest power level
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.12)
+
+    +---------+------+----------------+--------+----------------+
+    | Cluster | Core |   Powerdown    | Wakeup |  Cache Flush   |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   |      2.58      | 24.14  | 0.28 (-69.57%) |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   | 4.24 (-32.27%) |  40.1  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   |      3.58      | 35.54  |      0.28      |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   |      3.28      | 42.36  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.11)
 
     +---------+------+----------------+--------+----------------+
@@ -106,20 +120,19 @@
     |    1    |  0   | 3.7 (+40.15%)  |  38.1  |      0.28      |
     +---------+------+----------------+--------+----------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.10)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.12)
 
-    +---------+------+----------------+------------------+-----------------+
-    | Cluster | Core |   Powerdown    |      Wakeup      |   Cache Flush   |
-    +---------+------+----------------+------------------+-----------------+
-    |    0    |  0   |      2.12      | 23.94 (+137.50%) |  0.42 (-47.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    0    |  0   |      3.52      | 42.08 (+164.32%) |  0.26 (+62.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    1    |  0   | 2.76 (-25.00%) | 38.3 (+195.52%)  |  0.26 (+62.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    1    |  0   |      2.64      | 44.56 (+139.83%) | 0.36 (+100.00%) |
-    +---------+------+----------------+------------------+-----------------+
+    +---------+------+-----------+--------+-------------+
+    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
+    +---------+------+-----------+--------+-------------+
+    |    0    |  0   |    1.9    |  23.8  |     0.36    |
+    +---------+------+-----------+--------+-------------+
+    |    0    |  0   |    2.26   | 23.86  |     0.34    |
+    +---------+------+-----------+--------+-------------+
+    |    1    |  0   |    2.02   |  23.4  |     0.36    |
+    +---------+------+-----------+--------+-------------+
+    |    1    |  0   |    2.24   | 23.84  |     0.36    |
+    +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.11)
 
@@ -135,24 +148,23 @@
     |    1    |  0   |    2.24   | 22.66  |     0.3     |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.10)
-
-    +---------+------+-----------+------------------+----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |  Cache Flush   |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    1.74   | 23.7 (+138.91%)  |      0.3       |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    2.08   | 23.96 (+128.63%) | 0.26 (-27.78%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |    1.9    | 23.62 (+143.00%) | 0.28 (+75.00%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |    2.06   | 23.92 (+129.12%) | 0.26 (+62.50%) |
-    +---------+------+-----------+------------------+----------------+
-
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.12)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.46   |  31.7  |      0.32      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    2.06   |  35.5  | 0.48 (+60.00%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    1.96   |  35.7  |      0.32      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.08   | 23.38  |      0.28      |
+    +---------+------+-----------+--------+----------------+
+
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.11)
 
     +---------+------+----------------+--------+-------------+
@@ -167,20 +179,19 @@
     |    1    |  0   |      2.14      | 21.92  |     0.28    |
     +---------+------+----------------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.10)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.12)
 
-    +---------+------+---------------+------------------+----------------+
-    | Cluster | Core |   Powerdown   |      Wakeup      |  Cache Flush   |
-    +---------+------+---------------+------------------+----------------+
-    |    0    |  0   | 1.5 (+70.45%) | 35.02 (+184.25%) |      0.24      |
-    +---------+------+---------------+------------------+----------------+
-    |    0    |  0   |      1.92     | 38.12 (+160.74%) |      0.28      |
-    +---------+------+---------------+------------------+----------------+
-    |    1    |  0   |      1.88     | 38.1 (+169.45%)  | 0.26 (+62.50%) |
-    +---------+------+---------------+------------------+----------------+
-    |    1    |  0   |      2.04     | 23.1 (+144.70%)  |      0.24      |
-    +---------+------+---------------+------------------+----------------+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.66   | 23.22  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    2.58   | 23.72  | 0.78 (+85.71%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.02   | 23.84  |      0.38      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.16   | 23.92  |      0.34      |
+    +---------+------+-----------+--------+----------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
@@ -196,26 +207,26 @@
     |    1    |  0   |    2.18   |  22.3  |     0.34    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
-
-    +---------+------+-----------+------------------+-----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |   Cache Flush   |
-    +---------+------+-----------+------------------+-----------------+
-    |    0    |  0   |    1.52   | 23.08 (+145.53%) |       0.3       |
-    +---------+------+-----------+------------------+-----------------+
-    |    0    |  0   |    1.98   | 23.68 (+141.63%) |  0.28 (+55.56%) |
-    +---------+------+-----------+------------------+-----------------+
-    |    1    |  0   |    1.84   | 23.86 (+148.54%) | 0.28 (+100.00%) |
-    +---------+------+-----------+------------------+-----------------+
-    |    1    |  0   |    1.98   | 23.68 (+142.13%) |  0.28 (+55.56%) |
-    +---------+------+-----------+------------------+-----------------+
-
 ``CPU_OFF`` on all non-lead CPUs
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.12)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.84   | 23.82  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |   14.18   | 31.78  | 0.56 (+86.67%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.64   | 30.54  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   14.18   | 31.82  |      0.68      |
+    +---------+------+-----------+--------+----------------+
+
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
     +---------+------+-----------+--------+----------------+
@@ -230,23 +241,23 @@
     |    1    |  0   |   13.84   | 30.06  | 0.28 (-60.00%) |
     +---------+------+-----------+--------+----------------+
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
-
-    +---------+------+-----------+------------------+----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |  Cache Flush   |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    1.78   | 23.7 (+138.43%)  |      0.3       |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |   13.96   | 31.16 (+137.86%) | 0.34 (-32.00%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |   13.54   | 30.24 (+144.66%) | 0.26 (-38.10%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |   14.46   | 31.12 (+134.69%) | 0.7 (+34.62%)  |
-    +---------+------+-----------+------------------+----------------+
-
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.12)
+
+    +----------+------+-------------------+
+    | Cluster  | Core |      Latency      |
+    +----------+------+-------------------+
+    |    0     |  0   |        0.14       |
+    +----------+------+-------------------+
+    |    0     |  0   |   0.2 (-28.57%)   |
+    +----------+------+-------------------+
+    |    1     |  0   |        0.2        |
+    +----------+------+-------------------+
+    |    1     |  0   |        0.26       |
+    +----------+------+-------------------+
+
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.11)
 
     +-------------+--------+--------------+
@@ -261,28 +272,12 @@
     |      1      |   0    |     0.26     |
     +-------------+--------+--------------+
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.10)
-
-    +----------------------------------------------+
-    | test_rt_instr_psci_version_parallel (latest) |
-    +-------------+--------+-----------------------+
-    |   Cluster   |  Core  |        Latency        |
-    +-------------+--------+-----------------------+
-    |      0      |   0    |     0.14 (+75.00%)    |
-    +-------------+--------+-----------------------+
-    |      0      |   0    |          0.22         |
-    +-------------+--------+-----------------------+
-    |      1      |   0    |          0.2          |
-    +-------------+--------+-----------------------+
-    |      1      |   0    |          0.26         |
-    +-------------+--------+-----------------------+
-
 --------------
 
 *Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
-.. _TF-A v2.11-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.11-rc0
-.. _TFTF v2.11-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.11-rc0
+.. _TF-A v2.12-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.12-rc0
+.. _TFTF v2.12-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.12-rc0
 .. _user guide: https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-docs/-/blob/master/docs/n1sdp/user-guide.rst
-.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.11.0/n1sdp/release/
+.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/
 .. _N1SDP: https://developer.arm.com/documentation/101489/latest
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index afbb157..a086a98 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -65,25 +65,26 @@
    -  ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
       registers.
    -  ``devel_rsa`` : return a development public key hash embedded in the BL1
-      and BL2 binaries. This hash has been obtained from the RSA public key
-      ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
-      this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY``
-      when creating the certificates.
+      and BL2 binaries. This hash corresponds to the development private key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``.
+      The hashing algorithm is selected by ``HASH_ALG``; sha256 is used if
+      ``HASH_ALG`` is not specified. A different RSA key can be specified by setting
+      ``ROT_KEY``, there are 3k and 4k RSA keys in ``plat/arm/board/common/rotpk/``.
    -  ``devel_ecdsa`` : return a development public key hash embedded in the BL1
-      and BL2 binaries. This hash has been obtained from the ECDSA public key
-      ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To
-      use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
-      ``ROT_KEY`` when creating the certificates.
-   -  ``devel_full_dev_rsa_key`` : returns a development public key embedded in
-      the BL1 and BL2 binaries. This key has been obtained from the RSA public
-      key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``.
-
--  ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``, excluding
-   ``devel_full_dev_rsa_key``. Specifies the location of the ROTPK hash. Not
-   expected to be a build option. This defaults to
-   ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified
-   algorithm. Providing ``ROT_KEY`` enforces generation of the hash from the
-   ``ROT_KEY`` and overwrites the default hash file.
+      and BL2 binaries. This hash corresponds to the development private key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem`` unless a different key
+      is specified with ``ROT_KEY``, such as the 384 bit key in the same directory.
+      he hashing algorithm is selected by ``HASH_ALG``; sha256 is used if ``HASH_ALG``
+      is not specified.
+   -  ``devel_full_dev_rsa_key`` : return a development public key embedded in
+      the BL1 and BL2 binaries. This key corresponds to the RSA private
+      key ``plat/arm/board/common/rotpk/arm_rotprivk.pem`` by default, but can
+      be changed by setting ``ROT_KEY``, there are 3k and 4k RSA keys in
+      ``plat/arm/board/common/rotpk/``.
+   - ``devel_full_dev_ecdsa_key`` : return a development public key embedded in
+      the BL1 and BL2 binaries. This key corresponds to the EC private key
+      ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem``, unless a different
+      ECDSA key is specified by ``ROT_KEY``, such as the 384 bit key in the same directory.
 
 -  ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
 
diff --git a/docs/plat/arm/automotive_rd/index.rst b/docs/plat/arm/automotive_rd/index.rst
index d0db6ac..04ca2b9 100644
--- a/docs/plat/arm/automotive_rd/index.rst
+++ b/docs/plat/arm/automotive_rd/index.rst
@@ -11,15 +11,34 @@
 Boot Sequence
 -------------
 
-BL2 –> BL31 –> BL33
+The boot process starts from RSE (Runtime Security Engine) that loads the
+Application Processor (AP) BL2 image and signals the System Control Processor (SCP)
+to power up the AP. The AP then runs AP BL2
 
-The boot process starts from RSE (Runtime Security Engine) that loads the BL2 image
-and signals the System Control Processor (SCP) to power up the Application Processor (AP).
-The AP then runs BL2, which loads the rest of the images, including the runtime firmware
-BL31, and proceeds to execute it. Finally, it passes control to the non-secure world
-BL33 (u-boot).
+The primary compute boot flow follows the following steps:
 
-BL2 performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+1. AP BL2:
+
+   * Performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+   * Copies the AP BL31 image from Secure Flash to Secure SRAM
+   * Copies the AP BL32 (OP-TEE) image from Secure Flash to Secure DRAM
+   * Copies the AP BL33 (U-Boot) image from Secure Flash to Normal DRAM
+   * Transfers the execution to AP BL31
+
+2. AP BL31:
+
+   * Initializes Trusted Firmware-A Services
+   * Transfers the execution to AP BL32 and then transfers the execution to AP BL33
+   * During runtime, acts as the Secure Monitor, handling SMC calls,
+     and context switching between secure and non-secure worlds.
+
+3. AP BL32:
+
+   * Initializes OP-TEE environment
+   * Initializes Secure Partitions
+   * Transfers the execution back to AP BL31
+   * During runtime, it facilitates secure communication between the
+     normal world environment (e.g. Linux) and the Trusted Execution Environment.
 
 Build Procedure (TF-A only)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -41,6 +60,9 @@
       COT=tbbr \
       ARM_ROTPK_LOCATION=devel_rsa \
       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+      BL32=<path to optee binary> \
+      SPD=spmd \
+      SPMD_SPM_AT_SEL2=0 \
       BL33=<path to u-boot binary> \
 
 *Copyright (c) 2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-support.rst b/docs/plat/arm/fvp/fvp-support.rst
index 5292d68..ad76cf1 100644
--- a/docs/plat/arm/fvp/fvp-support.rst
+++ b/docs/plat/arm/fvp/fvp-support.rst
@@ -11,8 +11,8 @@
 .. note::
    The FVP models used are Version 11.26 Build 11, unless otherwise stated.
 
--  ``FVP_Base_AEMvA``
 -  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_RevC-2xAEMvA``
 -  ``FVP_Base_Cortex-A32x4``
 -  ``FVP_Base_Cortex-A35x4``
 -  ``FVP_Base_Cortex-A53x4``
@@ -40,11 +40,12 @@
 -  ``FVP_Base_Neoverse-N1``
 -  ``FVP_Base_Neoverse-N2``
 -  ``FVP_Base_Neoverse-V1``
--  ``FVP_Base_RevC-2xAEMv8A``
 -  ``FVP_BaseR_AEMv8R``
 -  ``FVP_Morello`` (Version 0.11/33)
 -  ``FVP_RD_V1``
--  ``FVP_TC2`` (Version 11.23/17)
+-  ``FVP_RD_1_AE`` (Version 11.27/20)
+-  ``FVP_TC3`` (Version 11.26/16)
+-  ``FVP_TC4`` (Version 0.0/8404)
 
 The latest version of the AArch32 build of TF-A has been tested on the
 following Arm FVPs without shifted affinities, and that do not support threaded
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 5320a3b..1e37696 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -56,7 +56,7 @@
 
 #. Obtain SCP binaries (Juno)
 
-   This version of TF-A is tested with SCP version 2.12.0 on Juno. You can
+   This version of TF-A is tested with SCP version 2.15.0 on Juno. You can
    download pre-built SCP binaries (``scp_bl1.bin`` and ``scp_bl2.bin``)
    from `TF-A downloads page`_. Alternatively, you can `build
    the binaries from source`_.
@@ -241,11 +241,11 @@
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
 .. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
-.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/juno/
+.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.15.0/juno/
 .. _build the binaries from source: https://github.com/ARM-software/SCP-firmware/blob/master/user_guide.md#scp-firmware-user-guide
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
diff --git a/docs/plat/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index 9469e9a..467738c 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -13,13 +13,15 @@
 - SCMI
 - MHUv2
 
-Currently, the main difference between TC0 (TARGET_PLATFORM=0), TC1
-(TARGET_PLATFORM=1), TC2 (TARGET_PLATFORM=2) platforms w.r.t to TF-A
-is the CPUs supported as below:
+The TF-A build is specified by the option `TARGET_PLATFORM` which represents
+the Total Compute platform number. The platforms support the CPU variants
+listed as below:
 
 -  TC0 has support for Cortex A510, Cortex A710 and Cortex X2. (Note TC0 is now deprecated)
 -  TC1 has support for Cortex A510, Cortex A715 and Cortex X3. (Note TC1 is now deprecated)
--  TC2 has support for Cortex A520, Cortex A720 and Cortex x4.
+-  TC2 has support for Cortex A520, Cortex A720 and Cortex x4. (Note TC2 is now deprecated)
+-  TC3 has support for Cortex A520, Cortex A725 and Cortex x925.
+
 
 Boot Sequence
 -------------
@@ -43,7 +45,7 @@
    .. code:: shell
 
       make PLAT=tc BL33=<path_to_uboot.bin> \
-      SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={0,1,2} all fip
+      SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={3} all fip
 
    Enable TBBR by adding the following options to the make command:
 
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index a8e0c8d..0b53d1d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -24,6 +24,7 @@
    mt8188
    mt8192
    mt8195
+   mt8196
    nvidia-tegra
    warp7
    imx8
diff --git a/docs/plat/mt8188.rst b/docs/plat/mt8188.rst
index 93abaa5..57b93ac 100644
--- a/docs/plat/mt8188.rst
+++ b/docs/plat/mt8188.rst
@@ -13,9 +13,9 @@
 
     Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel
 
-    How to Build
-    ------------
+How to Build
+------------
 
-    .. code:: shell
+.. code:: shell
 
-           make CROSS_COMPILE=aarch64-linux-gnu- LD=aarch64-linux-gnu-gcc PLAT=mt8188 DEBUG=1 COREBOOT=1
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8188 DEBUG=1 COREBOOT=1
diff --git a/docs/plat/mt8196.rst b/docs/plat/mt8196.rst
new file mode 100644
index 0000000..e4b6c63
--- /dev/null
+++ b/docs/plat/mt8196.rst
@@ -0,0 +1,23 @@
+MediaTek 8196
+=============
+
+MediaTek 8196 (MT8196) is a 64-bit ARM SoC introduced by MediaTek in 2024.
+The chip incorporates eight cores - four Cortex-A720 cores, three Cortex-X4
+cores and one Cortex-X925 core.
+Cortex-A720 can operate at up to 2.1 GHz.
+Cortex-X4 can operate at up to 2.8 GHz.
+Cortex-X925 can operate at up to 3.6 GHz.
+
+Boot Sequence
+-------------
+
+::
+
+    Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel
+
+How to Build
+------------
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8196 DEBUG=1 COREBOOT=1
diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst
index 1d483e7..0f89500 100644
--- a/docs/plat/qti.rst
+++ b/docs/plat/qti.rst
@@ -2,7 +2,7 @@
 ===========================
 
 Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180,
-SC7280.
+SC7280 and QCS615.
 
 Boot Trace
 -------------
@@ -30,7 +30,8 @@
 
     make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sc7180 COREBOOT=1
 
-update value of CROSS_COMPILE argument with your cross-compilation toolchain.
+Update value of CROSS_COMPILE argument with your cross-compilation toolchain.
+Update the value of PLAT to be either of sc7180, sc7280 or qcs615
 
 Additional QTISECLIB_PATH=<path to qtiseclib> can be added in build command.
 if QTISECLIB_PATH is not added in build command stub implementation of qtiseclib
@@ -41,3 +42,4 @@
 `link <https://github.com/coreboot/qc_blobs/blob/master/sc7180/qtiseclib/libqtisec.a?raw=true>`__
 QTISELIB for SC7280 is available at
 `link <https://github.com/coreboot/qc_blobs/blob/master/sc7280/qtiseclib/libqtisec.a?raw=true>`__
+QTISECLIB for QCS615 is not available yet and currently compile with stubs only.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index e672ad7..6d03f44 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2329,6 +2329,98 @@
 
 When ENABLE_RME is disabled, this function is not used.
 
+Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : const struct el3_token_sign_request *req
+    Return    : int
+
+Queue realm attestation token signing request from the RMM in EL3. The interface between
+the RMM and EL3 is modeled as a queue but the underlying implementation may be different,
+so long as the semantics of queuing and the error codes are used as defined below.
+
+See :ref:`el3_token_sign_request_struct` for definition of the request structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+      arg0: Pointer to the token sign request to be pushed to EL3.
+      The structure must be located in the RMM-EL3 shared
+      memory buffer and must be locked before use.
+
+Return codes:
+        - E_RMM_OK	On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that the request was not queued since the
+	  queue in EL3 is full. This may also be returned for any reason
+	  or situation in the system, that prevents accepting the request
+	  from the RMM.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_pull_resp() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : struct el3_token_sign_response *resp
+    Return    : int
+
+Populate the attestation signing response in the ``resp`` parameter. The interface between
+the RMM and EL3 is modeled as a queue for responses but the underlying implementation may
+be different, so long as the semantics of queuing and the error codes are used as defined
+below.
+
+See :ref:`el3_token_sign_response_struct` for definition of the response structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+          resp: Pointer to the token sign response to get from EL3.
+	  The structure must be located in the RMM-EL3 shared
+	  memory buffer and must be locked before use.
+
+Return:
+        - E_RMM_OK      On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that a response is not ready yet.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_get_rak_pub() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, size_t *, unsigned int
+    Return   : int
+
+This function returns the public portion of the realm attestation key which will be used to
+sign Realm attestation token. Typically, with delegated attestation, the private key is
+returned, however, there may be platforms where the private key bits are better protected
+in a platform specific manner such that the private key is not exposed. In such cases,
+the RMM will only cache the public key and forward any requests such as signing, that
+uses the private key to EL3. The API currently only supports P-384 ECC curve key.
+
+This is an optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the function are:
+
+    arg0 - A pointer to the buffer where the public key should be copied
+    by this function. The buffer must be big enough to hold the
+    attestation key.
+
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+    function returns the attestation key length in this parameter.
+
+    arg2 - The type of the elliptic curve to which the requested attestation key
+    belongs.
+
+The function returns E_RMM_OK on success, RMM_E_INVAL if arguments are invalid and
+E_RMM_UNK if the SMC is not implemented or if interface version is < 0.4.
+
 Function : bl31_plat_enable_mmu [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2362,7 +2454,7 @@
 The value should be obtained from a reliable source of randomness.
 
 This function is only needed if ARMv8.3 pointer authentication is used in the
-Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to non-zero.
+Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to 1, 2 or 3.
 
 Function : plat_get_syscnt_freq2() [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -3461,7 +3553,10 @@
 This function is invoked by BL31's exception handler when there is a synchronous
 system register trap caused by access to the implementation defined registers.
 It allows platforms enabling ``IMPDEF_SYSREG_TRAP`` to emulate those system
-registers choosing to program bits of their choice.
+registers choosing to program bits of their choice. If using in combination with
+``ARCH_FEATURE_AVAILABILITY``, the macros
+{SCR,MDCR,CPTR}_PLAT_{BITS,IGNORED,FLIPPED} should be defined to report correct
+results.
 
 The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
 syndrome register, which encodes the instruction that was trapped.
diff --git a/docs/resources/diagrams/root_context_sequence.png b/docs/resources/diagrams/root_context_sequence.png
new file mode 100644
index 0000000..67783f1
--- /dev/null
+++ b/docs/resources/diagrams/root_context_sequence.png
Binary files differ
diff --git a/docs/threat_model/firmware_threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
index f8e4f7d..ae0219e 100644
--- a/docs/threat_model/firmware_threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -892,28 +892,65 @@
 
 .. topic:: Measured Boot Threats (or lack of)
 
- In the current Measured Boot design, BL1, BL2, and BL31, as well as the
- secure world components, form the |SRTM|. Measurement data is currently
- considered an asset to be protected against attack, and this is achieved
- by storing them in the Secure Memory.
- Beyond the measurements stored inside the TCG-compliant Event Log buffer,
- there are no other assets to protect or threats to defend against that
- could compromise |TF-A| execution environment's security.
+ In the current Measured Boot design the following components form the |TCB|:
+
+   - BL1, BL2, BL31
+   - Secure world components
+   - RMM (if RME extension is implemented)
+   - The configuration data of the above components
+
+ Across various Measured Boot backends, the data recorded during the flow as
+ well as the criticality of this data can vary. In most cases, these attributes
+ are considered valuable assets and are protected against potential attacks:
+
+   - Image measurement: the digest value of a component produced by a hash
+     function.
+   - Signer-id: the digest value of the image verification publiy key. The
+     verification public key is part of the image metadata.
+
+ In addition to these, other metadata attributes (image version, hash algorithm
+ identifier, etc) could be recorded during the Measured Boot process. But these
+ are not critical data.
+
+ In this context, an attack means modifying the measurement data (image or
+ public key hash) or recording arbitrary data as valid measurements.
+
+ The current Measured Boot design consists of two main parts. A frontend, which
+ is responsible for taking the measurements, and a backend which is responsible
+ for storing them. |TF-A| makes it possible to integrate various backends. Some
+ of these are implemented by the |TF-A| projects, while others are part of
+ different projects, and |TF-A| provides an integration layer.
+
+   - TCG-compliant Event Log: Implemented by |TF-A|. Measurements are stored in
+     the Event Log which is located on the secure on-chip memory of the AP. The
+     address of the Event Log buffer is handed off between boot stages and new
+     measurements are appended to the Event Log. A limitation of the current
+     Measured Boot implementation in |TF-A| is that it does not extend the
+     measurements into a |PCR| of a Discrete |TPM|, where measurements would
+     be securely stored and protected against tampering.
+   - `CCA Measured Boot`_: Implemented by |TF-M|. Measurements are stored in
+     |HES| secure on-chip memory. |HES| implements protection against tampering
+     its on-chip memory. |HES| interface is available for BL1 and BL2.
+   - `DICE Protection Environment`_ (DPE): Implemented by |TF-M|. Measurements
+     are stored in |RSE| secure on-chip memory. |RSE| implements protection
+     against tampering its on-chip memory. DPE provides additional protection
+     against unauthorized access by malicious actors through the use of one-time
+     context handles and the identification of the client's target locality
+     (location of the client).
+
+ Beyond the measurements (image digest and signer-id) there are no other assets
+ to protect or threats to defend against that could compromise |TF-A| execution
+ environment's security.
 
  There are general security assets and threats associated with remote/delegated
  attestation. However, these are outside the |TF-A| security boundary and
  should be dealt with by the appropriate agent in the platform/system.
  Since current Measured Boot design does not use local attestation, there would
- be no further assets to protect(like unsealed keys).
+ be no further assets to protect (like unsealed keys).
 
- A limitation of the current Measured Boot design is that it is dependent upon
- Secure Boot as implementation of Measured Boot does not extend measurements
- into a discrete |TPM|, where they would be securely stored and protected
- against tampering. This implies that if Secure-Boot is compromised, Measured
- Boot may also be compromised.
-
- Platforms must carefully evaluate the security of the default implementation
- since the |SRTM| includes all secure world components.
+ System integrators must carefully evaluate the security requirement and
+ capabilities of their platform and choose an appropriate Measured Boot
+ solution.
 
 
 .. _Runtime Firmware Threats:
@@ -1169,3 +1206,5 @@
 .. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
 .. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
 .. _PSR Specification: https://developer.arm.com/documentation/den0106/0100
+.. _CCA Measured Boot: https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/measured_boot_integration_guide.html
+.. _DICE Protection Environment: https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/dice_protection_environment/dice_protection_environment.html
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 9fe8b37..fbcbdc7 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -312,7 +312,7 @@
 	/*
 	 * Send powerdown request to online secondary core(s)
 	 */
-	ret = psci_stop_other_cores(0, css_raise_pwr_down_interrupt);
+	ret = psci_stop_other_cores(plat_my_core_pos(), 0, css_raise_pwr_down_interrupt);
 	if (ret != PSCI_E_SUCCESS) {
 		ERROR("Failed to powerdown secondary core(s)\n");
 	}
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 19c3450..841c1fd 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2015-2021, Xilinx Inc.
+ * Copyright (c) 2015-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  * Written by Michal Simek.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -45,7 +46,7 @@
 #define TIMEOUT_COUNT_US	U(0x10624)
 
 struct dcc_console {
-	struct console console;
+	console_t console;
 };
 
 static inline uint32_t __dcc_getstatus(void)
@@ -147,13 +148,14 @@
 	},
 };
 
-int console_dcc_register(void)
+int console_dcc_register(console_t *console)
 {
-	return console_register(&dcc_console.console);
+	memcpy(console, &dcc_console.console, sizeof(console_t));
+	return console_register(console);
 }
 
-void console_dcc_unregister(void)
+void console_dcc_unregister(console_t *console)
 {
-	dcc_console_flush(&dcc_console.console);
-	(void)console_unregister(&dcc_console.console);
+	dcc_console_flush(console);
+	(void)console_unregister(console);
 }
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index ef04c4d..adca4fd 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -124,22 +124,35 @@
 				      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.
+			 *
+			 * It is recommended to set GPCEN and wait for completion
+			 * prior to setting ACCESSEN.
+			 */
+			mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
+					SMMU_ROOT_CR0_GPCEN);
+
+			/* Poll for GPCEN ack bit. */
+			if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
+					SMMU_ROOT_CR0_GPCEN,
+					SMMU_ROOT_CR0_GPCEN) != 0) {
+				WARN("Failed enabling SMMU GPC.\n");
+			}
+
+			/*
+			 * ACCESSEN=1: SMMU- and client-originated accesses are
+			 *             not terminated by this mechanism.
 			 */
 			mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
 					SMMU_ROOT_CR0_GPCEN |
 					SMMU_ROOT_CR0_ACCESSEN);
 
-			/* Poll for ACCESSEN and GPCEN ack bits. */
+			/* Poll for ACCESSEN ack bit. */
 			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");
+				WARN("Failed enabling SMMU ACCESS.\n");
 
 				/*
 				 * Do not return in error, but fall back to
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 765491e..b3c4c91 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -25,9 +25,9 @@
 
 # Specify mbed TLS configuration file
 ifeq (${PSA_CRYPTO},1)
-  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/default_psa_mbedtls_config.h>"
 else
-  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/mbedtls_config-3.h>"
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/default_mbedtls_config.h>"
 endif
 
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 9bfcaac..8fe426b 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -275,6 +275,7 @@
 		     unsigned char output[CRYPTO_MD_MAX_SIZE])
 {
 	const mbedtls_md_info_t *md_info;
+	int rc;
 
 	md_info = mbedtls_md_info_from_type(md_type(md_algo));
 	if (md_info == NULL) {
@@ -286,7 +287,12 @@
 	 * 'output' hash buffer pointer considering its size is always
 	 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
 	 */
-	return mbedtls_md(md_info, data_ptr, data_len, output);
+	rc = mbedtls_md(md_info, data_ptr, data_len, output);
+	if (rc != 0) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	return CRYPTO_SUCCESS;
 }
 #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index f2ccf15..0e4b57e 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -27,8 +27,10 @@
 
 #define LIB_NAME		"mbed TLS PSA"
 
-/* Maximum length of R_S pair in the ECDSA signature in bytes */
-#define MAX_ECDSA_R_S_PAIR_LEN	64U
+/* Minimum required size for a buffer containing a raw EC signature when using
+ * a maximum curve size of 384 bits.
+ * This is calculated as 2 * (384 / 8). */
+#define ECDSA_SIG_BUFFER_SIZE	96U
 
 /* Size of ASN.1 length and tag in bytes*/
 #define SIZE_OF_ASN1_LEN	1U
@@ -199,7 +201,7 @@
 	psa_key_id_t psa_key_id;
 	mbedtls_pk_type_t pk_alg;
 	psa_algorithm_t psa_alg;
-	__unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
+	__unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0};
 	unsigned char *local_sig_ptr;
 	size_t local_sig_len;
 
@@ -252,7 +254,7 @@
 		size_t key_bits = psa_get_key_bits(&psa_key_attr);
 
 		rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
-					      reformatted_sig, MAX_ECDSA_R_S_PAIR_LEN,
+					      reformatted_sig, ECDSA_SIG_BUFFER_SIZE,
 					      &local_sig_len);
 		if (rc != 0) {
 			rc = CRYPTO_ERR_SIGNATURE;
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c
index d2cd4d6..892d333 100644
--- a/drivers/cadence/emmc/cdns_sdmmc.c
+++ b/drivers/cadence/emmc/cdns_sdmmc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,35 +19,6 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-/* Card busy and present */
-#define CARD_BUSY					1
-#define CARD_NOT_BUSY					0
-
-/* 500 ms delay to read the RINST register */
-#define DELAY_MS_SRS_READ				500
-#define DELAY_RES					10
-
-/* SRS12 error mask */
-#define SRS12_ERR_MASK					0xFFFF8000
-
-/* Check DV dfi_init val=0 */
-#define IO_MASK_END_DATA				0x0
-
-/* Check DV dfi_init val=2; DDR Mode */
-#define IO_MASK_END_DATA_DDR				0x2
-#define IO_MASK_START_DATA				0x0
-#define DATA_SELECT_OE_END_DATA				0x1
-
-#define TIMEOUT						100000
-
-/* General define */
-#define SDHC_REG_MASK					UINT_MAX
-#define SD_HOST_BLOCK_SIZE				0x200
-#define DTCVVAL_DEFAULT_VAL				0xE
-#define CDMMC_DMA_MAX_BUFFER_SIZE			64*1024
-#define CDNSMMC_ADDRESS_MASK				U(0x0f)
-#define CONFIG_CDNS_DESC_COUNT				8
-
 void cdns_init(void);
 int cdns_send_cmd(struct mmc_cmd *cmd);
 int cdns_set_ios(unsigned int clk, unsigned int width);
@@ -62,7 +34,8 @@
 	.read			= cdns_read,
 	.write			= cdns_write,
 };
-
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uintptr_t buf,
+			  size_t size);
 struct cdns_sdmmc_params cdns_params;
 struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
 struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
@@ -92,42 +65,19 @@
 	return 0;
 }
 
-int cdns_busy(void)
-{
-	unsigned int data;
-
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
-	return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
-}
-
-int cdns_vol_reset(void)
-{
-	/* Reset embedded card */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
-	udelay(250);
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
-	udelay(500);
-
-	/* Turn on supply voltage */
-	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
-	udelay(250);
-	return 0;
-}
-
 void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+			struct cdns_sdmmc_sdhc *sdhc_reg)
 {
 	/* Values are taken by the reference of cadence IP documents */
 	combo_phy_reg->cp_clk_wr_delay = 0;
 	combo_phy_reg->cp_clk_wrdqs_delay = 0;
-	combo_phy_reg->cp_data_select_oe_end = 0;
+	combo_phy_reg->cp_data_select_oe_end = 1;
 	combo_phy_reg->cp_dll_bypass_mode = 1;
 	combo_phy_reg->cp_dll_locked_mode = 0;
-	combo_phy_reg->cp_dll_start_point = 0;
+	combo_phy_reg->cp_dll_start_point = 254;
 	combo_phy_reg->cp_gate_cfg_always_on = 1;
 	combo_phy_reg->cp_io_mask_always_on = 0;
-	combo_phy_reg->cp_io_mask_end = 0;
+	combo_phy_reg->cp_io_mask_end = 5;
 	combo_phy_reg->cp_io_mask_start = 0;
 	combo_phy_reg->cp_rd_del_sel = 52;
 	combo_phy_reg->cp_read_dqs_cmd_delay = 0;
@@ -142,38 +92,58 @@
 
 	sdhc_reg->sdhc_extended_rd_mode = 1;
 	sdhc_reg->sdhc_extended_wr_mode = 1;
-	sdhc_reg->sdhc_hcsdclkadj = 0;
+	sdhc_reg->sdhc_hcsdclkadj = 3;
 	sdhc_reg->sdhc_idelay_val = 0;
 	sdhc_reg->sdhc_rdcmd_en = 1;
 	sdhc_reg->sdhc_rddata_en = 1;
-	sdhc_reg->sdhc_rw_compensate = 9;
+	sdhc_reg->sdhc_rw_compensate = 10;
 	sdhc_reg->sdhc_sdcfsh = 0;
-	sdhc_reg->sdhc_sdcfsl = 1;
+	sdhc_reg->sdhc_sdcfsl = 0;
 	sdhc_reg->sdhc_wrcmd0_dly = 1;
 	sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
 	sdhc_reg->sdhc_wrcmd1_dly = 0;
 	sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
-	sdhc_reg->sdhc_wrdata0_dly = 1;
+	sdhc_reg->sdhc_wrdata0_dly = 0;
 	sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
 	sdhc_reg->sdhc_wrdata1_dly = 0;
 	sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
 }
 
-static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+				struct cdns_sdmmc_sdhc *sdhc_reg)
 {
 	uint32_t value = 0;
 	int ret = 0;
+	uint32_t timeout = 0;
+
+	/* HRS00 - Software Reset */
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_HRS00), SDHC_CDNS_HRS00_SWR);
+
+	/* Waiting for SDHC_CDNS_HRS00_SWR reset */
+	timeout = TIMEOUT;
+	do {
+		udelay(250);
+		if (--timeout <= 0) {
+			NOTICE(" SDHC Software Reset failed!!!\n");
+			panic();
+		}
+	} while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00) &
+		SDHC_CDNS_HRS00_SWR) == 1));
+
+	/* Step 1, switch on DLL_RESET */
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	value &= ~SDHC_PHY_SW_RESET;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
 
 	/* program PHY_DQS_TIMING_REG */
 	value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
 		(CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
 		(CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
 		(CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
-			SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DQS_TIMING_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
@@ -183,73 +153,90 @@
 		(CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
 		(CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
 		(CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
-			SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
-		return ret;
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+				 COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG,
+				 cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
+		return -ret;
 	}
 
 	/* program PHY_DLL_MASTER_CTRL_REG */
-	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
-			| (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode)) | (2 << 20) |
+		(CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
 	/* program PHY_DLL_SLAVE_CTRL_REG */
-	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
-		| (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
-		| (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
-		| (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay)) |
+		(CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay)) |
+		(CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay)) |
+		(CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
 	/* program PHY_CTRL_REG */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
-			+ PHY_CTRL_REG);
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS04, COMBO_PHY_REG + PHY_CTRL_REG);
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS05);
 
 	/* phony_dqs_timing=0 */
 	value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS05, value);
 
 	/* switch off DLL_RESET */
 	do {
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
 		value |= SDHC_PHY_SW_RESET;
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+		value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
 	/* polling PHY_INIT_COMPLETE */
 	} while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
 
 	/* program PHY_DQ_TIMING_REG */
-	combo_phy_reg->cp_io_mask_end = 0U;
-	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
-		| (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
-		| (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
-		| (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
+	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on)) |
+		(CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end)) |
+		(CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start)) |
+		(CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
 
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+				 COMBO_PHY_REG + PHY_DQ_TIMING_REG,
+				 cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
+
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	value |= (HRS_09_EXTENDED_RD_MODE | HRS_09_EXTENDED_WR_MODE |
+		HRS_09_RDCMD_EN | HRS_09_RDDATA_EN);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+
+	value = 0;
+	value = SDHC_HCSDCLKADJ(HRS_10_HCSDCLKADJ_VAL);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS10, value);
+
+	value = 0;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS16, value);
+
+	value = (10 << 16);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS07, value);
+
 	return 0;
 }
 
 int cdns_read(int lba, uintptr_t buf, size_t size)
 {
-	inv_dcache_range(buf, size);
+	return 0;
+}
 
+int cdns_write(int lba, uintptr_t buf, size_t size)
+{
 	return 0;
 }
 
@@ -260,120 +247,79 @@
 
 int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
 {
-	data_cmd = true;
-	struct cdns_idmac_desc *desc;
-	uint32_t desc_cnt, i;
-	uint64_t desc_base;
-
+	struct cdns_idmac_desc *cdns_desc_data;
 	assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
-			(cdns_params.desc_size > 0) &&
-			((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
-			((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
-			((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
+	 (cdns_params.desc_size > 0));
 
-	flush_dcache_range(dma_buff, size);
+	cdns_desc_data = (struct cdns_idmac_desc *)cdns_params.desc_base;
+	sd_host_adma_prepare(cdns_desc_data, dma_buff, size);
 
-	desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
-	assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
-
-	if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
-		ERROR("Requested data transfer length %ld is greater than configured length %d",
-				size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
-		return -EINVAL;
-	}
-
-	desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
-	desc_base = (uint64_t)desc;
-	i = 0;
-
-	while ((i + 1) < desc_cnt) {
-		desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
-		desc->reserved = 0;
-		desc->len = MAX_64KB_PAGE;
-		desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
-#if CONFIG_DMA_ADDR_T_64BIT == 1
-		desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
-#endif
-		size -= CDMMC_DMA_MAX_BUFFER_SIZE;
-		desc++;
-		i++;
-	}
-
-	desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
-			ADMA_DESC_ATTR_END;
-	desc->reserved = 0;
-	desc->len = size;
-#if CONFIG_DMA_ADDR_T_64BIT == 1
-	desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
-	desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
-#else
-	desc->addr_lo = (dma_buff & UINT_MAX);
-#endif
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
-	flush_dcache_range(cdns_params.desc_base,
-				desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
-			((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
 	return 0;
 }
 
-static void cdns_host_set_clk(int clk)
+void cdns_host_set_clk(uint32_t clk)
 {
 	uint32_t ret = 0;
 	uint32_t sdclkfsval = 0;
-	uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
+	uint32_t dtcvval = 0xE;
 
-	sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+	sdclkfsval = (SD_HOST_CLK / 2) / clk;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11,
+			(dtcvval << SDMMC_CDN_DTCV) | (sdclkfsval << SDMMC_CDN_SDCLKFS) |
+			(1 << SDMMC_CDN_ICE));
 
-	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
-	if (ret != 0U) {
-		ERROR("Waiting SDMMC_CDN_ICS timeout");
+	ret = cdns_wait_ics(5000, cdns_params.reg_base + SDHC_CDNS_SRS11);
+	if (ret != 0) {
+		ERROR("Waiting ICS timeout");
 	}
-
 	/* Enable DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
-			~SDHC_DLL_RESET_MASK);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & ~0x00000001);
 	/* Set extended_wr_mode */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
-			& SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		(mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & 0xFFFFFFF7) |
+			(1 << EXTENDED_WR_MODE));
 	/* Release DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | 1);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | PHY_SW_RESET_EN);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | RDCMD_EN);
 
 	do {
-		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) &
+		(PHY_INIT_COMPLETE_BIT));
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-	(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) |
+			(1 << SDMMC_CDN_SDCE));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS13, 0xFFFFFFFF);
 }
 
 int cdns_set_ios(unsigned int clk, unsigned int width)
 {
+	uint32_t _status = 0;
 
+	_status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
 	switch (width) {
 	case MMC_BUS_WIDTH_1:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
+		_status &= ~(BIT4);
 		break;
+
 	case MMC_BUS_WIDTH_4:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
+		_status |= BIT4;
 		break;
+
 	case MMC_BUS_WIDTH_8:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
+		_status |= BIT8;
 		break;
+
 	default:
 		assert(0);
 		break;
 	}
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS10), _status);
 	cdns_host_set_clk(clk);
 
 	return 0;
@@ -388,6 +334,7 @@
 	value |= data;
 	mmio_write_32(addr, value);
 	value = mmio_read_32(addr);
+
 	if (value != data) {
 		ERROR("SD host address is not set properly\n");
 		return -ENXIO;
@@ -396,429 +343,403 @@
 	return 0;
 }
 
-int cdns_write(int lba, uintptr_t buf, size_t size)
+
+
+void sd_host_oper_mode(enum sd_opr_modes opr_mode)
 {
-	return 0;
+
+	uint32_t reg = 0;
+
+	switch (opr_mode) {
+	case SD_HOST_OPR_MODE_HV4E_0_SDMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_SDMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= (HV4E);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_SDMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg |= (HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_0_ADMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_0_ADMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_3;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= BIT_AD_64;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_ADMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= HV4E;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_ADMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg |= (HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+	}
 }
 
-static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+void card_reset(bool power_enable)
 {
-	uint32_t value = 0;
-	int ret = 0;
+	uint32_t reg_value = 0;
 
-	/* program HRS09, register 42 */
-	value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
-		| (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
-		| (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
-		| (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
-	if (ret != 0) {
-		ERROR("Program HRS09 failed");
-		return ret;
+	/* Reading SRS10 value before writing */
+	reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+
+	if (power_enable == true) {
+		reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+		reg_value = ((1 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	} else {
+		reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
 	}
-
-	/* program HRS10, register 43 */
-	value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
-	if (ret != 0) {
-		ERROR("Program HRS10 failed");
-		return ret;
-	}
-
-	/* program HRS16, register 48 */
-	value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
-		| (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
-		| (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
-		| (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
-		| (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
-		| (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
-		| (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
-		| (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
-	if (ret != 0) {
-		ERROR("Program HRS16 failed");
-		return ret;
-	}
-
-	/* program HRS07, register 40 */
-	value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
-		| (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
-	if (ret != 0) {
-		ERROR("Program HRS07 failed");
-		return ret;
-	}
-
-	return ret;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
 }
 
-static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
+void high_speed_enable(bool mode)
 {
-	uint32_t ret = 0;
-	uint32_t dtcvval, sdclkfsval;
 
-	dtcvval = DTC_VAL;
-	sdclkfsval = 0;
+	uint32_t reg_value = 0;
+	/* Reading SRS10 value before writing */
+	reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
 
-	if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
-		sdclkfsval = 4;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
-		sdclkfsval = 2;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
-		sdclkfsval = 1;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
-		sdclkfsval = 0;
+	if (mode == true) {
+		reg_value |= HS_EN;
+	} else {
+		reg_value &= ~HS_EN;
 	}
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
-	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
-	if (ret != 0U) {
-		ERROR("Waiting SDMMC_CDN_ICS timeout");
-		return ret;
-	}
-
-	/* Enable DLL reset */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
-	/* Set extended_wr_mode */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
-	(mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &	SDHC_EXTENDED_WR_MODE_MASK) |
-			(1 << EXTENDED_WR_MODE));
-	/* Release DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | 1);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
-	do {
-		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
-	return 0;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
 }
 
 int cdns_reset(void)
 {
-	uint32_t data = 0;
+	volatile uint32_t data = 0;
 	uint32_t count = 0;
-	uint32_t value = 0;
-
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
-	value &= ~(0xFFFF);
-	value |= 0x0;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
-	udelay(500);
 
 	/* Software reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, SRS11_SRFA);
 	/* Wait status command response ready */
 	do {
-		data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
+		data = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00);
 		count++;
-		if (count >= 5000) {
+		if (count >= CDNS_TIMEOUT) {
 			return -ETIMEDOUT;
 		}
-	/* Wait for HRS00.SWR */
-	} while ((data & 1) == 1);
-
-	/* Step 1, switch on DLL_RESET */
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	value &= ~SDHC_PHY_SW_RESET;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+	/* Wait for SRS11 */
+	} while (((SRS11_SRFA_CHK(data)) & 1) == 1);
 
 	return 0;
 }
 
+void sdmmc_host_init(bool uhs2_enable)
+{
+	uint32_t timeout;
+
+	/* SRS11 - Host Control  default value set */
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0x0);
+
+	/* Waiting for detect card */
+	timeout = TIMEOUT;
+	do {
+		udelay(250);
+		if (--timeout <= 0) {
+			NOTICE(" SDHC Card Detecion failed!!!\n");
+			panic();
+		}
+	} while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & CHECK_CARD) == 0));
+
+	/* UHS2 Host setting */
+	if (uhs2_enable == true) {
+	/** need to implement*/
+	}
+
+	/* Card reset */
+
+	card_reset(1);
+	udelay(2500);
+	card_reset(0);
+	udelay(2500);
+	card_reset(1);
+	udelay(2500);
+
+	/* Enable Interrupt Flags*/
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS13), ~0);
+	high_speed_enable(true);
+}
+
 int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
-struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
+		      struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
 {
 	int ret = 0;
 
 	ret = cdns_reset();
-	if (ret != 0) {
+	if (ret != 0U) {
 		ERROR("Program phy reg init failed");
 		return ret;
 	}
 
 	ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (ret != 0) {
+	if (ret != 0U) {
 		ERROR("Program phy reg init failed");
 		return ret;
 	}
+	sdmmc_host_init(0);
+	cdns_host_set_clk(100000);
 
-	ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (ret != 0) {
-		ERROR("Program init for HRS reg is failed");
-		return ret;
-	}
-
-	ret = cdns_sd_card_detect();
-	if (ret != 0) {
-		ERROR("SD card does not detect");
-		return ret;
-	}
-
-	ret = cdns_vol_reset();
-	if (ret != 0) {
-		ERROR("eMMC card reset failed");
-		return ret;
-	}
-
-	ret = cdns_hc_set_clk(&cdns_params);
-	if (ret != 0) {
-		ERROR("hc set clk failed");
-		return ret;
-	}
+	sd_host_oper_mode(SD_HOST_OPR_MODE_HV4E_0_ADMA_64);
 
 	return 0;
 }
 
-void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
-{
-	uint32_t data_op = 0U;
-
-	data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
-	mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
-}
-
-void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
-{
-	uint32_t data = 0U;
-
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
-}
-
 int cdns_send_cmd(struct mmc_cmd *cmd)
 {
-	uint32_t op = 0, ret = 0;
-	uint8_t write_value = 0, prev_val = 0;
-	uint32_t value;
-	int32_t timeout;
-	uint32_t cmd_indx;
-	uint32_t status = 0, srs15_val = 0, srs11_val = 0;
+	uint32_t cmd_flags = 0;
+	uint32_t timeout = 0;
 	uint32_t status_check = 0;
+	uint32_t mode = 0;
+	uint32_t status;
 
 	assert(cmd);
-	cmd_indx = (cmd->cmd_idx) << COM_IDX;
 
-	if (data_cmd) {
-		switch (cmd->cmd_idx) {
-		case SD_SWITCH:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | DT_WIDTH;
-			prev_val = ADMA2_32 | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			srs15_val = BIT_AD_64 | HV4E | V18SE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
+	cmd_flags = CDNS_HOST_CMD_INHIBIT | CDNS_HOST_DATA_INHIBIT;
 
-		case SD_WRITE_SINGLE_BLOCK:
-		case SD_READ_SINGLE_BLOCK:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
-			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
-			break;
-
-		case SD_WRITE_MULTIPLE_BLOCK:
-		case SD_READ_MULTIPLE_BLOCK:
-			op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
-			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
-			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
-			break;
-
-		case SD_APP_SEND_SCR:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | LEDC;
-			prev_val = LEDC;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = BIT_AD_64 | HV4E | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_SEND_IF_COND:
-			op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		default:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			op = 0;
-			break;
-		}
-	} else {
-		switch (cmd->cmd_idx) {
-		case SD_GO_IDLE_STATE:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_ALL_SEND_CID:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E | V18SE;
-			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_SEND_IF_COND:
-			op = CMD_IDX_CHK_ENABLE;
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_STOP_TRANSMISSION:
-			op = CMD_STOP_ABORT_CMD;
-			break;
-
-		case SD_SEND_STATUS:
-			break;
-
-		case 1:
-			cmd->cmd_arg = 0;
-			break;
-
-		case SD_SELECT_CARD:
-			op = MULTI_BLK_READ;
-			break;
-
-		case SD_APP_CMD:
-		default:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			op = 0;
-			break;
-		}
-	}
-
-	switch (cmd->resp_type) {
-	case MMC_RESPONSE_NONE:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
-		break;
-
-	case MMC_RESPONSE_R2:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
-			RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
-		break;
-
-	case MMC_RESPONSE_R3:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
-			RES_TYPE_SEL_48;
-		break;
-
-	case MMC_RESPONSE_R1:
-		if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
-			== SD_WRITE_MULTIPLE_BLOCK)) {
-			op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
-			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		} else {
-			op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
-			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		}
-		break;
-
-	default:
-		op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
-			RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		break;
+	if ((cmd->cmd_idx == SD_STOP_TRANSMISSION) && (!data_cmd)) {
+		cmd_flags &= ~CDNS_HOST_DATA_INHIBIT;
 	}
 
 	timeout = TIMEOUT;
 	do {
 		udelay(100);
-		ret = cdns_busy();
 		if (--timeout <= 0) {
 			udelay(50);
+			NOTICE("Timeout occur data and cmd line %x\n",
+			 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09));
 			panic();
 		}
-	} while (ret);
+	} while ((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & (cmd_flags)));
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, 0xFFFFFFFF);
+	cmd_flags = 0;
+	cmd_flags = (cmd->cmd_idx) << COM_IDX;
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
-	if (cmd_indx == 1)
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
-	else
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
-
-	timeout = TIMEOUT;
-	do {
-		udelay(500);
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
-	} while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
-
-	timeout = TIMEOUT;
-
-	if (data_cmd) {
-		data_cmd = false;
-		do {
-			udelay(250);
-		} while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
+	if ((cmd->resp_type & MMC_RSP_136) != 0) {
+		cmd_flags |= RES_TYPE_SEL_136;
+	} else if (((cmd->resp_type & MMC_RSP_48) != 0) &&
+			((cmd->resp_type & MMC_RSP_BUSY) != 0)) {
+		cmd_flags |= RES_TYPE_SEL_48_B;
+	} else if ((cmd->resp_type & MMC_RSP_48) != 0) {
+		cmd_flags |= RES_TYPE_SEL_48;
+	} else {
+		cmd_flags &= ~RES_TYPE_SEL_NO;
 	}
 
-	status_check = value & SRS12_ERR_MASK;
+	if ((cmd->resp_type & MMC_RSP_CRC) != 0) {
+		cmd_flags |= CMD_CHECK_RESP_CRC;
+	}
+
+	if ((cmd->resp_type & MMC_RSP_CMD_IDX) != 0) {
+		cmd_flags |= CMD_IDX_CHK_ENABLE;
+	}
+
+	if ((cmd->cmd_idx == MMC_ACMD(51)) || (cmd->cmd_idx == MMC_CMD(17)) ||
+		(cmd->cmd_idx == MMC_CMD(18)) || (cmd->cmd_idx == MMC_CMD(24)) ||
+		(cmd->cmd_idx == MMC_CMD(25))) {
+		mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+		cmd_flags |= DATA_PRESENT;
+		mode |= BLK_CNT_EN;
+
+		mode |= (DMA_ENABLED);
+		if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+		(cmd->cmd_idx == SD_READ_MULTIPLE_BLOCK)) {
+			mode |= (MULTI_BLK_READ);
+		} else {
+			mode &= ~(MULTI_BLK_READ);
+		}
+		if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+		(cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK)) {
+			mode &= ~CMD_READ;
+		} else {
+			mode |= CMD_READ;
+		}
+		mmio_write_16(cdns_params.reg_base + SDHC_CDNS_SRS03, mode);
+
+	} else {
+		mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+	}
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS02, cmd->cmd_arg);
+	mmio_write_16((cdns_params.reg_base + CICE_OFFSET),
+		SDHCI_MAKE_CMD(cmd->cmd_idx, cmd_flags));
+
+	timeout = TIMEOUT;
+
+	do {
+		udelay(CDNS_TIMEOUT);
+		status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12);
+	} while (((status & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
+	status_check = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12) & 0xffff8000;
 	if (status_check != 0U) {
-		ERROR("SD host controller send command failed, SRS12 = %x", status);
+		timeout = TIMEOUT;
+		ERROR("SD host controller send command failed, SRS12 = %x", status_check);
 		return -1;
 	}
 
-	if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
-		cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
-		if (op & RES_TYPE_SEL_136) {
-			cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
-			cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
-			cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
+	if (!((cmd_flags & RES_TYPE_SEL_NO) == 0)) {
+		cmd->resp_data[0] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS04);
+		if ((cmd_flags & RES_TYPE_SEL_NO) == RES_TYPE_SEL_136) {
+			cmd->resp_data[1] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS05);
+			cmd->resp_data[2] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS06);
+			cmd->resp_data[3] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS07);
+			/* 136-bit: RTS=01b, Response field R[127:8] - RESP3[23:0],
+			 * RESP2[31:0], RESP1[31:0], RESP0[31:0]
+			 * Subsystem expects 128 bits response but cadence SDHC sends
+			 * 120 bits response from R[127:8]. Bits manupulation to address
+			 * the correct responses for the 136 bit response type.
+			 */
+			cmd->resp_data[3] = ((cmd->resp_data[3] << 8) |
+						((cmd->resp_data[2] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[2] = ((cmd->resp_data[2] << 8) |
+						((cmd->resp_data[1] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[1] = ((cmd->resp_data[1] << 8) |
+						((cmd->resp_data[0] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[0] = (cmd->resp_data[0] << 8);
 		}
 	}
 
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
+
 	return 0;
 }
+
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uint64_t buf,
+			  size_t size)
+{
+	uint32_t full_desc_cnt = 0;
+	uint32_t non_full_desc_cnt = 0;
+	uint64_t desc_address;
+	uint32_t block_count;
+	uint32_t transfer_block_size;
+
+	full_desc_cnt = (size / PAGE_BUFFER_LEN);
+	non_full_desc_cnt = (size % PAGE_BUFFER_LEN);
+	for (int i = 0; i < full_desc_cnt; i++) {
+		desc_ptr->attr = (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_VALID);
+		desc_ptr->len = 0; // 0 means 64kb page size it will take
+		desc_ptr->addr_lo = 0;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+		if (non_full_desc_cnt == 0) {
+			desc_ptr->attr |= (ADMA_DESC_ATTR_END);
+		}
+	buf += PAGE_BUFFER_LEN;
+	}
+
+	if (non_full_desc_cnt != 0) {
+		desc_ptr->attr =
+		(ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_END | ADMA_DESC_ATTR_VALID);
+		desc_ptr->addr_lo = buf & 0xffffffff;
+		desc_ptr->len = size;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+		desc_address = (uint64_t)desc_ptr;
+		if (size > MMC_MAX_BLOCK_LEN) {
+			transfer_block_size = MMC_MAX_BLOCK_LEN;
+		} else {
+			transfer_block_size = size;
+		}
+
+		block_count = (size / transfer_block_size);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS01,
+				((transfer_block_size << BLOCK_SIZE) | SDMA_BUF |
+				(block_count << BLK_COUNT_CT)));
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS22,
+				(uint32_t)desc_address & 0xFFFFFFFF);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS23,
+				(uint32_t)(desc_address >> 32 & 0xFFFFFFFF));
+	}
+}
+
+int cdns_mmc_init(struct cdns_sdmmc_params *params,
+		  struct mmc_device_info *info)
+{
+
+	int result = 0;
+
+	assert((params != NULL) &&
+		((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+		((params->desc_size & MMC_BLOCK_MASK) == 0) &&
+		((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
+		((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
+		(params->desc_size > 0) &&
+		(params->clk_rate > 0) &&
+		((params->bus_width == MMC_BUS_WIDTH_1) ||
+		(params->bus_width == MMC_BUS_WIDTH_4) ||
+		(params->bus_width == MMC_BUS_WIDTH_8)));
+
+	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
+
+	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (result < 0) {
+		return result;
+	}
+
+	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
+	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
+
+	result = mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
+			params->flags, info);
+
+	return result;
+}
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index a3fd7bf..bdbbbf6 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,3 +80,25 @@
 
 	timer_ops = ops_ptr;
 }
+
+/***********************************************************
+ * Initialize the timer in us
+ ***********************************************************/
+uint64_t timeout_init_us(uint32_t usec)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_init_us != NULL);
+
+	return timer_ops->timeout_init_us(usec);
+}
+
+/***********************************************************
+ * check the given timeout elapsed or not.
+ ***********************************************************/
+bool timeout_elapsed(uint64_t cnt)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_elapsed != NULL);
+
+	return timer_ops->timeout_elapsed(cnt);
+}
diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c
index ca522e0..0407e38 100644
--- a/drivers/delay_timer/generic_delay_timer.c
+++ b/drivers/delay_timer/generic_delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -18,7 +18,26 @@
 
 static timer_ops_t ops;
 
-static uint32_t get_timer_value(void)
+static uint64_t timeout_cnt_us2cnt(uint32_t us)
+{
+	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
+}
+
+static uint64_t generic_delay_timeout_init_us(uint32_t us)
+{
+	uint64_t cnt = timeout_cnt_us2cnt(us);
+
+	cnt += read_cntpct_el0();
+
+	return cnt;
+}
+
+static bool generic_delay_timeout_elapsed(uint64_t expire_cnt)
+{
+	return read_cntpct_el0() > expire_cnt;
+}
+
+static uint32_t generic_delay_get_timer_value(void)
 {
 	/*
 	 * Generic delay timer implementation expects the timer to be a down
@@ -31,9 +50,11 @@
 
 void generic_delay_timer_init_args(uint32_t mult, uint32_t div)
 {
-	ops.get_timer_value	= get_timer_value;
+	ops.get_timer_value	= generic_delay_get_timer_value;
 	ops.clk_mult		= mult;
 	ops.clk_div		= div;
+	ops.timeout_init_us	= generic_delay_timeout_init_us;
+	ops.timeout_elapsed	= generic_delay_timeout_elapsed;
 
 	timer_init(&ops);
 
@@ -59,4 +80,3 @@
 
 	generic_delay_timer_init_args(mult, div);
 }
-
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index 9b57607..235b988 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -7,6 +7,7 @@
 #include <common/debug.h>
 #include <drivers/clk.h>
 #include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <s32cc-clk-ids.h>
 #include <s32cc-clk-modules.h>
 #include <s32cc-clk-regs.h>
@@ -1464,7 +1465,39 @@
 	return 0;
 }
 
-void s32cc_clk_register_drv(void)
+static int s32cc_clk_mmap_regs(const struct s32cc_clk_drv *drv)
+{
+	const uintptr_t base_addrs[11] = {
+		drv->fxosc_base,
+		drv->armpll_base,
+		drv->periphpll_base,
+		drv->armdfs_base,
+		drv->cgm0_base,
+		drv->cgm1_base,
+		drv->cgm5_base,
+		drv->ddrpll_base,
+		drv->mc_me,
+		drv->mc_rgm,
+		drv->rdc,
+	};
+	size_t i;
+	int ret;
+
+	for (i = 0U; i < ARRAY_SIZE(base_addrs); i++) {
+		ret = mmap_add_dynamic_region(base_addrs[i], base_addrs[i],
+					      PAGE_SIZE,
+					      MT_DEVICE | MT_RW | MT_SECURE);
+		if (ret != 0) {
+			ERROR("Failed to map clock module 0x%" PRIuPTR "\n",
+			      base_addrs[i]);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+int s32cc_clk_register_drv(bool mmap_regs)
 {
 	static const struct clk_ops s32cc_clk_ops = {
 		.enable		= s32cc_clk_enable,
@@ -1475,7 +1508,19 @@
 		.get_parent	= s32cc_clk_get_parent,
 		.set_parent	= s32cc_clk_set_parent,
 	};
+	const struct s32cc_clk_drv *drv;
 
 	clk_register(&s32cc_clk_ops);
+
+	drv = get_drv();
+	if (drv == NULL) {
+		return -EINVAL;
+	}
+
+	if (mmap_regs) {
+		return s32cc_clk_mmap_regs(drv);
+	}
+
+	return 0;
 }
 
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 02b9df9..f001568 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -180,11 +180,14 @@
 	return ret;
 }
 
-int s32cc_init_early_clks(void)
+int s32cc_init_core_clocks(void)
 {
 	int ret;
 
-	s32cc_clk_register_drv();
+	ret = s32cc_clk_register_drv(false);
+	if (ret != 0) {
+		return ret;
+	}
 
 	ret = setup_fxosc();
 	if (ret != 0) {
@@ -206,6 +209,18 @@
 		return ret;
 	}
 
+	return ret;
+}
+
+int s32cc_init_early_clks(void)
+{
+	int ret;
+
+	ret = s32cc_clk_register_drv(true);
+	if (ret != 0) {
+		return ret;
+	}
+
 	ret = setup_periph_pll();
 	if (ret != 0) {
 		return ret;
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index 66662c1..1529dc0 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -149,6 +149,9 @@
 static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U };
 static uint64_t rcar_image_number = { 0U };
 static uint32_t rcar_cert_load = { 0U };
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+static uint32_t rcar_image_offset = 0U;
+#endif
 
 static io_type_t device_type_rcar(void)
 {
@@ -196,8 +199,10 @@
 
 		*offset = rcar_image_header[addr];
 
-		if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
-			*offset += 0x800000;
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+		*offset += rcar_image_offset;
+#endif
+
 		*cert = RCAR_CERT_SIZE;
 		*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
 		*cert += RCAR_SDRAM_certESS;
@@ -499,6 +504,15 @@
 	 */
 	offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER :
 	    RCAR_FLASH_CERT_HEADER;
+
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+	rcar_image_offset = 0;
+	if ((name == FLASH_DEV_ID) &&
+	    (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)) {
+		rcar_image_offset = 0x800000;
+	}
+#endif
+
 	rc = io_seek(handle, IO_SEEK_SET, offset);
 	if (rc != IO_SUCCESS) {
 		WARN("Firmware Image Package header failed to seek\n");
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
index a0712b5..e5c8258 100644
--- a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
@@ -761,17 +761,9 @@
 {
 	uint16_t loopvector;
 	uint16_t pllbypass_dat = 0U;
-	uint16_t skipddc_dat = 0U;	/*
-					 * Set to vector offset based on frequency to disable dram
-					 * drift compensation.
-					 */
 
 	pllbypass_dat |= (uint16_t)config->uib.pllbypass;
 
-	if (config->uib.frequency < 333U) {
-		skipddc_dat |= 0x5U;
-	}
-
 	for (loopvector = 0U; loopvector < 8U; loopvector++) {
 		uint16_t dfifreqxlat_dat;
 		uintptr_t reg = (uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER |
@@ -799,6 +791,15 @@
 		}
 #else /* STM32MP_LPDDR4_TYPE */
 		if (loopvector == 0U) {
+			uint16_t skipddc_dat = 0U;	/*
+							 * Set to vector offset based on frequency
+							 * to disable dram drift compensation.
+							 */
+
+			if (config->uib.frequency < 333U) {
+				skipddc_dat |= 0x5U;
+			}
+
 			/*
 			 * Retrain & Relock DfiFreq = 00,01,02,03)  Use StartVec 0 (pll_enabled) or
 			 * StartVec 1 (pll_bypassed).
diff --git a/fdts/rd1ae.dts b/fdts/rd1ae.dts
index 3060b5a..26eaa65 100644
--- a/fdts/rd1ae.dts
+++ b/fdts/rd1ae.dts
@@ -255,10 +255,25 @@
 		#size-cells = <2>;
 		ranges;
 
+		timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0 0x10000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			clock-frequency = <250000000>;
+			ranges;
+
+			frame@2a830000 {
+				frame-number = <0>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+		};
+
 		gic: interrupt-controller@30000000 {
 			compatible = "arm,gic-v3";
 			reg = <0x0 0x30000000 0 0x10000>,	// GICD
-				  <0x0 0x301c0000 0 0x8000000>;	// GICR
+				  <0x0 0x301c0000 0 0x400000>;	// GICR
 			#interrupt-cells = <3>;
 			#address-cells = <2>;
 			#size-cells = <2>;
@@ -410,7 +425,7 @@
 		method = "smc";
 		cpu_suspend = <0xc4000001>;
 		cpu_off = <0x84000002>;
-		cpu_on = <0x84000003>;
+		cpu_on = <0xc4000003>;
 	};
 
 };
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index d85221b..fe5f464 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -194,6 +194,7 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
+		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
 		CLK_CKPER_HSE
@@ -242,6 +243,7 @@
 		DIV(DIV_APB3, 1)
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
 		DIV(DIV_MCO1, 0)
 		DIV(DIV_MCO2, 0)
 	>;
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 12846db..46ef0f0 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -195,7 +195,7 @@
 		CLK_MCU_PLL3P
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
-		CLK_MCO2_PLL4P
+		CLK_MCO2_PLL4
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index bac9e05..3115a00 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -198,6 +198,7 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
+		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
 		CLK_CKPER_HSE
@@ -246,6 +247,7 @@
 		DIV(DIV_APB3, 1)
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
 		DIV(DIV_MCO1, 0)
 		DIV(DIV_MCO2, 0)
 	>;
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index e250e3f..e6662d0 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -31,6 +31,7 @@
 			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
 			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
 			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
 			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
 		};
diff --git a/fdts/stm32mp25-bl31.dtsi b/fdts/stm32mp25-bl31.dtsi
new file mode 100644
index 0000000..fa63f63
--- /dev/null
+++ b/fdts/stm32mp25-bl31.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+	soc@0 {
+		rifsc@42080000 {
+			/delete-node/ mmc@48220000;
+			/delete-node/ mmc@48230000;
+		};
+	};
+};
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
index 102980d..2f83f24 100644
--- a/fdts/stm32mp25-fw-config.dtsi
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -31,6 +31,10 @@
 			id = <BL31_IMAGE_ID>;
 		};
 
+		soc_fw-config {
+			id = <SOC_FW_CONFIG_ID>;
+		};
+
 		tos_fw {
 			id = <BL32_IMAGE_ID>;
 		};
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
index e41c6b9..5bfcf8d 100644
--- a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
@@ -11,6 +11,10 @@
 
 / {
 	dtb-registry {
+		soc_fw-config {
+			load-address = <0x0 0x81ff0000>;
+			max-size = <0x10000>;
+		};
 		tos_fw {
 			load-address = <0x0 0x82000000>;
 			max-size = <0x2000000>;
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index 735d429..691a3b8 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -387,7 +387,7 @@
 	soc_uartclk: uartclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <UARTCLK_FREQ>;
+		clock-frequency = <TC_UARTCLK>;
 		clock-output-names = "uartclk";
 	};
 
@@ -405,34 +405,50 @@
 	dpu_aclk: dpu_aclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-frequency = <LCD_TIMING_CLK>;
 		clock-output-names = "fpga:dpu_aclk";
 	};
 
 	dpu_pixel_clk: dpu-pixel-clk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-frequency = <LCD_TIMING_CLK>;
 		clock-output-names = "pxclk";
 	};
 #endif /* !TC_DPU_USE_SCMI_CLK */
 
+#if TC_DPU_USE_SIMPLE_PANEL
+	vpanel {
+		compatible = "panel-dpi";
+		post-init-providers = <&pl0>;
+		port {
+			lcd_in: endpoint {
+				remote-endpoint = <&dp_pl0_out0>;
+			};
+		};
+
+		panel-timing {
+			LCD_TIMING;
+		};
+	};
+
+#else
 	vencoder {
 		compatible = "drm,virtual-encoder";
 		port {
-			vencoder_in: endpoint {
+			lcd_in: endpoint {
 				remote-endpoint = <&dp_pl0_out0>;
 			};
 		};
 
 		display-timings {
 			timing-panel {
-				VENCODER_TIMING;
+				LCD_TIMING;
 			};
 		};
 
 	};
-
+#endif
 	ethernet: ethernet@ETHERNET_ADDR {
 		reg = <0x0 ADDRESSIFY(ETHERNET_ADDR) 0x0 0x10000>;
 		interrupts = <GIC_SPI ETHERNET_INT IRQ_TYPE_LEVEL_HIGH 0>;
@@ -575,7 +591,7 @@
 				port@0 {
 					reg = <0>;
 					dp_pl0_out0: endpoint {
-						remote-endpoint = <&vencoder_in>;
+						remote-endpoint = <&lcd_in>;
 					};
 				};
 			};
diff --git a/fdts/tc-fpga.dtsi b/fdts/tc-fpga.dtsi
index 08b9ae5..af140bb 100644
--- a/fdts/tc-fpga.dtsi
+++ b/fdts/tc-fpga.dtsi
@@ -8,9 +8,9 @@
 #define GIC_GICR_OFFSET		0x1000000
 #define UART_OFFSET		0x10000
 /* 1440x3200@120 framebuffer */
-#define VENCODER_TIMING_CLK 836000000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 836000000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <1440>;							\
 	vactive = <3200>;							\
 	hfront-porch = <136>;							\
@@ -25,6 +25,19 @@
 		stdout-path = "serial0:38400n8";
 	};
 
+#if TC_FPGA_ANDROID_IMG_IN_RAM
+	reserved-memory {
+		phram@0x880000000 {
+			/*
+			 * starting from 0x8_8000_0000 reserve some memory
+			 * android image will be side loaded to this location
+			 */
+			reg = <0x8 0x80000000  HI(ANDROID_FS_SIZE) LO(ANDROID_FS_SIZE)>
+			no-map;
+		};
+	};
+#endif /* TC_FPGA_ANDROID_IMG_IN_RAM */
+
 	ethernet: ethernet@ETHERNET_ADDR {
 		compatible = "smsc,lan9115";
 		phy-mode = "mii";
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index f57e21d..960730c 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -10,9 +10,9 @@
 
 #ifdef TC_RESOLUTION_1920X1080P60
 
-#define VENCODER_TIMING_CLK 148500000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 148500000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <1920>;							\
 	vactive = <1080>;							\
 	hfront-porch = <88>;							\
@@ -24,9 +24,9 @@
 
 #else /* TC_RESOLUTION_640X480P60 */
 
-#define VENCODER_TIMING_CLK 25175000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 25175000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <640>;							\
 	vactive = <480>;							\
 	hfront-porch = <16>;							\
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index c492274..003efdc 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -36,7 +36,6 @@
 #define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x4-pmu"
 
 #define MPAM_ADDR			0x1 0x00010000 /* 0x1_0001_0000 */
-#define UARTCLK_FREQ			5000000
 
 #define DPU_ADDR			2cc00000
 #define DPU_IRQ				69
diff --git a/fdts/tc3-4-base.dtsi b/fdts/tc3-4-base.dtsi
index 169d68f..84aa8e8 100644
--- a/fdts/tc3-4-base.dtsi
+++ b/fdts/tc3-4-base.dtsi
@@ -15,10 +15,9 @@
 #define MHU_OFFSET			0x10000
 #define MHU_MBOX_CELLS			3
 #define MHU_RX_INT_NUM			300
-#define MHU_RX_INT_NAME			"combined-mbx"
+#define MHU_RX_INT_NAME			"combined"
 
 #define MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
-#define UARTCLK_FREQ			3750000
 
 #if TARGET_FLAVOUR_FVP
 #define DPU_ADDR			4000000000
@@ -52,6 +51,31 @@
 		};
 	};
 
+	rse_mbox_db_rx: mhu@RSE_MHU_RX_ADDR {
+		compatible = MHU_RX_COMPAT;
+		reg = <0x0 ADDRESSIFY(RSE_MHU_RX_ADDR) 0x0 MHU_OFFSET>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupts = <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = MHU_RX_INT_NAME;
+#if TARGET_FLAVOUR_FPGA
+		status = "disabled";
+#endif
+	};
+
+	rse_mbox_db_tx: mhu@RSE_MHU_TX_ADDR {
+		compatible = MHU_TX_COMPAT;
+		reg = <0x0 ADDRESSIFY(RSE_MHU_TX_ADDR) 0x0 MHU_OFFSET>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupt-names = MHU_TX_INT_NAME;
+#if TARGET_FLAVOUR_FPGA
+		status = "disabled";
+#endif
+	};
+
 	gic: interrupt-controller@GIC_CTRL_ADDR {
 		ppi-partitions {
 			ppi_partition_little: interrupt-partition-0 {
@@ -80,5 +104,39 @@
 			mboxes = <&mbox_db_tx 0 0 0 &mbox_db_rx 0 0 0 &mbox_db_rx 0 0 1>;
 			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_p2a>;
 		};
+
+		rse {
+			compatible = "arm,rse";
+			mbox-names = "tx", "rx";
+			mboxes = <&rse_mbox_db_tx 0 0 0>, <&rse_mbox_db_rx 0 0 0>;
+#if TARGET_FLAVOUR_FPGA
+			status = "disabled";
+#endif
+		};
+	};
+
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
+	};
+
+	cs-pmu@0 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
+	};
+
+	cs-pmu@1 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
+	};
+
+	cs-pmu@2 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
+	};
+
+	cs-pmu@3 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
 	};
 };
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index ffe3b6d..b8fe587 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -13,6 +13,9 @@
 #define MHU_TX_ADDR			46040000 /* hex */
 #define MHU_RX_ADDR			46140000 /* hex */
 
+#define RSE_MHU_TX_ADDR			49010000 /* hex */
+#define RSE_MHU_RX_ADDR			49110000 /* hex */
+
 #define LIT_CPU_PMU_COMPATIBLE		"arm,cortex-a520-pmu"
 #define MID_CPU_PMU_COMPATIBLE		"arm,cortex-a725-pmu"
 #define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x925-pmu"
@@ -46,24 +49,13 @@
 #include "tc3-4-base.dtsi"
 
 / {
-	cs-pmu@0 {
-		compatible = "arm,coresight-pmu";
-		reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
-	};
-
-	cs-pmu@1 {
-		compatible = "arm,coresight-pmu";
-		reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
-	};
-
-	cs-pmu@2 {
-		compatible = "arm,coresight-pmu";
-		reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
-	};
-
-	cs-pmu@3 {
-		compatible = "arm,coresight-pmu";
-		reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
+	/*
+	 * The kaslr-seed node is a placeholder in DT. In the booting
+	 * sequence, it will be initialized in U-Boot and then later
+	 * used by Linux kernel.
+	 */
+	chosen {
+		kaslr-seed = <0x0 0x0>;
 	};
 
 	spe-pmu-mid {
@@ -74,11 +66,6 @@
 		status = "okay";
 	};
 
-	dsu-pmu {
-		compatible = "arm,dsu-pmu";
-		cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
-	};
-
 	ni-pmu {
 		compatible = "arm,ni-tower";
 		reg = <0x0 0x4f000000 0x0 0x4000000>;
diff --git a/fdts/tc4.dts b/fdts/tc4.dts
index 135d30a..5ab58d5 100644
--- a/fdts/tc4.dts
+++ b/fdts/tc4.dts
@@ -17,6 +17,9 @@
 #define MID_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
 #define BIG_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
 
+#define RSE_MHU_TX_ADDR			49020000 /* hex */
+#define RSE_MHU_RX_ADDR			49030000 /* hex */
+
 #define ETHERNET_ADDR			64000000
 #define ETHERNET_INT			799
 
@@ -64,4 +67,28 @@
 		interrupt-names = "IRQAW";
 		iommus = <&smmu_700 0x200>;
 	};
+
+	dsu-pmu {
+		interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+
+	cs-pmu@4 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(4) 0x0 0xffc>;
+	};
+
+	cs-pmu@5 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(5) 0x0 0xffc>;
+	};
+
+	cs-pmu@6 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(6) 0x0 0xffc>;
+	};
+
+	cs-pmu@7 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(7) 0x0 0xffc>;
+	};
 };
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index d32ead4..d2591dd 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -697,8 +697,7 @@
 /* PAR fields */
 #define PAR_F_SHIFT	U(0)
 #define PAR_F_MASK	ULL(0x1)
-#define PAR_ADDR_SHIFT	U(12)
-#define PAR_ADDR_MASK	(BIT_64(40) - ULL(1)) /* 40-bits-wide page address */
+#define PAR_ADDR_MASK	GENMASK_64(39, 12) /* 28-bits-wide page address */
 
 /*******************************************************************************
  * Definitions for system register interface to AMU for FEAT_AMUv1
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index abe34a4..e347240 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -194,5 +194,9 @@
 static inline bool is_feat_ebep_present(void) { return false; }
 __attribute__((always_inline))
 static inline bool is_feat_sebep_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_d128_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_ls64_accdata_present(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index d8ad881..4d26153 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -293,6 +293,18 @@
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_EL1		S3_0_C0_C6_1
 
+#define ID_AA64ISAR1_LS64_SHIFT		U(60)
+#define ID_AA64ISAR1_LS64_MASK		ULL(0xf)
+#define LS64_ACCDATA_IMPLEMENTED	ULL(0x3)
+#define LS64_V_IMPLEMENTED		ULL(0x2)
+#define LS64_IMPLEMENTED		ULL(0x1)
+#define LS64_NOT_IMPLEMENTED		ULL(0x0)
+
+#define ID_AA64ISAR1_SB_SHIFT		U(36)
+#define ID_AA64ISAR1_SB_MASK		ULL(0xf)
+#define SB_IMPLEMENTED			ULL(0x1)
+#define SB_NOT_IMPLEMENTED		ULL(0x0)
+
 #define ID_AA64ISAR1_GPI_SHIFT		U(28)
 #define ID_AA64ISAR1_GPI_MASK		ULL(0xf)
 #define ID_AA64ISAR1_GPA_SHIFT		U(24)
@@ -303,13 +315,12 @@
 #define ID_AA64ISAR1_APA_SHIFT		U(4)
 #define ID_AA64ISAR1_APA_MASK		ULL(0xf)
 
-#define ID_AA64ISAR1_SB_SHIFT		U(36)
-#define ID_AA64ISAR1_SB_MASK		ULL(0xf)
-#define SB_IMPLEMENTED			ULL(0x1)
-#define SB_NOT_IMPLEMENTED		ULL(0x0)
-
 /* ID_AA64ISAR2_EL1 definitions */
 #define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
+#define ID_AA64ISAR2_EL1_MOPS_SHIFT	U(16)
+#define ID_AA64ISAR2_EL1_MOPS_MASK	ULL(0xf)
+
+#define MOPS_IMPLEMENTED		ULL(0x1)
 
 /* ID_AA64PFR2_EL1 definitions */
 #define ID_AA64PFR2_EL1			S3_0_C0_C4_2
@@ -331,6 +342,7 @@
 #define PARANGE_0100	U(44)
 #define PARANGE_0101	U(48)
 #define PARANGE_0110	U(52)
+#define PARANGE_0111	U(56)
 
 #define ID_AA64MMFR0_EL1_ECV_SHIFT		U(60)
 #define ID_AA64MMFR0_EL1_ECV_MASK		ULL(0xf)
@@ -394,6 +406,10 @@
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
 
+#define ID_AA64MMFR3_EL1_D128_SHIFT		U(32)
+#define ID_AA64MMFR3_EL1_D128_MASK		ULL(0xf)
+#define D128_IMPLEMENTED			ULL(0x1)
+
 #define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
 #define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
 
@@ -406,6 +422,10 @@
 #define ID_AA64MMFR3_EL1_S1PIE_SHIFT		U(8)
 #define ID_AA64MMFR3_EL1_S1PIE_MASK		ULL(0xf)
 
+#define ID_AA64MMFR3_EL1_SCTLR2_SHIFT		U(4)
+#define ID_AA64MMFR3_EL1_SCTLR2_MASK		ULL(0xf)
+#define SCTLR2_IMPLEMENTED			ULL(1)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
@@ -433,6 +453,10 @@
 #define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
 #define GCS_IMPLEMENTED			ULL(1)
 
+#define ID_AA64PFR1_EL1_THE_SHIFT	U(48)
+#define ID_AA64PFR1_EL1_THE_MASK	ULL(0xf)
+#define THE_IMPLEMENTED			ULL(1)
+
 #define RNG_TRAP_IMPLEMENTED		ULL(0x1)
 
 /* ID_AA64PFR2_EL1 definitions */
@@ -445,6 +469,11 @@
 #define ID_AA64PFR2_EL1_MTEFAR_SHIFT		U(8)
 #define ID_AA64PFR2_EL1_MTEFAR_MASK		ULL(0xf)
 
+#define ID_AA64PFR2_EL1_FPMR_SHIFT		U(32)
+#define ID_AA64PFR2_EL1_FPMR_MASK		ULL(0xf)
+
+#define FPMR_IMPLEMENTED			ULL(0x1)
+
 #define VDISR_EL2				S3_4_C12_C1_1
 #define VSESR_EL2				S3_4_C5_C2_3
 
@@ -585,16 +614,22 @@
 #define SCR_NSE_SHIFT		U(62)
 #define SCR_FGTEN2_BIT		(UL(1) << 59)
 #define SCR_NSE_BIT		(ULL(1) << SCR_NSE_SHIFT)
+#define SCR_EnFPM_BIT		(ULL(1) << 50)
 #define SCR_GPF_BIT		(UL(1) << 48)
+#define SCR_D128En_BIT		(UL(1) << 47)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
 #define SCR_PIEN_BIT		(UL(1) << 45)
+#define SCR_SCTLR2En_BIT	(UL(1) << 44)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
+#define SCR_RCWMASKEn_BIT	(UL(1) << 42)
+#define SCR_ENTP2_SHIFT		U(41)
+#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
 #define SCR_GCSEn_BIT		(UL(1) << 39)
 #define SCR_HXEn_BIT		(UL(1) << 38)
-#define SCR_ENTP2_SHIFT		U(41)
-#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
+#define SCR_ADEn_BIT		(UL(1) << 37)
+#define SCR_EnAS0_BIT		(UL(1) << 36)
 #define SCR_AMVOFFEN_SHIFT	U(35)
 #define SCR_AMVOFFEN_BIT	(UL(1) << SCR_AMVOFFEN_SHIFT)
 #define SCR_TWEDEn_BIT		(UL(1) << 29)
@@ -623,13 +658,18 @@
 
 /* MDCR_EL3 definitions */
 #define MDCR_EBWE_BIT		(ULL(1) << 43)
+#define MDCR_E3BREC_BIT		(ULL(1) << 38)
+#define MDCR_E3BREW_BIT		(ULL(1) << 37)
 #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_SBRBE(x)		((x) << MDCR_SBRBE_SHIFT)
+#define MDCR_SBRBE_ALL		ULL(0x3)
+#define MDCR_SBRBE_NS		ULL(0x1)
 #define MDCR_NSTB(x)		((x) << 24)
 #define MDCR_NSTB_EL1		ULL(0x3)
+#define MDCR_NSTB_EL3		ULL(0x2)
 #define MDCR_NSTBE_BIT		(ULL(1) << 26)
 #define MDCR_MTPME_BIT		(ULL(1) << 28)
 #define MDCR_TDCC_BIT		(ULL(1) << 27)
@@ -646,6 +686,7 @@
 #define MDCR_SPD32_ENABLE	ULL(0x3)
 #define MDCR_NSPB(x)		((x) << 12)
 #define MDCR_NSPB_EL1		ULL(0x3)
+#define MDCR_NSPB_EL3		ULL(0x2)
 #define MDCR_NSPBE_BIT		(ULL(1) << 11)
 #define MDCR_TDOSA_BIT		(ULL(1) << 10)
 #define MDCR_TDA_BIT		(ULL(1) << 9)
@@ -1167,8 +1208,9 @@
 /* PAR_EL1 fields */
 #define PAR_F_SHIFT	U(0)
 #define PAR_F_MASK	ULL(0x1)
-#define PAR_ADDR_SHIFT	U(12)
-#define PAR_ADDR_MASK	(BIT(40) - ULL(1)) /* 40-bits-wide page address */
+
+#define PAR_D128_ADDR_MASK	GENMASK(55, 12) /* 44-bits-wide page address */
+#define PAR_ADDR_MASK		GENMASK(51, 12) /* 40-bits-wide page address */
 
 /*******************************************************************************
  * Definitions for system register interface to SPE
@@ -1473,10 +1515,32 @@
 #define TRFCR_EL1		S3_0_C1_C2_1
 
 /*******************************************************************************
+ * FEAT_THE - Translation Hardening Extension Registers
+ ******************************************************************************/
+#define RCWMASK_EL1		S3_0_C13_C0_6
+#define RCWSMASK_EL1		S3_0_C13_C0_3
+
+/*******************************************************************************
+ * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
+ ******************************************************************************/
+#define SCTLR2_EL2		S3_4_C1_C0_3
+#define SCTLR2_EL1		S3_0_C1_C0_3
+
+/*******************************************************************************
+ * FEAT_LS64_ACCDATA - LoadStore64B with status data
+ ******************************************************************************/
+#define ACCDATA_EL1		S3_0_C13_C0_5
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
 
+/*******************************************************************************
+ * FEAT_FPMR - Floating point Mode Register
+ ******************************************************************************/
+#define FPMR			S3_3_C4_C4_2
+
 /* CLUSTERPWRDN_EL1 register definitions */
 #define DSU_CLUSTER_PWR_OFF	0
 #define DSU_CLUSTER_PWR_ON	1
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index f03c9d5..1d0a2e0 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -134,6 +134,18 @@
  * +----------------------------+
  * |	FEAT_FGT2		|
  * +----------------------------+
+ * |	FEAT_THE		|
+ * +----------------------------+
+ * |	FEAT_SCTLR2		|
+ * +----------------------------+
+ * |	FEAT_D128		|
+ * +----------------------------+
+ * |	FEAT_LS64_ACCDATA	|
+ * +----------------------------+
+ * |	FEAT_FPMR		|
+ * +----------------------------+
+ * |	FEAT_MOPS		|
+ * +----------------------------+
  */
 
 __attribute__((always_inline))
@@ -262,6 +274,29 @@
 CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
 		     ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
 
+/* FEAT_THE: Translation Hardening Extension */
+CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
+		     ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
+
+/* FEAT_SCTLR2 */
+CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+		     ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
+		     ENABLE_FEAT_SCTLR2)
+
+/* FEAT_D128 */
+CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
+		     ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
+		     ENABLE_FEAT_D128)
+
+/* FEAT_FPMR */
+CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
+		     ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
+		     ENABLE_FEAT_FPMR)
+/* FEAT_MOPS */
+CREATE_FEATURE_FUNCS(feat_mops, id_aa64isar2_el1, ID_AA64ISAR2_EL1_MOPS_SHIFT,
+		     ID_AA64ISAR2_EL1_MOPS_MASK, MOPS_IMPLEMENTED,
+		     ENABLE_FEAT_MOPS)
+
 __attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void)
 {
@@ -323,8 +358,8 @@
 		     ID_AA64MMFR1_EL1_HCX_MASK, 1U, ENABLE_FEAT_HCX)
 
 /* FEAT_RNG_TRAP: Trapping support */
-CREATE_FEATURE_PRESENT(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
-		      ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED)
+CREATE_FEATURE_FUNCS(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+		      ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED, ENABLE_FEAT_RNG_TRAP)
 
 /* Return the RME version, zero if not supported. */
 CREATE_FEATURE_FUNCS(feat_rme, id_aa64pfr0_el1, ID_AA64PFR0_FEAT_RME_SHIFT,
@@ -401,6 +436,11 @@
 CREATE_FEATURE_FUNCS(feat_sme2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
 		     ID_AA64PFR1_EL1_SME_MASK, SME2_IMPLEMENTED, ENABLE_SME2_FOR_NS)
 
+/* FEAT_LS64_ACCDATA: */
+CREATE_FEATURE_FUNCS(feat_ls64_accdata, id_aa64isar1_el1, ID_AA64ISAR1_LS64_SHIFT,
+		     ID_AA64ISAR1_LS64_MASK, LS64_ACCDATA_IMPLEMENTED,
+		     ENABLE_FEAT_LS64_ACCDATA)
+
 /*******************************************************************************
  * Function to get hardware granularity support
  ******************************************************************************/
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index a892654..8b92f19 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -13,6 +13,7 @@
 #include <string.h>
 
 #include <arch.h>
+#include <lib/extensions/sysreg128.h>
 
 /**********************************************************************
  * Macros which create inline functions to read or write CPU system
@@ -263,7 +264,12 @@
 #define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
 #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
 
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(par_el1)
+#else
 DEFINE_SYSREG_RW_FUNCS(par_el1)
+#endif
+
 DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
@@ -289,6 +295,7 @@
 DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
 DEFINE_SYSREG_RW_FUNCS(sp_el1)
 DEFINE_SYSREG_RW_FUNCS(sp_el2)
+DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1)
 
 DEFINE_SYSOP_FUNC(wfi)
 DEFINE_SYSOP_FUNC(wfe)
@@ -443,13 +450,21 @@
 DEFINE_SYSREG_RW_FUNCS(tcr_el2)
 DEFINE_SYSREG_RW_FUNCS(tcr_el3)
 
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el2)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el2)
+DECLARE_SYSREG128_RW_FUNCS(vttbr_el2)
+#else
 DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
-
 DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
-
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
 DEFINE_SYSREG_RW_FUNCS(vttbr_el2)
+#endif
+
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
 
 DEFINE_SYSREG_RW_FUNCS(cptr_el2)
 DEFINE_SYSREG_RW_FUNCS(cptr_el3)
@@ -574,7 +589,6 @@
 
 /* Armv8.1 VHE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
-DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
 
 /* Armv8.2 ID Registers */
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
@@ -670,6 +684,22 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
 
+/* FEAT_THE Registers */
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(rcwmask_el1)
+DECLARE_SYSREG128_RW_FUNCS(rcwsmask_el1)
+#else
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+#endif
+
+/* FEAT_SCTLR2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+
+/* FEAT_LS64_ACCDATA Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(accdata_el1, ACCDATA_EL1)
+
 /* DynamIQ Control registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
@@ -689,6 +719,8 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
 
+DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
+
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
 
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index ec2acd5..197ea06 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -225,13 +225,6 @@
 	.endm
 
 	/*
-	 * With RAS extension executes esb instruction, else NOP
-	 */
-	.macro esb
-	.inst	0xd503221f
-	.endm
-
-	/*
 	 * Helper macro to read system register value into x0
 	 */
 	.macro	read reg:req
@@ -265,6 +258,14 @@
 	msr	SYSREG_SB, xzr
 	.endm
 
+	.macro psb_csync
+	hint #17 /* use the hint synonym for compatibility */
+	.endm
+
+	.macro tsb_csync
+	hint #18 /* use the hint synonym for compatibility */
+	.endm
+
 	/*
 	 * Macro for using speculation barrier instruction introduced by
 	 * FEAT_SB, if it's enabled.
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 60c5a0c..204625c 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -59,24 +59,18 @@
 	 * zero here but are updated ahead of transitioning to a lower EL in the
 	 * function cm_init_context_common().
 	 *
-	 * SCR_EL3.SIF: Set to one to disable instruction fetches from
-	 *  Non-secure memory.
-	 *
-	 * SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts
-	 *  to EL3 when executing at any EL.
-	 *
 	 * SCR_EL3.EEL2: Set to one if S-EL2 is present and enabled.
 	 *
 	 * NOTE: Modifying EEL2 bit along with EA bit ensures that we mitigate
 	 * against ERRATA_V2_3099206.
 	 * ---------------------------------------------------------------------
 	 */
-	mov_imm	x0, (SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT)
+	mov_imm	x0, SCR_RESET_VAL
 #if IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2
-	mrs x1, id_aa64pfr0_el1
-	and x1, x1, #(ID_AA64PFR0_SEL2_MASK << ID_AA64PFR0_SEL2_SHIFT)
-	cbz x1, 1f
-	orr x0, x0, #SCR_EEL2_BIT
+	mrs	x1, id_aa64pfr0_el1
+	and	x1, x1, #(ID_AA64PFR0_SEL2_MASK << ID_AA64PFR0_SEL2_SHIFT)
+	cbz	x1, 1f
+	orr	x0, x0, #SCR_EEL2_BIT
 #endif
 1:
 	msr	scr_el3, x0
@@ -84,22 +78,11 @@
 	/* ---------------------------------------------------------------------
 	 * Initialise MDCR_EL3, setting all fields rather than relying on hw.
 	 * Some fields are architecturally UNKNOWN on reset.
-	 *
-	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
-	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
-	 *  disabled from all ELs in Secure state.
 	 */
-	mov_imm	x0, (MDCR_EL3_RESET_VAL | MDCR_SDD_BIT)
+	mov_imm	x0, MDCR_EL3_RESET_VAL
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
-	 * Enable External Aborts and SError Interrupts now that the exception
-	 * vectors have been setup.
-	 * ---------------------------------------------------------------------
-	 */
-	msr	daifclr, #DAIF_ABT_BIT
-
-	/* ---------------------------------------------------------------------
 	 * Initialise CPTR_EL3, setting all fields rather than relying on hw.
 	 * All fields are architecturally UNKNOWN on reset.
 	 * ---------------------------------------------------------------------
@@ -107,28 +90,6 @@
 	mov_imm x0, CPTR_EL3_RESET_VAL
 	msr	cptr_el3, x0
 
-	/*
-	 * If Data Independent Timing (DIT) functionality is implemented,
-	 * always enable DIT in EL3.
-	 * First assert that the FEAT_DIT build flag matches the feature id
-	 * register value for DIT.
-	 */
-#if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
-	mrs	x0, id_aa64pfr0_el1
-	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
-#if ENABLE_FEAT_DIT > 1
-	cbz	x0, 1f
-#else
-	cmp	x0, #DIT_IMPLEMENTED
-	ASM_ASSERT(eq)
-#endif
-
-#endif /* ENABLE_ASSERTIONS */
-	mov	x0, #DIT_BIT
-	msr	DIT, x0
-1:
-#endif
 	.endm
 
 /* -----------------------------------------------------------------------------
@@ -270,6 +231,12 @@
 
 	el3_arch_init_common
 
+	/* ---------------------------------------------------------------------
+	 * Set the el3 execution context(i.e. root_context).
+	 * ---------------------------------------------------------------------
+	 */
+	setup_el3_execution_context
+
 	.if \_secondary_cold_boot
 		/* -------------------------------------------------------------
 		 * Check if this is a primary or secondary CPU cold boot.
@@ -373,7 +340,9 @@
 #endif
 
 #if defined(IMAGE_BL1) ||	\
-	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM)
+	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM) || \
+	(defined(IMAGE_BL31) && SEPARATE_RWDATA_REGION)
+
 		adrp	x0, __DATA_RAM_START__
 		add	x0, x0, :lo12:__DATA_RAM_START__
 		adrp	x1, __DATA_ROM_START__
@@ -460,4 +429,68 @@
 	end:
 	.endm
 
+/*-----------------------------------------------------------------------------
+ * Helper macro to configure EL3 registers we care about, while executing
+ * at EL3/Root world. Root world has its own execution environment and
+ * needs to have its settings configured to be independent of other worlds.
+ * -----------------------------------------------------------------------------
+ */
+	.macro setup_el3_execution_context
+
+	/* ---------------------------------------------------------------------
+	 * The following registers need to be part of separate root context
+	 * as their values are of importance during EL3 execution.
+	 * Hence these registers are overwritten to their intital values,
+	 * irrespective of whichever world they return from to ensure EL3 has a
+	 * consistent execution context throughout the lifetime of TF-A.
+	 *
+	 * DAIF.A: Enable External Aborts and SError Interrupts at EL3.
+	 *
+	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
+	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
+	 *  disabled from all ELs in Secure state.
+	 *
+	 * SCR_EL3.EA: Set to one to enable SError interrupts at EL3.
+	 *
+	 * SCR_EL3.SIF: Set to one to disable instruction fetches from
+	 *  Non-secure memory.
+	 *
+	 * PMCR_EL0.DP: Set to one so that the cycle counter,
+	 *  PMCCNTR_EL0 does not count when event counting is prohibited.
+	 *  Necessary on PMUv3 <= p7 where MDCR_EL3.{SCCD,MCCD} are not
+	 *  available.
+	 *
+	 * PSTATE.DIT: Set to one to enable the Data Independent Timing (DIT)
+	 *  functionality, if implemented in EL3.
+	 * ---------------------------------------------------------------------
+	 */
+		msr	daifclr, #DAIF_ABT_BIT
+
+		mrs 	x15, mdcr_el3
+		orr	x15, x15, #MDCR_SDD_BIT
+		msr	mdcr_el3, x15
+
+		mrs	x15, scr_el3
+		orr	x15, x15, #SCR_EA_BIT
+		orr	x15, x15, #SCR_SIF_BIT
+		msr	scr_el3, x15
+
+		mrs 	x15, pmcr_el0
+		orr	x15, x15, #PMCR_EL0_DP_BIT
+		msr	pmcr_el0, x15
+
+#if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT > 1
+		mrs	x15, id_aa64pfr0_el1
+		ubfx	x15, x15, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+		cbz	x15, 1f
+#endif
+		mov	x15, #DIT_BIT
+		msr	DIT, x15
+	1:
+#endif
+
+		isb
+	.endm
+
 #endif /* EL3_COMMON_MACROS_S */
diff --git a/include/bl32/tsp/tsp.h b/include/bl32/tsp/tsp.h
index 285bfbe..a63abf1 100644
--- a/include/bl32/tsp/tsp.h
+++ b/include/bl32/tsp/tsp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,12 +36,13 @@
  * Identifiers for various TSP services. Corresponding function IDs (whether
  * fast or yielding) are generated by macros defined below
  */
-#define TSP_ADD		0x2000
-#define TSP_SUB		0x2001
-#define TSP_MUL		0x2002
-#define TSP_DIV		0x2003
+#define TSP_ADD				0x2000
+#define TSP_SUB				0x2001
+#define TSP_MUL				0x2002
+#define TSP_DIV				0x2003
 #define TSP_HANDLE_SEL1_INTR_AND_RETURN	0x2004
-#define TSP_CHECK_DIT	0x2005
+#define TSP_CHECK_DIT			0x2005
+#define TSP_MODIFY_EL1_CTX		0x2006
 
 /*
  * Identify a TSP service from function ID filtering the last 16 bits from the
diff --git a/include/bl32/tsp/tsp_el1_context.h b/include/bl32/tsp/tsp_el1_context.h
new file mode 100644
index 0000000..64fde63
--- /dev/null
+++ b/include/bl32/tsp/tsp_el1_context.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TSP_EL1_CONTEXT_H
+#define TSP_EL1_CONTEXT_H
+
+#define TSP_CORRUPT_EL1_REGS        1
+#define TSP_RESTORE_EL1_REGS        0
+
+/* Public helper function to handle EL1 ctx registers at S-EL1(TSP) */
+void modify_el1_ctx_regs(const bool modify_option);
+
+#endif /* TSP_EL1_CONTEXT_H */
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 647ae85..2f065ec 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -168,6 +168,15 @@
 } meminfo_t;
 
 /*******************************************************************************
+ * Structure used for conveying the location and size of the heap allocated for
+ * use by the cryptography library.
+ * *****************************************************************************/
+struct crypto_heap_info {
+	void *addr;
+	size_t size;
+};
+
+/*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
 int load_auth_image(unsigned int image_id, image_info_t *image_data);
diff --git a/include/common/par.h b/include/common/par.h
new file mode 100644
index 0000000..c8d67a3
--- /dev/null
+++ b/include/common/par.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAR_H
+#define PAR_H
+
+#include<arch_features.h>
+#include<lib/extensions/sysreg128.h>
+
+static inline uint64_t get_par_el1_pa(sysreg_t par)
+{
+	uint64_t pa = par & UINT64_MAX;
+	/* PA, bits [51:12] is Output address */
+	uint64_t mask = PAR_ADDR_MASK;
+
+#if ENABLE_FEAT_D128
+	/* If D128 is in use, the PA is in the upper 64-bit word of PAR_EL1 */
+	if (is_feat_d128_supported() && (par & PAR_EL1_D128)) {
+		pa = (par >> 64) & UINT64_MAX;
+		/* PA, bits [55:12] is Output address */
+		mask = PAR_D128_ADDR_MASK;
+	}
+#endif
+	return pa & mask;
+}
+
+#endif /* PAR_H */
diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h
index 072bed5..7f71932 100644
--- a/include/drivers/arm/dcc.h
+++ b/include/drivers/arm/dcc.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2021,  Xilinx Inc.
+ * Copyright (c) 2021-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,7 @@
  * Initialize a new dcc console instance and register it with the console
  * framework.
  */
-int console_dcc_register(void);
-void console_dcc_unregister(void);
+int console_dcc_register(console_t *console);
+void console_dcc_unregister(console_t *console);
 
-#endif /* DCC */
+#endif /* DCC_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/default_mbedtls_config.h
similarity index 89%
rename from include/drivers/auth/mbedtls/mbedtls_config-3.h
rename to include/drivers/auth/mbedtls/default_mbedtls_config.h
index 6ed9397..23daf24 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/default_mbedtls_config.h
@@ -11,6 +11,11 @@
  */
 
 /*
+ * This file is compatible with versions >= 3.6.2
+ */
+#define MBEDTLS_CONFIG_VERSION         0x03060200
+
+/*
  * Key algorithms currently supported on mbed TLS libraries
  */
 #define TF_MBEDTLS_RSA			1
@@ -127,18 +132,15 @@
 #endif
 
 /*
- * Determine Mbed TLS heap size
- * 13312 = 13*1024
- * 11264 = 11*1024
- * 7168  = 7*1024
+ * Determine Mbed TLS heap size.
  */
 #if TF_MBEDTLS_USE_ECDSA
-#define TF_MBEDTLS_HEAP_SIZE		U(13312)
+#define TF_MBEDTLS_HEAP_SIZE		U(13 * 1024)
 #elif TF_MBEDTLS_USE_RSA
 #if TF_MBEDTLS_KEY_SIZE <= 2048
-#define TF_MBEDTLS_HEAP_SIZE		U(7168)
+#define TF_MBEDTLS_HEAP_SIZE		U(7 * 1024)
 #else
-#define TF_MBEDTLS_HEAP_SIZE		U(11264)
+#define TF_MBEDTLS_HEAP_SIZE		U(11 * 1024)
 #endif
 #endif
 
@@ -150,3 +152,9 @@
  * the warnings to more functions.
  */
 #define MBEDTLS_CHECK_RETURN_WARNING
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint but reduced
+ * speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
diff --git a/include/drivers/auth/mbedtls/psa_mbedtls_config.h b/include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
similarity index 78%
rename from include/drivers/auth/mbedtls/psa_mbedtls_config.h
rename to include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
index 1001d89..00b1f34 100644
--- a/include/drivers/auth/mbedtls/psa_mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
@@ -7,7 +7,7 @@
 #ifndef PSA_MBEDTLS_CONFIG_H
 #define PSA_MBEDTLS_CONFIG_H
 
-#include "mbedtls_config-3.h"
+#include "default_mbedtls_config.h"
 
 #define MBEDTLS_PSA_CRYPTO_C
 #define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
@@ -26,4 +26,12 @@
  */
 #define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
 
+/*
+ * Override heap size for PSA Crypto when RSA key size > 2048.
+ */
+#if TF_MBEDTLS_USE_RSA && TF_MBEDTLS_KEY_SIZE > 2048
+#undef TF_MBEDTLS_HEAP_SIZE
+#define TF_MBEDTLS_HEAP_SIZE        U(12 * 1024)
+#endif
+
 #endif /* PSA_MBEDTLS_CONFIG_H */
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index 8bf3b78..f8d616f 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,23 +11,26 @@
 
 #include <drivers/cadence/cdns_combo_phy.h>
 #include <drivers/mmc.h>
-#include "socfpga_plat_def.h"
 
 #if MMC_DEVICE_TYPE == 0
-#define CONFIG_DMA_ADDR_T_64BIT		0
+#define CONFIG_DMA_ADDR_T_64BIT			0
 #endif
 
-#define MMC_REG_BASE			SOCFPGA_MMC_REG_BASE
-#define COMBO_PHY_REG		0x0
-#define SDHC_EXTENDED_WR_MODE_MASK	0xFFFFFFF7
-#define SDHC_DLL_RESET_MASK	0x00000001
+#define MMC_REG_BASE				SOCFPGA_MMC_REG_BASE
+#define COMBO_PHY_REG				0x0
+#define SDHC_EXTENDED_WR_MODE_MASK		0xFFFFFFF7
+#define SDHC_DLL_RESET_MASK			0x00000001
+#define MMC_MAX_BLOCK_LEN 512U
+
 /* HRS09 */
 #define SDHC_PHY_SW_RESET			BIT(0)
-#define SDHC_PHY_INIT_COMPLETE		BIT(1)
-#define SDHC_EXTENDED_RD_MODE(x)	((x) << 2)
+#define SDHC_PHY_INIT_COMPLETE			BIT(1)
+#define SDHC_EXTENDED_RD_MODE(x)		((x) << 2)
 #define EXTENDED_WR_MODE			3
-#define SDHC_EXTENDED_WR_MODE(x)	((x) << 3)
-#define RDCMD_EN					15
+#define SDHC_EXTENDED_WR_MODE(x)		((x) << 3)
+#define RDCMD_EN				(3 << 15)
+#define PHY_SW_RESET_EN				(1 << 0)
+#define PHY_INIT_COMPLETE_BIT			(1 << 1)
 #define SDHC_RDCMD_EN(x)			((x) << 15)
 #define SDHC_RDDATA_EN(x)			((x) << 16)
 
@@ -38,9 +42,9 @@
 /* • 1111b - Reserved */
 /* • 1110b - t_sdmclk*2(27+2) */
 /* • 1101b - t_sdmclk*2(26+2) */
-#define READ_CLK					0xa << 16
-#define WRITE_CLK					0xe << 16
-#define DTC_VAL						0xE
+#define READ_CLK				0xa << 16
+#define WRITE_CLK				0xe << 16
+#define DTC_VAL					0xE
 
 /* SRS00 */
 /* System Address / Argument 2 / 32-bit block count
@@ -49,18 +53,18 @@
  * • SDMA system memory address
  * • Auto CMD23 Argument
  */
-#define SAAR						(1)
+#define SAAR					(1)
 
 /* SRS01 */
 /* Transfer Block Size
  * This field defines block size for block data transfers
  */
-#define BLOCK_SIZE					0
+#define BLOCK_SIZE				0
 
 /* SDMA Buffer Boundary
  * System address boundary can be set for SDMA engine.
  */
-#define SDMA_BUF					7 << 12
+#define SDMA_BUF				7 << 12
 
 /* Block Count For Current Transfer
  * To set the number of data blocks can be defined for next transfer
@@ -68,93 +72,108 @@
 #define BLK_COUNT_CT				16
 
 /* SRS03 */
-#define CMD_START					(U(1) << 31)
+#define CMD_START				(U(1) << 31)
 #define CMD_USE_HOLD_REG			(1 << 29)
 #define CMD_UPDATE_CLK_ONLY			(1 << 21)
 #define CMD_SEND_INIT				(1 << 15)
 #define CMD_STOP_ABORT_CMD			(4 << 22)
 #define CMD_RESUME_CMD				(2 << 22)
 #define CMD_SUSPEND_CMD				(1 << 22)
-#define DATA_PRESENT				(1 << 21)
-#define CMD_IDX_CHK_ENABLE			(1 << 20)
-#define CMD_WRITE					(0 << 4)
-#define CMD_READ					(1 << 4)
+#define DATA_PRESENT				(0x20)
+#define CMD_IDX_CHK_ENABLE			(0x10)
+#define CMD_WRITE				(0 << 4)
+#define CMD_READ				(1 << 4)
 #define	MULTI_BLK_READ				(1 << 5)
-#define RESP_ERR					(1 << 7)
-#define CMD_CHECK_RESP_CRC			(1 << 19)
-#define RES_TYPE_SEL_48				(2 << 16)
-#define RES_TYPE_SEL_136			(1 << 16)
-#define RES_TYPE_SEL_48_B			(3 << 16)
-#define RES_TYPE_SEL_NO				(0 << 16)
-#define DMA_ENABLED					(1 << 0)
-#define BLK_CNT_EN					(1 << 1)
-#define AUTO_CMD_EN					(2 << 2)
-#define COM_IDX						24
-#define ERROR_INT					(1 << 15)
-#define INT_SBE						(1 << 13)
-#define INT_HLE						(1 << 12)
-#define INT_FRUN					(1 << 11)
-#define INT_DRT						(1 << 9)
-#define INT_RTO						(1 << 8)
-#define INT_DCRC					(1 << 7)
-#define INT_RCRC					(1 << 6)
-#define INT_RXDR					(1 << 5)
-#define INT_TXDR					(1 << 4)
-#define INT_DTO						(1 << 3)
+#define RESP_ERR				(1 << 7)
+#define CMD_CHECK_RESP_CRC			(0x08)
+#define RES_TYPE_SEL_48				(0x2)
+#define RES_TYPE_SEL_136			(0x1)
+#define RES_TYPE_SEL_48_B			(0x3)
+#define RES_TYPE_SEL_NO				(0x3)
+#define DMA_ENABLED				(1 << 0)
+#define BLK_CNT_EN				(1 << 1)
+#define AUTO_CMD_EN				(2 << 2)
+#define COM_IDX					24
+#define ERROR_INT				(1 << 15)
+#define INT_SBE					(1 << 13)
+#define INT_HLE					(1 << 12)
+#define INT_FRUN				(1 << 11)
+#define INT_DRT					(1 << 9)
+#define INT_RTO					(1 << 8)
+#define INT_DCRC				(1 << 7)
+#define INT_RCRC				(1 << 6)
+#define INT_RXDR				(1 << 5)
+#define INT_TXDR				(1 << 4)
+#define INT_DTO					(1 << 3)
 #define INT_CMD_DONE				(1 << 0)
-#define TRAN_COMP					(1 << 1)
+#define TRAN_COMP				(1 << 1)
 
 /* SRS09 */
 #define STATUS_DATA_BUSY			BIT(2)
+#define CI					16
+#define CHECK_CARD				BIT(CI)
 
 /* SRS10 */
+#define BIT1					(0 << 1)
+#define BIT4					(1 << 1)
+#define BIT8					(1 << 5)
+
 /* LED Control
  * State of this bit directly drives led port of the host
  * in order to control the external LED diode
  * Default value 0 << 1
  */
-#define LEDC						BIT(0)
-#define LEDC_OFF					0 << 1
+#define LEDC					BIT(0)
+#define LEDC_OFF				(0 << 1)
 
 /* Data Transfer Width
  * Bit used to configure DAT bus width to 1 or 4
  * Default value 1 << 1
  */
-#define DT_WIDTH					BIT(1)
-#define DTW_4BIT					1 << 1
+#define DT_WIDTH				BIT(1)
+#define DTW_4BIT				(1 << 1)
 
 /* Extended Data Transfer Width
  * This bit is to enable/disable 8-bit DAT bus width mode
  * Default value 1 << 5
  */
-#define EDTW_8BIT					1 << 5
+#define EDTW_8BIT				BIT(5)
 
 /* High Speed Enable
  * Selects operating mode to Default Speed (HSE=0) or High Speed (HSE=1)
  */
-#define HS_EN						BIT(2)
+#define HS_EN					BIT(2)
 
 /* here 0 defines the 64 Kb size */
 #define MAX_64KB_PAGE				0
-#define EMMC_DESC_SIZE		(1<<20)
-
+#define EMMC_DESC_SIZE				(1<<20)
+#define DTCV_OFFSET				(0x22E)
+#define DTCV_VAL				(0xE)
+#define CICE_OFFSET				(0x20E)
+#define SRS_12_CC_EN				(1 << 0)
 /* SRS11 */
 /* Software Reset For All
  * When set to 1, the entire slot is reset
  * After completing the reset operation, SRFA bit is automatically cleared
  */
-#define SRFA						BIT(24)
+#define SRFA					BIT(24)
 
 /* Software Reset For CMD Line
  * When set to 1, resets the logic related to the command generation and response checking
  */
-#define SRCMD						BIT(25)
+#define SRCMD					BIT(25)
 
 /* Software Reset For DAT Line
  * When set to 1, resets the logic related to the data path,
  * including data buffers and the DMA logic
  */
-#define SRDAT						BIT(26)
+#define SRDAT					BIT(26)
+
+
+/* SRS12 */
+/* Error mask */
+#define SRS12_ERR_MASK				0xFFFF8000U
+#define CDNS_CSD_BYTE_MASK			0x000000FFU
 
 /* SRS15 */
 /* UHS Mode Select
@@ -165,40 +184,43 @@
  * • 011b - SDR104
  * • 100b - DDR50
  */
-#define SDR12_MODE					0 << 16
-#define SDR25_MODE					1 << 16
-#define SDR50_MODE					2 << 16
-#define SDR104_MODE					3 << 16
-#define DDR50_MODE					4 << 16
+#define SDR12_MODE				0 << 16
+#define SDR25_MODE				1 << 16
+#define SDR50_MODE				2 << 16
+#define SDR104_MODE				3 << 16
+#define DDR50_MODE				4 << 16
 /* 1.8V Signaling Enable
  * • 0 - for Default Speed, High Speed mode
  * • 1 - for UHS-I mode
  */
-#define V18SE						BIT(19)
+#define V18SE					BIT(19)
 
 /* CMD23 Enable
  * In result of Card Identification process,
  * Host Driver set this bit to 1 if Card supports CMD23
  */
-#define CMD23_EN					BIT(27)
+#define CMD23_EN				BIT(27)
 
 /* Host Version 4.00 Enable
  * • 0 - Version 3.00
  * • 1 - Version 4.00
  */
-#define HV4E						BIT(28)
+#define HV4E					BIT(28)
 /* Conf depends on SRS15.HV4E */
-#define SDMA						0 << 3
-#define ADMA2_32					2 << 3
-#define ADMA2_64					3 << 3
+#define SDMA					0 << 3
+#define ADMA2_32				2 << 3
+#define ADMA2_64				3 << 3
+#define DMA_SEL_BIT				3 << 3
+#define DMA_SEL_BIT_2				2 << 3
+#define DMA_SEL_BIT_3				3 << 3
 
 /* Preset Value Enable
  * Setting this bit to 1 triggers an automatically update of SRS11
  */
-#define PVE							BIT(31)
+#define PVE					BIT(31)
 
-#define BIT_AD_32					0 << 29
-#define BIT_AD_64					1 << 29
+#define BIT_AD_32				0 << 29
+#define BIT_AD_64				1 << 29
 
 /* SW RESET REG*/
 #define SDHC_CDNS_HRS00				(0x00)
@@ -206,7 +228,7 @@
 
 /* PHY access port */
 #define SDHC_CDNS_HRS04				0x10
-#define SDHC_CDNS_HRS04_ADDR		GENMASK(5, 0)
+#define SDHC_CDNS_HRS04_ADDR			GENMASK(5, 0)
 
 /* PHY data access port */
 #define SDHC_CDNS_HRS05				0x14
@@ -233,14 +255,51 @@
 #define SDHC_CDNS_SRS13				0x234
 #define SDHC_CDNS_SRS14				0x238
 #define SDHC_CDNS_SRS15				0x23c
+#define SDHC_CDNS_SRS16				0x240
 #define SDHC_CDNS_SRS21				0x254
 #define SDHC_CDNS_SRS22				0x258
 #define SDHC_CDNS_SRS23				0x25c
+#define SDHC_CDNS_SRS24				0x260
+#define SDHC_CDNS_SRS25				0x264
+
+/* SRS00 */
+#define SAAR					(1)
+
+/* SRS03 */
+#define CMD_START				(U(1) << 31)
+#define CMD_USE_HOLD_REG			(1 << 29)
+#define CMD_UPDATE_CLK_ONLY			(1 << 21)
+#define CMD_SEND_INIT				(1 << 15)
+#define CMD_STOP_ABORT_CMD			(4 << 22)
+#define CMD_RESUME_CMD				(2 << 22)
+#define CMD_SUSPEND_CMD				(1 << 22)
+#define DMA_ENABLED				(1 << 0)
+#define BLK_CNT_EN				(1 << 1)
+#define AUTO_CMD_EN				(2 << 2)
+#define COM_IDX					24
+#define ERROR_INT				(1 << 15)
+#define INT_SBE					(1 << 13)
+#define INT_HLE					(1 << 12)
+#define INT_FRUN				(1 << 11)
+#define INT_DRT					(1 << 9)
+#define INT_RTO					(1 << 8)
+#define INT_DCRC				(1 << 7)
+#define INT_RCRC				(1 << 6)
+#define INT_RXDR				(1 << 5)
+#define INT_TXDR				(1 << 4)
+#define INT_DTO					(1 << 3)
+#define INT_CMD_DONE				(1 << 0)
+#define TRAN_COMP				(1 << 1)
+#define CDNS_HOST_CMD_INHIBIT			(BIT(0))
+#define CDNS_HOST_DATA_INHIBIT			(BIT(1))
+#define ACE_CMD_12				(BIT(2))
+
+#define PAGE_BUFFER_LEN				(64 * 1024)
 
 /* HRS07 */
 #define SDHC_CDNS_HRS07				0x1c
 #define SDHC_IDELAY_VAL(x)			((x) << 0)
-#define SDHC_RW_COMPENSATE(x)		((x) << 16)
+#define SDHC_RW_COMPENSATE(x)			((x) << 16)
 
 /* PHY reset port */
 #define SDHC_CDNS_HRS09				0x24
@@ -254,50 +313,49 @@
 
 /* Pinmux headers will reomove after ATF driver implementation */
 #define PINMUX_SDMMC_SEL			0x0
-#define PIN0SEL						0x00
-#define PIN1SEL						0x04
-#define PIN2SEL						0x08
-#define PIN3SEL						0x0C
-#define PIN4SEL						0x10
-#define PIN5SEL						0x14
-#define PIN6SEL						0x18
-#define PIN7SEL						0x1C
-#define PIN8SEL						0x20
-#define PIN9SEL						0x24
-#define PIN10SEL					0x28
+#define PIN0SEL					0x00
+#define PIN1SEL					0x04
+#define PIN2SEL					0x08
+#define PIN3SEL					0x0C
+#define PIN4SEL					0x10
+#define PIN5SEL					0x14
+#define PIN6SEL					0x18
+#define PIN7SEL					0x1C
+#define PIN8SEL					0x20
+#define PIN9SEL					0x24
+#define PIN10SEL				0x28
 
 /* HRS16 */
 #define SDHC_WRCMD0_DLY(x)			((x) << 0)
 #define SDHC_WRCMD1_DLY(x)			((x) << 4)
 #define SDHC_WRDATA0_DLY(x)			((x) << 8)
 #define SDHC_WRDATA1_DLY(x)			((x) << 12)
-#define SDHC_WRCMD0_SDCLK_DLY(x)	((x) << 16)
-#define SDHC_WRCMD1_SDCLK_DLY(x)	((x) << 20)
-#define SDHC_WRDATA0_SDCLK_DLY(x)	((x) << 24)
-#define SDHC_WRDATA1_SDCLK_DLY(x)	((x) << 28)
+#define SDHC_WRCMD0_SDCLK_DLY(x)		((x) << 16)
+#define SDHC_WRCMD1_SDCLK_DLY(x)		((x) << 20)
+#define SDHC_WRDATA0_SDCLK_DLY(x)		((x) << 24)
+#define SDHC_WRDATA1_SDCLK_DLY(x)		((x) << 28)
 
 /* Shared Macros */
 #define SDMMC_CDN(_reg)				(SDMMC_CDN_REG_BASE + \
 								(SDMMC_CDN_##_reg))
 
 /* MMC Peripheral Definition */
-#define SOCFPGA_MMC_BLOCK_SIZE		U(8192)
-#define SOCFPGA_MMC_BLOCK_MASK		(SOCFPGA_MMC_BLOCK_SIZE - U(1))
-#define SOCFPGA_MMC_BOOT_CLK_RATE	(400 * 1000)
+#define SOCFPGA_MMC_BLOCK_MASK			(SOCFPGA_MMC_BLOCK_SIZE - U(1))
+#define SOCFPGA_MMC_BOOT_CLK_RATE		(400 * 1000)
 #define MMC_RESPONSE_NONE			0
-#define SDHC_CDNS_SRS03_VALUE		0x01020013
+#define SDHC_CDNS_SRS03_VALUE			0x01020013
 
 /* Value randomly chosen for eMMC RCA, it should be > 1 */
-#define MMC_FIX_RCA					6
+#define MMC_FIX_RCA				6
 #define RCA_SHIFT_OFFSET			16
 
-#define CMD_EXTCSD_PARTITION_CONFIG	179
-#define CMD_EXTCSD_BUS_WIDTH		183
-#define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_PARTITION_CONFIG		179
+#define CMD_EXTCSD_BUS_WIDTH			183
+#define CMD_EXTCSD_HS_TIMING			185
 #define CMD_EXTCSD_SEC_CNT			212
 
-#define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
-#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+#define PART_CFG_BOOT_PARTITION1_ENABLE		(U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS		(U(1) << 0)
 
 /* Values in EXT CSD register */
 #define MMC_BUS_WIDTH_1				U(0)
@@ -305,8 +363,8 @@
 #define MMC_BUS_WIDTH_8				U(2)
 #define MMC_BUS_WIDTH_DDR_4			U(5)
 #define MMC_BUS_WIDTH_DDR_8			U(6)
-#define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
-#define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
+#define MMC_BOOT_MODE_BACKWARD			(U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING			(U(1) << 3)
 #define MMC_BOOT_MODE_DDR			(U(2) << 3)
 
 #define EXTCSD_SET_CMD				(U(0) << 24)
@@ -315,14 +373,14 @@
 #define EXTCSD_WRITE_BYTES			(U(3) << 24)
 #define EXTCSD_CMD(x)				(((x) & 0xff) << 16)
 #define EXTCSD_VALUE(x)				(((x) & 0xff) << 8)
-#define EXTCSD_CMD_SET_NORMAL		U(1)
+#define EXTCSD_CMD_SET_NORMAL			U(1)
 
-#define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
-#define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
-#define CSD_TRAN_SPEED_MULT_SHIFT	3
+#define CSD_TRAN_SPEED_UNIT_MASK		GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK		GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT		3
 
-#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
-#define STATUS_READY_FOR_DATA		BIT(8)
+#define STATUS_CURRENT_STATE(x)			(((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA			BIT(8)
 #define STATUS_SWITCH_ERROR			BIT(7)
 #define MMC_GET_STATE(x)			(((x) >> 9) & 0xf)
 #define MMC_STATE_IDLE				0
@@ -343,12 +401,51 @@
 #define VHS_2_7_3_6_V				BIT(8)
 
 /*ADMA table component*/
-#define ADMA_DESC_ATTR_VALID		BIT(0)
+#define ADMA_DESC_ATTR_VALID			BIT(0)
 #define ADMA_DESC_ATTR_END			BIT(1)
 #define ADMA_DESC_ATTR_INT			BIT(2)
 #define ADMA_DESC_ATTR_ACT1			BIT(4)
 #define ADMA_DESC_ATTR_ACT2			BIT(5)
-#define ADMA_DESC_TRANSFER_DATA		ADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_TRANSFER_DATA			ADMA_DESC_ATTR_ACT2
+
+#define HRS_09_EXTENDED_RD_MODE			(1 << 2)
+#define HRS_09_EXTENDED_WR_MODE			(1 << 3)
+#define HRS_09_RDCMD_EN				(1 << 15)
+#define HRS_09_RDDATA_EN			(1 << 16)
+#define HRS_10_HCSDCLKADJ_VAL			(3)
+
+#define SRS11_SRFA				(1 << 24)
+#define SRS11_SRFA_CHK(x)			(x >> 24)
+#define CDNS_TIMEOUT				(5000)
+
+#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
+
+/* Card busy and present */
+#define CARD_BUSY				1
+#define CARD_NOT_BUSY				0
+
+/* 500 ms delay to read the RINST register */
+#define DELAY_MS_SRS_READ			500
+#define DELAY_RES				10
+
+/* Check DV dfi_init val=0 */
+#define IO_MASK_END_DATA			0x0
+
+/* Check DV dfi_init val=2; DDR Mode */
+#define IO_MASK_END_DATA_DDR			0x2
+#define IO_MASK_START_DATA			0x0
+#define DATA_SELECT_OE_END_DATA			0x1
+
+#define TIMEOUT					100000
+
+/* General define */
+#define SDHC_REG_MASK				UINT_MAX
+#define SD_HOST_BLOCK_SIZE			0x200
+#define DTCVVAL_DEFAULT_VAL			0xE
+#define CDMMC_DMA_MAX_BUFFER_SIZE		64*1024
+#define CDNSMMC_ADDRESS_MASK			U(0x0f)
+#define CONFIG_CDNS_DESC_COUNT			8
+#define SD_HOST_CLK				200000000
 
 enum sd_opcode {
 	SD_GO_IDLE_STATE = 0,
@@ -389,6 +486,16 @@
 	SD_APP_SEND_SCR = 51,
 };
 
+enum sd_opr_modes {
+	SD_HOST_OPR_MODE_HV4E_0_SDMA_32 = 0,
+	SD_HOST_OPR_MODE_HV4E_1_SDMA_32,
+	SD_HOST_OPR_MODE_HV4E_1_SDMA_64,
+	SD_HOST_OPR_MODE_HV4E_0_ADMA_32,
+	SD_HOST_OPR_MODE_HV4E_0_ADMA_64,
+	SD_HOST_OPR_MODE_HV4E_1_ADMA_32,
+	SD_HOST_OPR_MODE_HV4E_1_ADMA_64,
+};
+
 struct cdns_sdmmc_sdhc {
 	uint32_t	sdhc_extended_rd_mode;
 	uint32_t	sdhc_extended_wr_mode;
@@ -440,9 +547,6 @@
 	uint32_t	combophy;
 };
 
-/* read and write API */
-size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
 
 struct cdns_idmac_desc {
 	/*8 bit attribute*/
@@ -468,4 +572,8 @@
 struct cdns_sdmmc_sdhc *mmc_sdhc_reg);
 void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
 struct cdns_sdmmc_sdhc *sdhc_reg);
+int cdns_mmc_init(struct cdns_sdmmc_params *params, struct mmc_device_info *info);
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+				struct cdns_sdmmc_sdhc *sdhc_reg);
+void cdns_host_set_clk(uint32_t clk);
 #endif
diff --git a/include/drivers/delay_timer.h b/include/drivers/delay_timer.h
index 20a5543..e9fdfb7 100644
--- a/include/drivers/delay_timer.h
+++ b/include/drivers/delay_timer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,27 +25,12 @@
 	uint32_t (*get_timer_value)(void);
 	uint32_t clk_mult;
 	uint32_t clk_div;
+	uint64_t (*timeout_init_us)(uint32_t usec);
+	bool (*timeout_elapsed)(uint64_t cnt);
 } timer_ops_t;
 
-static inline uint64_t timeout_cnt_us2cnt(uint32_t us)
-{
-	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
-}
-
-static inline uint64_t timeout_init_us(uint32_t us)
-{
-	uint64_t cnt = timeout_cnt_us2cnt(us);
-
-	cnt += read_cntpct_el0();
-
-	return cnt;
-}
-
-static inline bool timeout_elapsed(uint64_t expire_cnt)
-{
-	return read_cntpct_el0() > expire_cnt;
-}
-
+uint64_t timeout_init_us(uint32_t usec);
+bool timeout_elapsed(uint64_t cnt);
 void mdelay(uint32_t msec);
 void udelay(uint32_t usec);
 void timer_init(const timer_ops_t *ops_ptr);
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
index d879f5b..632b82f 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
@@ -6,6 +6,7 @@
 #ifndef S32CC_CLK_DRV_H
 #define S32CC_CLK_DRV_H
 
+int s32cc_init_core_clocks(void);
 int s32cc_init_early_clks(void);
 
 #endif
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
index e6adecc..c6e90f0 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -5,6 +5,7 @@
 #ifndef S32CC_CLK_UTILS_H
 #define S32CC_CLK_UTILS_H
 
+#include <stdbool.h>
 #include <s32cc-clk-modules.h>
 
 struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
@@ -18,6 +19,6 @@
 struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
 int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id);
 
-void s32cc_clk_register_drv(void);
+int s32cc_clk_register_drv(bool mmap_regs);
 
 #endif /* S32CC_CLK_UTILS_H */
diff --git a/include/lib/cpus/aarch64/cortex_a720_ae.h b/include/lib/cpus/aarch64/cortex_a720_ae.h
new file mode 100644
index 0000000..c88b1f9
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a720_ae.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A720_AE_H
+#define CORTEX_A720_AE_H
+
+#define CORTEX_A720_AE_MIDR				U(0x410FD890)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_AE_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* CORTEX_A720_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_alto.h b/include/lib/cpus/aarch64/cortex_alto.h
new file mode 100644
index 0000000..1c8786a
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_alto.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_ALTO_H
+#define CORTEX_ALTO_H
+
+#define CORTEX_ALTO_MIDR					U(0x411FD900)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define CORTEX_ALTO_SVCRSM					S0_3_C4_C2_3
+#define CORTEX_ALTO_SVCRZA					S0_3_C4_C4_3
+
+#endif /* CORTEX_ALTO_H */
diff --git a/include/lib/cpus/aarch64/cortex_arcadia.h b/include/lib/cpus/aarch64/cortex_arcadia.h
new file mode 100644
index 0000000..8b74de2
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_arcadia.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_ARCADIA_H
+#define CORTEX_ARCADIA_H
+
+#define CORTEX_ARCADIA_MIDR					U(0x410FD8F0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ARCADIA_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_ARCADIA_CPUECTLR_EL1_EXTLLC_BIT			U(0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ARCADIA_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_ARCADIA_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 98294b9..5e92934 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -433,7 +433,7 @@
  *
  * _get_rev:
  *	Optional parameter that determines whether to insert a call to the CPU revision fetching
- *	procedure. Stores the result of this in the temporary register x10.
+ *	procedure. Stores the result of this in the temporary register x10 to allow for chaining
  *
  * clobbers: x0-x10 (PCS compliant)
  */
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
index 038de25..7fe43c7 100644
--- a/include/lib/el3_runtime/context_el1.h
+++ b/include/lib/el3_runtime/context_el1.h
@@ -7,6 +7,8 @@
 #ifndef CONTEXT_EL1_H
 #define CONTEXT_EL1_H
 
+#include <lib/extensions/sysreg128.h>
+
 #ifndef __ASSEMBLER__
 
 /*******************************************************************************
@@ -28,15 +30,12 @@
 	uint64_t csselr_el1;
 	uint64_t sp_el1;
 	uint64_t esr_el1;
-	uint64_t ttbr0_el1;
-	uint64_t ttbr1_el1;
 	uint64_t mair_el1;
 	uint64_t amair_el1;
 	uint64_t actlr_el1;
 	uint64_t tpidr_el1;
 	uint64_t tpidr_el0;
 	uint64_t tpidrro_el0;
-	uint64_t par_el1;
 	uint64_t far_el1;
 	uint64_t afsr0_el1;
 	uint64_t afsr1_el1;
@@ -44,6 +43,9 @@
 	uint64_t vbar_el1;
 	uint64_t mdccint_el1;
 	uint64_t mdscr_el1;
+	sysreg_t par_el1;
+	sysreg_t ttbr0_el1;
+	sysreg_t ttbr1_el1;
 } el1_common_regs_t;
 
 typedef struct el1_aarch32_regs {
@@ -107,6 +109,19 @@
 	uint64_t gcspr_el0;
 } el1_gcs_regs_t;
 
+typedef struct el1_the_regs {
+	sysreg_t rcwmask_el1;
+	sysreg_t rcwsmask_el1;
+} el1_the_regs_t;
+
+typedef struct el1_sctlr2_regs {
+	uint64_t sctlr2_el1;
+} el1_sctlr2_regs_t;
+
+typedef struct el1_ls64_regs {
+	uint64_t accdata_el1;
+} el1_ls64_regs_t;
+
 typedef struct el1_sysregs {
 
 	el1_common_regs_t common;
@@ -155,6 +170,17 @@
 	el1_gcs_regs_t gcs;
 #endif
 
+#if ENABLE_FEAT_THE
+	el1_the_regs_t the;
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+	el1_sctlr2_regs_t sctlr2;
+#endif
+
+#if ENABLE_FEAT_LS64_ACCDATA
+	el1_ls64_regs_t ls64;
+#endif
 } el1_sysregs_t;
 
 
@@ -168,6 +194,9 @@
 #define write_el1_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
 							= (uint64_t) (val))
 
+#define write_el1_ctx_common_sysreg128(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (sysreg_t) (val))
+
 #if NS_TIMER_SWITCH
 #define read_el1_ctx_arch_timer(ctx, reg)		(((ctx)->arch_timer).reg)
 #define write_el1_ctx_arch_timer(ctx, reg, val)	((((ctx)->arch_timer).reg)	\
@@ -266,6 +295,33 @@
 #define read_el1_ctx_gcs(ctx, reg)		ULL(0)
 #define write_el1_ctx_gcs(ctx, reg, val)
 #endif /* ENABLE_FEAT_GCS */
+
+#if ENABLE_FEAT_THE
+#define read_el1_ctx_the(ctx, reg)		(((ctx)->the).reg)
+#define write_el1_ctx_the_sysreg128(ctx, reg, val)	((((ctx)->the).reg)	\
+							= (sysreg_t) (val))
+#else
+#define read_el1_ctx_the(ctx, reg)		ULL(0)
+#define write_el1_ctx_the_sysreg128(ctx, reg, val)
+#endif /* ENABLE_FEAT_THE */
+
+#if ENABLE_FEAT_SCTLR2
+#define read_el1_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el1_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el1_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
+#if ENABLE_FEAT_LS64_ACCDATA
+#define read_el1_ctx_ls64(ctx, reg)		(((ctx)->ls64).reg)
+#define write_el1_ctx_ls64(ctx, reg, val)	((((ctx)->ls64).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_ls64(ctx, reg)		ULL(0)
+#define write_el1_ctx_ls64(ctx, reg, val)
+#endif /* ENABLE_FEAT_LS64_ACCDATA */
 /******************************************************************************/
 #endif /* __ASSEMBLER__ */
 
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 14c1fb6..f35a091 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -7,7 +7,10 @@
 #ifndef CONTEXT_EL2_H
 #define CONTEXT_EL2_H
 
+#include <lib/extensions/sysreg128.h>
+
 #ifndef __ASSEMBLER__
+
 /*******************************************************************************
  * EL2 Registers:
  * AArch64 EL2 system register context structure for preserving the
@@ -40,12 +43,12 @@
 	uint64_t sp_el2;
 	uint64_t tcr_el2;
 	uint64_t tpidr_el2;
-	uint64_t ttbr0_el2;
 	uint64_t vbar_el2;
 	uint64_t vmpidr_el2;
 	uint64_t vpidr_el2;
 	uint64_t vtcr_el2;
-	uint64_t vttbr_el2;
+	sysreg_t vttbr_el2;
+	sysreg_t ttbr0_el2;
 } el2_common_regs_t;
 
 typedef struct el2_mte2_regs {
@@ -75,7 +78,7 @@
 
 typedef struct el2_vhe_regs {
 	uint64_t contextidr_el2;
-	uint64_t ttbr1_el2;
+	sysreg_t ttbr1_el2;
 } el2_vhe_regs_t;
 
 typedef struct el2_ras_regs {
@@ -135,6 +138,10 @@
 	uint64_t mpamvpmv_el2;
 } el2_mpam_regs_t;
 
+typedef struct el2_sctlr2_regs {
+	uint64_t sctlr2_el2;
+} el2_sctlr2_regs_t;
+
 typedef struct el2_sysregs {
 
 	el2_common_regs_t common;
@@ -203,6 +210,10 @@
 	el2_mpam_regs_t mpam;
 #endif
 
+#if ENABLE_FEAT_SCTLR2
+	el2_sctlr2_regs_t sctlr2;
+#endif
+
 } el2_sysregs_t;
 
 /*
@@ -214,6 +225,9 @@
 #define write_el2_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
 							= (uint64_t) (val))
 
+#define write_el2_ctx_common_sysreg128(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (sysreg_t) (val))
+
 #if ENABLE_FEAT_MTE2
 #define read_el2_ctx_mte2(ctx, reg)		(((ctx)->mte2).reg)
 #define write_el2_ctx_mte2(ctx, reg, val)	((((ctx)->mte2).reg)	\
@@ -254,9 +268,12 @@
 #define read_el2_ctx_vhe(ctx, reg)		(((ctx)->vhe).reg)
 #define write_el2_ctx_vhe(ctx, reg, val)	((((ctx)->vhe).reg)	\
 							= (uint64_t) (val))
+#define write_el2_ctx_vhe_sysreg128(ctx, reg, val)	((((ctx)->vhe).reg)	\
+							= (sysreg_t) (val))
 #else
 #define read_el2_ctx_vhe(ctx, reg)		ULL(0)
 #define write_el2_ctx_vhe(ctx, reg, val)
+#define write_el2_ctx_vhe_sysreg128(ctx, reg, val)
 #endif /* ENABLE_FEAT_VHE */
 
 #if ENABLE_FEAT_RAS
@@ -358,6 +375,15 @@
 #define write_el2_ctx_mpam(ctx, reg, val)
 #endif /* CTX_INCLUDE_MPAM_REGS */
 
+#if ENABLE_FEAT_SCTLR2
+#define read_el2_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el2_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
 /******************************************************************************/
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 2c7b619..8b54806 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,8 +59,19 @@
 #define CPU_DATA_CRASH_BUF_END		CPU_DATA_CRASH_BUF_OFFSET
 #endif
 
+/* buffer space for EHF data is sizeof(pe_exc_data_t) */
+#define CPU_DATA_EHF_DATA_SIZE		8
+#define CPU_DATA_EHF_DATA_BUF_OFFSET	CPU_DATA_CRASH_BUF_END
+
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+#define CPU_DATA_EHF_DATA_BUF_END	(CPU_DATA_EHF_DATA_BUF_OFFSET + \
+						CPU_DATA_EHF_DATA_SIZE)
+#else
+#define CPU_DATA_EHF_DATA_BUF_END	CPU_DATA_EHF_DATA_BUF_OFFSET
+#endif	/* EL3_EXCEPTION_HANDLING */
+
 /* cpu_data size is the data size rounded up to the platform cache line size */
-#define CPU_DATA_SIZE			(((CPU_DATA_CRASH_BUF_END + \
+#define CPU_DATA_SIZE			(((CPU_DATA_EHF_DATA_BUF_END + \
 					CACHE_WRITEBACK_GRANULE - 1) / \
 						CACHE_WRITEBACK_GRANULE) * \
 							CACHE_WRITEBACK_GRANULE)
@@ -68,7 +79,7 @@
 #if ENABLE_RUNTIME_INSTRUMENTATION
 /* Temporary space to store PMF timestamps from assembly code */
 #define CPU_DATA_PMF_TS_COUNT		1
-#define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_CRASH_BUF_END
+#define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_EHF_DATA_BUF_END
 #define CPU_DATA_PMF_TS0_IDX		0
 #endif
 
@@ -159,6 +170,12 @@
 	assert_cpu_data_crash_stack_offset_mismatch);
 #endif
 
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+CASSERT(CPU_DATA_EHF_DATA_BUF_OFFSET == __builtin_offsetof
+	(cpu_data_t, ehf_data),
+	assert_cpu_data_ehf_stack_offset_mismatch);
+#endif
+
 CASSERT(CPU_DATA_SIZE == sizeof(cpu_data_t),
 		assert_cpu_data_size_mismatch);
 
diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h
index cbd8ecc..4419f15 100644
--- a/include/lib/el3_runtime/pubsub.h
+++ b/include/lib/el3_runtime/pubsub.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,7 +73,7 @@
  */
 #define SUBSCRIBE_TO_EVENT(event, func) \
 	extern pubsub_cb_t __cb_func_##func##event __pubsub_section(event); \
-	pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = (func)
+	pubsub_cb_t __cb_func_##func##event __used __pubsub_section(event) = (func)
 
 /*
  * Iterate over subscribed handlers for a defined event. 'event' is the name of
diff --git a/include/lib/extensions/fpmr.h b/include/lib/extensions/fpmr.h
new file mode 100644
index 0000000..bc3ee9e
--- /dev/null
+++ b/include/lib/extensions/fpmr.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FPMR_H
+#define FPMR_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_FPMR
+void fpmr_enable_per_world(per_world_context_t *per_world_ctx);
+#else
+static inline void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
+{
+}
+#endif /* ENABLE_FEAT_FPMR */
+
+#endif /* FPMR_H */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 4801a22..0a41e1e 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -14,7 +14,6 @@
 void spe_enable(cpu_context_t *ctx);
 void spe_disable(cpu_context_t *ctx);
 void spe_init_el2_unused(void);
-void spe_stop(void);
 #else
 static inline void spe_enable(cpu_context_t *ctx)
 {
@@ -25,9 +24,6 @@
 static inline void spe_init_el2_unused(void)
 {
 }
-static inline void spe_stop(void)
-{
-}
 #endif /* ENABLE_SPE_FOR_NS */
 
 #endif /* SPE_H */
diff --git a/include/lib/extensions/sysreg128.h b/include/lib/extensions/sysreg128.h
new file mode 100644
index 0000000..8854856
--- /dev/null
+++ b/include/lib/extensions/sysreg128.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYSREG128_H
+#define SYSREG128_H
+
+#ifndef __ASSEMBLER__
+
+#if ENABLE_FEAT_D128
+#include <stdint.h>
+
+typedef uint128_t sysreg_t;
+
+#define PAR_EL1_D128	(((sysreg_t)(1ULL)) << (64))
+
+#define _DECLARE_SYSREG128_READ_FUNC(_name)	\
+uint128_t read_ ## _name(void);
+
+#define _DECLARE_SYSREG128_WRITE_FUNC(_name)	\
+void write_ ## _name(uint128_t v);
+
+#define DECLARE_SYSREG128_RW_FUNCS(_name)	\
+	_DECLARE_SYSREG128_READ_FUNC(_name)	\
+	_DECLARE_SYSREG128_WRITE_FUNC(_name)
+#else
+
+typedef uint64_t sysreg_t;
+
+#endif /* ENABLE_FEAT_D128 */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SYSREG128_H */
diff --git a/include/lib/hob/efi_types.h b/include/lib/hob/efi_types.h
new file mode 100644
index 0000000..071d012
--- /dev/null
+++ b/include/lib/hob/efi_types.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EFI_TYPES_H
+#define EFI_TYPES_H
+
+#include <stdint.h>
+#include <tools_share/uuid.h>
+
+typedef uint64_t efi_physical_address_t;
+
+/*****************************************************************************
+ *                            EFI_BOOT_MODE                                  *
+ *****************************************************************************/
+
+typedef uint32_t efi_boot_mode_t;
+/**
+ * EFI boot mode.
+ */
+#define EFI_BOOT_WITH_FULL_CONFIGURATION                   U(0x00)
+#define EFI_BOOT_WITH_MINIMAL_CONFIGURATION                U(0x01)
+#define EFI_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES         U(0x02)
+#define EFI_BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS  U(0x03)
+#define EFI_BOOT_WITH_DEFAULT_SETTINGS                     U(0x04)
+#define EFI_BOOT_ON_S4_RESUME                              U(0x05)
+#define EFI_BOOT_ON_S5_RESUME                              U(0x06)
+#define EFI_BOOT_WITH_MFG_MODE_SETTINGS                    U(0x07)
+#define EFI_BOOT_ON_S2_RESUME                              U(0x10)
+#define EFI_BOOT_ON_S3_RESUME                              U(0x11)
+#define EFI_BOOT_ON_FLASH_UPDATE                           U(0x12)
+#define EFI_BOOT_IN_RECOVERY_MODE                          U(0x20)
+
+/*****************************************************************************
+ *                            EFI_RESOURCE_TYPE                              *
+ *****************************************************************************/
+
+typedef uint32_t efi_resource_type_t;
+
+/**
+ * Value of EFI_RESOURCE_TYPE used in EFI_HOB_RESOURCE_DESCRIPTOR.
+ */
+#define EFI_RESOURCE_SYSTEM_MEMORY          U(0x00000000)
+#define EFI_RESOURCE_MEMORY_MAPPED_IO       U(0x00000001)
+#define EFI_RESOURCE_IO                     U(0x00000002)
+#define EFI_RESOURCE_FIRMWARE_DEVICE        U(0x00000003)
+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT  U(0x00000004)
+#define EFI_RESOURCE_MEMORY_RESERVED        U(0x00000005)
+#define EFI_RESOURCE_IO_RESERVED            U(0x00000006)
+
+/*****************************************************************************
+ *                       EFI_RESOURCE_ATTRIBUTE_TYPE                         *
+ *****************************************************************************/
+
+typedef uint32_t efi_resource_attribute_type_t;
+
+#define EFI_RESOURCE_ATTRIBUTE_PRESENT                  U(0x00000001)
+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED              U(0x00000002)
+#define EFI_RESOURCE_ATTRIBUTE_TESTED                   U(0x00000004)
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED           U(0x00000080)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED          U(0x00000100)
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED      U(0x00000200)
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT               U(0x00800000)
+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC           U(0x00000008)
+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC         U(0x00000010)
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1           U(0x00000020)
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2           U(0x00000040)
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE              U(0x00000400)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE        U(0x00000800)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE  U(0x00001000)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE     U(0x00002000)
+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO                U(0x00004000)
+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO                U(0x00008000)
+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO                U(0x00010000)
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED        U(0x00020000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE         U(0x00100000)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE        U(0x00200000)
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE    U(0x00400000)
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE              U(0x01000000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED      U(0x00040000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE    U(0x00080000)
+#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE            U(0x02000000)
+
+#endif  /* EFI_TYPES_H */
diff --git a/include/lib/hob/hob.h b/include/lib/hob/hob.h
new file mode 100644
index 0000000..120f5da
--- /dev/null
+++ b/include/lib/hob/hob.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HOB_H
+#define HOB_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/hob/efi_types.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/*****************************************************************************
+ *                            Hob Generic Header                             *
+ *****************************************************************************/
+
+/**
+ * HobType values of EFI_HOB_GENERIC_HEADER.
+ */
+#define EFI_HOB_TYPE_HANDOFF              U(0x0001)
+#define EFI_HOB_TYPE_MEMORY_ALLOCATION    U(0x0002)
+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR  U(0x0003)
+#define EFI_HOB_TYPE_GUID_EXTENSION       U(0x0004)
+#define EFI_HOB_TYPE_FV                   U(0x0005)
+#define EFI_HOB_TYPE_CPU                  U(0x0006)
+#define EFI_HOB_TYPE_MEMORY_POOL          U(0x0007)
+#define EFI_HOB_TYPE_FV2                  U(0x0009)
+#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED     U(0x000A)
+#define EFI_HOB_TYPE_UEFI_CAPSULE         U(0x000B)
+#define EFI_HOB_TYPE_FV3                  U(0x000C)
+#define EFI_HOB_TYPE_UNUSED               U(0xFFFE)
+#define EFI_HOB_TYPE_END_OF_HOB_LIST      U(0xFFFF)
+
+struct efi_hob_generic_header {
+	uint16_t hob_type;
+	uint16_t hob_length;
+	uint32_t reserved;
+};
+
+/*****************************************************************************
+ *                               PHIT Hob.                                   *
+ *****************************************************************************/
+
+#define EFI_HOB_HANDOFF_TABLE_VERSION     U(0x000a)
+
+struct efi_hob_handoff_info_table {
+	struct efi_hob_generic_header header;
+	uint32_t version;
+	efi_boot_mode_t  boot_mode;
+	efi_physical_address_t efi_memory_top;
+	efi_physical_address_t efi_memory_bottom;
+	efi_physical_address_t efi_free_memory_top;
+	efi_physical_address_t efi_free_memory_bottom;
+	efi_physical_address_t efi_end_of_hob_list;
+};
+
+/*****************************************************************************
+ *                       Resource Descriptor Hob.                            *
+ *****************************************************************************/
+
+struct efi_hob_resource_descriptor {
+	struct efi_hob_generic_header header;
+	struct efi_guid owner;
+	efi_resource_type_t resource_type;
+	efi_resource_attribute_type_t resource_attribute;
+	efi_physical_address_t physical_start;
+	uint64_t resource_length;
+};
+
+/*****************************************************************************
+ *                           Guid Extension Hob.                             *
+ *****************************************************************************/
+struct efi_hob_guid_type {
+	struct efi_hob_generic_header header;
+	struct efi_guid name;
+	/**
+	 * Guid specific data goes here.
+	 */
+};
+
+/*****************************************************************************
+ *                           Firmware Volume Hob.                            *
+ *****************************************************************************/
+struct efi_hob_firmware_volume {
+	struct efi_hob_generic_header header;
+	efi_physical_address_t base_address;
+	uint64_t length;
+	/**
+	 * Guid specific data goes here.
+	 */
+};
+
+/*****************************************************************************
+ *                              Interfaces.                                  *
+ *****************************************************************************/
+
+struct efi_hob_handoff_info_table *
+create_hob_list(
+		efi_physical_address_t efi_memory_begin, size_t efi_memory_length,
+		efi_physical_address_t efi_free_memory_bottom, size_t efi_free_memory_length);
+
+int create_resource_descriptor_hob(
+		struct efi_hob_handoff_info_table *hob_table,
+		efi_resource_type_t resource_type,
+		efi_resource_attribute_type_t resource_attribute,
+		efi_physical_address_t phy_addr_start,
+		uint64_t resource_length);
+
+int create_guid_hob(struct efi_hob_handoff_info_table *hob_table,
+		struct efi_guid *guid, uint16_t data_length, void **data);
+
+int create_fv_hob(struct efi_hob_handoff_info_table *hob_table,
+		efi_physical_address_t base_addr, uint64_t size);
+
+#endif /* HOB_H */
diff --git a/include/lib/hob/hob_guid.h b/include/lib/hob/hob_guid.h
new file mode 100644
index 0000000..65d3dbf
--- /dev/null
+++ b/include/lib/hob/hob_guid.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HOB_GUID_H
+#define HOB_GUID_H
+
+#include <lib/hob/efi_types.h>
+
+/**
+ * Guid used for creating StandaloneMm related information.
+ */
+
+#define MM_PEI_MMRAM_MEMORY_RESERVE_GUID                                        \
+{                                                                               \
+	0x0703f912, 0xbf8d, 0x4e2a, {0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 } \
+}
+
+#define MM_NS_BUFFER_GUID                                                       \
+{                                                                               \
+	0xf00497e3, 0xbfa2, 0x41a1, {0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 } \
+}
+
+#define MM_MP_INFORMATION_GUID                                                  \
+{                                                                               \
+	0xba33f15d, 0x4000, 0x45c1, {0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57, 0xe3}  \
+}
+
+#endif /* HOB_GUID_H */
diff --git a/include/lib/hob/mmram.h b/include/lib/hob/mmram.h
new file mode 100644
index 0000000..b269c64
--- /dev/null
+++ b/include/lib/hob/mmram.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef MMRAM_H
+#define MMRAM_H
+
+#include <lib/hob/efi_types.h>
+
+/**
+ * MMRAM states and capabilities
+ * See UEFI Platform Initialization Specification Version 1.8, IV-5.3.5
+ */
+#define EFI_MMRAM_OPEN                U(0x00000001)
+#define EFI_MMRAM_CLOSED              U(0x00000002)
+#define EFI_MMRAM_LOCKED              U(0x00000004)
+#define EFI_CACHEABLE                 U(0x00000008)
+#define EFI_ALLOCATED                 U(0x00000010)
+#define EFI_NEEDS_TESTING             U(0x00000020)
+#define EFI_NEEDS_ECC_INITIALIZATION  U(0x00000040)
+
+#define EFI_SMRAM_OPEN    EFI_MMRAM_OPEN
+#define EFI_SMRAM_CLOSED  EFI_MMRAM_CLOSED
+#define EFI_SMRAM_LOCKED  EFI_MMRAM_LOCKED
+
+struct efi_mmram_descriptor {
+	efi_physical_address_t physical_start;
+	efi_physical_address_t cpu_start;
+	uint64_t physical_size;
+	uint64_t region_state;
+};
+
+/**
+ * MMRAM block descriptor
+ * This definition comes from
+ *     https://github.com/tianocore/edk2/blob/master/StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
+ */
+struct efi_mmram_hob_descriptor_block {
+	uint32_t number_of_mm_reserved_regions;
+	struct efi_mmram_descriptor descriptor[];
+};
+
+#endif /* MMRAM_H */
diff --git a/include/lib/hob/mpinfo.h b/include/lib/hob/mpinfo.h
new file mode 100644
index 0000000..b80d8f1
--- /dev/null
+++ b/include/lib/hob/mpinfo.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#ifndef MPINFO_H
+#define MPINFO_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <lib/utils_def.h>
+
+/*
+ * Value used in the NumberProcessors parameter of the GetProcessorInfo function
+ */
+#define CPU_V2_EXTENDED_TOPOLOGY  UL(1 << 24)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is playing the role of BSP. If the bit is 1,
+ * then the processor is BSP. Otherwise, it is AP.
+ */
+#define PROCESSOR_AS_BSP_BIT  UL(1 << 0)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is enabled. If the bit is 1, then the
+ * processor is enabled. Otherwise, it is disabled.
+ */
+#define PROCESSOR_ENABLED_BIT  UL(1 << 1)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is healthy. If the bit is 1, then the
+ * processor is healthy. Otherwise, some fault has been detected for the processor.
+ */
+#define PROCESSOR_HEALTH_STATUS_BIT  UL(1 << 2)
+
+/*
+ * Structure that describes the physical location of a logical CPU.
+ */
+struct efi_cpu_physical_location {
+	uint32_t package;
+	uint32_t core;
+	uint32_t thread;
+};
+
+/*
+ * Structure that defines the 6-level physical location of the processor
+ */
+struct efi_cpu_physical_location2 {
+	uint32_t package;
+	uint32_t module;
+	uint32_t tile;
+	uint32_t die;
+	uint32_t core;
+	uint32_t thread;
+};
+
+union extended_processor_information {
+	/*
+	 * The 6-level physical location of the processor, including the
+	 * physical package number that identifies the cartridge, the physical
+	 * module number within package, the physical tile number within the module,
+	 * the physical die number within the tile, the physical core number within
+	 * package, and logical thread number within core.
+	 */
+	struct efi_cpu_physical_location2 location2;
+};
+
+/*
+ * Structure that describes information about a logical CPU.
+ */
+struct efi_processor_information {
+	/*
+	 * The unique processor ID determined by system hardware.
+	 */
+	uint64_t processor_id;
+
+	/*
+	 * Flags indicating if the processor is BSP or AP, if the processor is enabled
+	 * or disabled, and if the processor is healthy. Bits 3..31 are reserved and
+	 * must be 0.
+	 *
+	 * <pre>
+	 * BSP  ENABLED  HEALTH  Description
+	 * ===  =======  ======  ===================================================
+	 * 0      0       0     Unhealthy Disabled AP.
+	 * 0      0       1     Healthy Disabled AP.
+	 * 0      1       0     Unhealthy Enabled AP.
+	 * 0      1       1     Healthy Enabled AP.
+	 * 1      0       0     Invalid. The BSP can never be in the disabled state.
+	 * 1      0       1     Invalid. The BSP can never be in the disabled state.
+	 * 1      1       0     Unhealthy Enabled BSP.
+	 * 1      1       1     Healthy Enabled BSP.
+	 * </pre>
+	 */
+	uint32_t status_flags;
+
+	/*
+	 * The physical location of the processor, including the physical package number
+	 * that identifies the cartridge, the physical core number within package, and
+	 * logical thread number within core.
+	 */
+	struct efi_cpu_physical_location location;
+
+	/*
+	 * The extended information of the processor. This field is filled only when
+	 * CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber.
+	 */
+	union extended_processor_information extended_information;
+};
+
+struct efi_mp_information_hob_data {
+	uint64_t number_of_processors;
+	uint64_t number_of_enabled_processors;
+	struct efi_processor_information processor_info[];
+};
+
+#endif /* MPINFO_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index c40f955..f12a4d6 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -302,7 +302,7 @@
 
 	/*
 	 * Highest power level which takes part in a power management
-	 * operation.
+	 * operation. May be lower while the core is in suspend state.
 	 */
 	unsigned int target_pwrlvl;
 
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index c50f8cb..9950a6e 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -89,10 +89,10 @@
 void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
 void psci_prepare_next_non_secure_ctx(
 			  entry_point_info_t *next_image_info);
-int psci_stop_other_cores(unsigned int wait_ms,
+int psci_stop_other_cores(unsigned int this_cpu_idx, unsigned int wait_ms,
 			  void (*stop_func)(u_register_t mpidr));
-bool psci_is_last_on_cpu_safe(void);
-bool psci_are_all_cpus_on_safe(void);
+bool psci_is_last_on_cpu_safe(unsigned int this_core);
+bool psci_are_all_cpus_on_safe(unsigned int this_core);
 void psci_pwrdown_cpu(unsigned int power_level);
 void psci_do_manage_extensions(void);
 
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 1b5ec2d..bcf9fc9 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -56,11 +56,12 @@
 	TL_TAG_HOB_BLOCK = 2,
 	TL_TAG_HOB_LIST = 3,
 	TL_TAG_ACPI_TABLE_AGGREGATE = 4,
+	TL_TAG_TPM_EVLOG = 5,
 	TL_TAG_OPTEE_PAGABLE_PART = 0x100,
 	TL_TAG_DT_SPMC_MANIFEST = 0x101,
 	TL_TAG_EXEC_EP_INFO64 = 0x102,
-	TL_TAG_TB_FW_CONFIG = 0x103,
 	TL_TAG_SRAM_LAYOUT64 = 0x104,
+	TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
 };
 
 enum transfer_list_ops {
@@ -110,6 +111,7 @@
 CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
 
 void transfer_list_dump(struct transfer_list_header *tl);
+struct transfer_list_header *transfer_list_ensure(void *addr, size_t size);
 entry_point_info_t *
 transfer_list_set_handoff_args(struct transfer_list_header *tl,
 			       entry_point_info_t *ep_info);
diff --git a/include/plat/arm/board/common/rotpk/rotpk_def.h b/include/plat/arm/board/common/rotpk/rotpk_def.h
index 685c21a..9ad9e4e 100644
--- a/include/plat/arm/board/common/rotpk/rotpk_def.h
+++ b/include/plat/arm/board/common/rotpk/rotpk_def.h
@@ -13,12 +13,9 @@
  */
 
 /*
- * Root of trust key lengths
+ * Length of the header for a hashed DER ROTPK.
  */
-#ifndef ARM_ROTPK_HEADER_LEN
-#define ARM_ROTPK_HEADER_LEN		19
-#endif
-#ifndef ARM_ROTPK_HASH_LEN
-#define ARM_ROTPK_HASH_LEN		32
+#ifndef ARM_ROTPK_HASH_DER_HEADER_LEN
+#define ARM_ROTPK_HASH_DER_HEADER_LEN		19
 #endif
 #endif /* ROTPK_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index c3756bf..1d7a59d 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -288,6 +288,11 @@
 void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl);
 void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
 					struct transfer_list_header *secure_tl);
+void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
+				      struct transfer_list_header *ns_tl);
+struct transfer_list_entry *
+arm_transfer_list_set_heap_info(struct transfer_list_header *tl);
+void arm_transfer_list_get_heap_info(void **heap_addr, size_t *heap_size);
 
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
@@ -427,6 +432,7 @@
 extern plat_psci_ops_t plat_arm_psci_pm_ops;
 extern const mmap_region_t plat_arm_mmap[];
 extern const unsigned int arm_pm_idle_states[];
+extern struct transfer_list_header *secure_tl;
 
 /* secure watchdog */
 void plat_arm_secure_wdt_start(void);
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index ae5aa23..b43f131 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -15,6 +15,7 @@
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
+#include <services/rmm_el3_token_sign.h>
 #endif
 #include <drivers/fwu/fwu_metadata.h>
 #if TRNG_SUPPORT
@@ -298,6 +299,16 @@
 #if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
 void bl2_plat_mboot_init(void);
 void bl2_plat_mboot_finish(void);
+#if TRANSFER_LIST
+int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base);
+#else
+static inline int
+plat_handoff_mboot(__unused const void *data, __unused uint32_t data_size,
+	      __unused void *tl_base)
+{
+	return -1;
+}
+#endif
 #else
 static inline void bl2_plat_mboot_init(void)
 {
@@ -376,6 +387,15 @@
 				   uint64_t *remaining_len);
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
+/* The following 3 functions are to be implement if
+ * RMMD_ENABLE_EL3_TOKEN_SIGN=1.
+ * The following three functions are expected to return E_RMM_* error codes.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					   unsigned int type);
+int plat_rmmd_el3_token_sign_push_req(
+				const struct el3_token_sign_request *req);
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
diff --git a/include/plat/nuvoton/common/npcm845x_arm_def.h b/include/plat/nuvoton/common/npcm845x_arm_def.h
index df3ad24..9e921b8 100644
--- a/include/plat/nuvoton/common/npcm845x_arm_def.h
+++ b/include/plat/nuvoton/common/npcm845x_arm_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * Copyright (C) 2017-2023 Nuvoton Ltd.
  *
@@ -30,10 +30,9 @@
  *****************************************************************************/
 
 /*
- * Root of trust key hash lengths
+ * Length of the header for a hashed DER ROTPK.
  */
-#define ARM_ROTPK_HEADER_LEN		19
-#define ARM_ROTPK_HASH_LEN		32
+#define ARM_ROTPK_HASH_DER_HEADER_LEN		19
 
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index 645b388..c2b1f41 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,8 +13,310 @@
 #define SMCCC_ARCH_WORKAROUND_1		U(0x80008000)
 #define SMCCC_ARCH_WORKAROUND_2		U(0x80007FFF)
 #define SMCCC_ARCH_WORKAROUND_3		U(0x80003FFF)
+#define SMCCC_ARCH_FEATURE_AVAILABILITY		U(0x80000003)
 
 #define SMCCC_GET_SOC_VERSION		U(0)
 #define SMCCC_GET_SOC_REVISION		U(1)
 
+#ifndef __ASSEMBLER__
+#if ARCH_FEATURE_AVAILABILITY
+#include <lib/cassert.h>
+
+#if ENABLE_FEAT_FGT2
+#define SCR_FEAT_FGT2 SCR_FGTEN2_BIT
+#else
+#define SCR_FEAT_FGT2 (0)
+#endif
+
+#if ENABLE_FEAT_FPMR
+#define SCR_FEAT_FPMR SCR_EnFPM_BIT
+#else
+#define SCR_FEAT_FPMR
+#endif
+
+#if ENABLE_FEAT_D128
+#define SCR_FEAT_D128 SCR_D128En_BIT
+#else
+#define SCR_FEAT_D128 (0)
+#endif
+
+#if ENABLE_FEAT_S1PIE
+#define SCR_FEAT_S1PIE SCR_PIEN_BIT
+#else
+#define SCR_FEAT_S1PIE (0)
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+#define SCR_FEAT_SCTLR2 SCR_SCTLR2En_BIT
+#else
+#define SCR_FEAT_SCTLR2 (0)
+#endif
+
+#if ENABLE_FEAT_TCR2
+#define SCR_FEAT_TCR2 SCR_TCR2EN_BIT
+#else
+#define SCR_FEAT_TCR2 (0)
+#endif
+
+#if ENABLE_FEAT_THE
+#define SCR_FEAT_THE SCR_RCWMASKEn_BIT
+#else
+#define SCR_FEAT_THE (0)
+#endif
+
+#if ENABLE_SME_FOR_NS
+#define SCR_FEAT_SME SCR_ENTP2_BIT
+#else
+#define SCR_FEAT_SME (0)
+#endif
+
+#if ENABLE_FEAT_GCS
+#define SCR_FEAT_GCS SCR_GCSEn_BIT
+#else
+#define SCR_FEAT_GCS (0)
+#endif
+
+#if ENABLE_FEAT_HCX
+#define SCR_FEAT_HCX SCR_HXEn_BIT
+#else
+#define SCR_FEAT_HCX (0)
+#endif
+
+#if ENABLE_FEAT_LS64_ACCDATA
+#define SCR_FEAT_LS64_ACCDATA (SCR_ADEn_BIT | SCR_EnAS0_BIT)
+#else
+#define SCR_FEAT_LS64_ACCDATA (0)
+#endif
+
+#if ENABLE_FEAT_AMUv1p1
+#define SCR_FEAT_AMUv1p1 SCR_AMVOFFEN_BIT
+#else
+#define SCR_FEAT_AMUv1p1 (0)
+#endif
+
+#if ENABLE_FEAT_ECV
+#define SCR_FEAT_ECV SCR_ECVEN_BIT
+#else
+#define SCR_FEAT_ECV (0)
+#endif
+
+#if ENABLE_FEAT_FGT
+#define SCR_FEAT_FGT SCR_FGTEN_BIT
+#else
+#define SCR_FEAT_FGT (0)
+#endif
+
+#if ENABLE_FEAT_MTE2
+#define SCR_FEAT_MTE2 SCR_ATA_BIT
+#else
+#define SCR_FEAT_MTE2 (0)
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+#define SCR_FEAT_CSV2_2 SCR_EnSCXT_BIT
+#else
+#define SCR_FEAT_CSV2_2 (0)
+#endif
+
+#if ENABLE_FEAT_RAS
+#define SCR_FEAT_RAS SCR_TERR_BIT
+#else
+#define SCR_FEAT_RAS (0)
+#endif
+
+#ifndef SCR_PLAT_FEATS
+#define SCR_PLAT_FEATS (0)
+#endif
+#ifndef SCR_PLAT_FLIPPED
+#define SCR_PLAT_FLIPPED (0)
+#endif
+#ifndef SCR_PLAT_IGNORED
+#define SCR_PLAT_IGNORED (0)
+#endif
+
+#ifndef CPTR_PLAT_FEATS
+#define CPTR_PLAT_FEATS (0)
+#endif
+#ifndef CPTR_PLAT_FLIPPED
+#define CPTR_PLAT_FLIPPED (0)
+#endif
+
+#ifndef MDCR_PLAT_FEATS
+#define MDCR_PLAT_FEATS (0)
+#endif
+#ifndef MDCR_PLAT_FLIPPED
+#define MDCR_PLAT_FLIPPED (0)
+#endif
+#ifndef MDCR_PLAT_IGNORED
+#define MDCR_PLAT_IGNORED (0)
+#endif
+/*
+ * XYZ_EL3_FEATS - list all bits that are relevant for feature enablement. It's
+ * a constant list based on what features are expected. This relies on the fact
+ * that if the feature is in any way disabled, then the relevant bit will not be
+ * written by context management.
+ *
+ * XYZ_EL3_FLIPPED - bits with an active 0, rather than the usual active 1. The
+ * spec always uses active 1 to mean that the feature will not trap.
+ *
+ * XYZ_EL3_IGNORED - list of all bits that are not relevant for feature
+ * enablement and should not be reported to lower ELs
+ */
+#define SCR_EL3_FEATS (								\
+	SCR_FEAT_FGT2		|						\
+	SCR_FEAT_FPMR		|						\
+	SCR_FEAT_D128		|						\
+	SCR_FEAT_S1PIE		|						\
+	SCR_FEAT_SCTLR2		|						\
+	SCR_FEAT_TCR2		|						\
+	SCR_FEAT_THE		|						\
+	SCR_FEAT_SME		|						\
+	SCR_FEAT_GCS		|						\
+	SCR_FEAT_HCX		|						\
+	SCR_FEAT_LS64_ACCDATA	|						\
+	SCR_FEAT_AMUv1p1	|						\
+	SCR_FEAT_ECV		|						\
+	SCR_FEAT_FGT		|						\
+	SCR_FEAT_MTE2		|						\
+	SCR_FEAT_CSV2_2		|						\
+	SCR_APK_BIT		| /* FEAT_Pauth */				\
+	SCR_FEAT_RAS		|						\
+	SCR_PLAT_FEATS)
+#define SCR_EL3_FLIPPED (							\
+	SCR_FEAT_RAS		|						\
+	SCR_PLAT_FLIPPED)
+#define SCR_EL3_IGNORED (							\
+	SCR_API_BIT		|						\
+	SCR_RW_BIT		|						\
+	SCR_SIF_BIT		|						\
+	SCR_HCE_BIT		|						\
+	SCR_FIQ_BIT		|						\
+	SCR_IRQ_BIT		|						\
+	SCR_NS_BIT		|						\
+	SCR_RES1_BITS		|						\
+	SCR_PLAT_IGNORED)
+CASSERT((SCR_EL3_FEATS & SCR_EL3_IGNORED) == 0, scr_feat_is_ignored);
+CASSERT((SCR_EL3_FLIPPED & SCR_EL3_FEATS) == SCR_EL3_FLIPPED, scr_flipped_not_a_feat);
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+#define CPTR_SYS_REG_TRACE (TCPAC_BIT | TTA_BIT)
+#else
+#define CPTR_SYS_REG_TRACE (0)
+#endif
+
+#if ENABLE_FEAT_AMU
+#define CPTR_FEAT_AMU TAM_BIT
+#else
+#define CPTR_FEAT_AMU (0)
+#endif
+
+#if ENABLE_SME_FOR_NS
+#define CPTR_FEAT_SME ESM_BIT
+#else
+#define CPTR_FEAT_SME (0)
+#endif
+
+#if ENABLE_SVE_FOR_NS
+#define CPTR_FEAT_SVE CPTR_EZ_BIT
+#else
+#define CPTR_FEAT_SVE (0)
+#endif
+
+#define CPTR_EL3_FEATS (							\
+	CPTR_SYS_REG_TRACE	|						\
+	CPTR_FEAT_AMU		|						\
+	CPTR_FEAT_SME		|						\
+	TFP_BIT			|						\
+	CPTR_FEAT_SVE		|						\
+	CPTR_PLAT_FEATS)
+#define CPTR_EL3_FLIPPED (							\
+	CPTR_SYS_REG_TRACE	|						\
+	CPTR_FEAT_AMU		|						\
+	TFP_BIT			|						\
+	CPTR_PLAT_FLIPPED)
+CASSERT((CPTR_EL3_FLIPPED & CPTR_EL3_FEATS) == CPTR_EL3_FLIPPED, cptr_flipped_not_a_feat);
+
+/*
+ * Some features enables are expressed with more than 1 bit in order to cater
+ * for multi world enablement. In those cases (BRB, TRB, SPE) only the last bit
+ * is used and reported. This (ab)uses the convenient fact that the last bit
+ * always means "enabled for this world" when context switched correctly.
+ * The per-world values have been adjusted such that this is always true.
+ */
+#if ENABLE_BRBE_FOR_NS
+#define MDCR_FEAT_BRBE MDCR_SBRBE(1UL)
+#else
+#define MDCR_FEAT_BRBE (0)
+#endif
+
+#if ENABLE_FEAT_FGT
+#define MDCR_FEAT_FGT MDCR_TDCC_BIT
+#else
+#define MDCR_FEAT_FGT (0)
+#endif
+
+#if ENABLE_TRBE_FOR_NS
+#define MDCR_FEAT_TRBE MDCR_NSTB(1UL)
+#else
+#define MDCR_FEAT_TRBE (0)
+#endif
+
+#if ENABLE_TRF_FOR_NS
+#define MDCR_FEAT_TRF MDCR_TTRF_BIT
+#else
+#define MDCR_FEAT_TRF (0)
+#endif
+
+#if ENABLE_SPE_FOR_NS
+#define MDCR_FEAT_SPE MDCR_NSPB(1UL)
+#else
+#define MDCR_FEAT_SPE (0)
+#endif
+
+#define MDCR_EL3_FEATS (							\
+	MDCR_FEAT_BRBE		|						\
+	MDCR_FEAT_FGT		|						\
+	MDCR_FEAT_TRBE		|						\
+	MDCR_FEAT_TRF		|						\
+	MDCR_FEAT_SPE		|						\
+	MDCR_TDOSA_BIT		|						\
+	MDCR_TDA_BIT		|						\
+	MDCR_TPM_BIT		| /* FEAT_PMUv3 */				\
+	MDCR_PLAT_FEATS)
+#define MDCR_EL3_FLIPPED (							\
+	MDCR_FEAT_FGT		|						\
+	MDCR_FEAT_TRF		|						\
+	MDCR_TDOSA_BIT		|						\
+	MDCR_TDA_BIT		|						\
+	MDCR_TPM_BIT		|						\
+	MDCR_PLAT_FLIPPED)
+#define MDCR_EL3_IGNORED (							\
+	MDCR_EBWE_BIT		|						\
+	MDCR_EnPMSN_BIT		|						\
+	MDCR_SBRBE(2UL)		|						\
+	MDCR_MTPME_BIT		|						\
+	MDCR_NSTBE_BIT		|						\
+	MDCR_NSTB(2UL)		|						\
+	MDCR_SDD_BIT		|						\
+	MDCR_SPD32(3UL)		|						\
+	MDCR_NSPB(2UL)		|						\
+	MDCR_NSPBE_BIT		|						\
+	MDCR_PLAT_IGNORED)
+CASSERT((MDCR_EL3_FEATS & MDCR_EL3_IGNORED) == 0, mdcr_feat_is_ignored);
+CASSERT((MDCR_EL3_FLIPPED & MDCR_EL3_FEATS) == MDCR_EL3_FLIPPED, mdcr_flipped_not_a_feat);
+
+#define MPAM3_EL3_FEATS		(MPAM3_EL3_TRAPLOWER_BIT)
+#define MPAM3_EL3_FLIPPED	(MPAM3_EL3_TRAPLOWER_BIT)
+#define MPAM3_EL3_IGNORED	(MPAM3_EL3_MPAMEN_BIT)
+CASSERT((MPAM3_EL3_FEATS & MPAM3_EL3_IGNORED) == 0, mpam3_feat_is_ignored);
+CASSERT((MPAM3_EL3_FLIPPED & MPAM3_EL3_FEATS) == MPAM3_EL3_FLIPPED, mpam3_flipped_not_a_feat);
+
+/* The hex representations of these registers' S3 encoding */
+#define SCR_EL3_OPCODE  			U(0x1E1100)
+#define CPTR_EL3_OPCODE 			U(0x1E1140)
+#define MDCR_EL3_OPCODE 			U(0x1E1320)
+#define MPAM3_EL3_OPCODE 			U(0x1EA500)
+
+#endif /* ARCH_FEATURE_AVAILABILITY */
+#endif /* __ASSEMBLER__ */
 #endif /* ARM_ARCH_SVC_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 01dbea9..f5a9a2d 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -173,8 +173,8 @@
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 #define FFA_NORMAL_WORLD_RESUME	FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
 #define FFA_EL3_INTR_HANDLE	FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
-#define FFA_MEM_PERM_GET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
-#define FFA_MEM_PERM_SET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
+#define FFA_MEM_PERM_GET_SMC32	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
+#define FFA_MEM_PERM_SET_SMC32	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
 #define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
 
 /* FFA SMC64 FIDs */
@@ -201,6 +201,8 @@
 	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
 #define FFA_MSG_SEND_DIRECT_RESP2_SMC64	\
 	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
+#define FFA_MEM_PERM_GET_SMC64	FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_GET)
+#define FFA_MEM_PERM_SET_SMC64	FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_SET)
 
 /*
  * FF-A partition properties values.
@@ -208,6 +210,8 @@
 #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)
+#define FFA_PARTITION_DIRECT_REQ2_RECV	U(1 << 9)
+#define FFA_PARTITION_DIRECT_REQ2_SEND	U(1 << 10)
 
 /*
  * Reserve a special value for traffic targeted to the Hypervisor or SPM.
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 578bc14..6b57267 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,7 +67,7 @@
 	uintptr_t base;			/* Console base address */
 	uint64_t map_pages;		/* Num of pages to be mapped in RMM for the console MMIO */
 	char name[RMM_CONSOLE_MAX_NAME_LEN];	/* Name of console */
-	uint64_t clk_in_hz;		/* UART clock (in HZ) for the console */
+	uint64_t clk_in_hz;		/* UART clock (in Hz) for the console */
 	uint64_t baud_rate;		/* Baud rate */
 	uint64_t flags;			/* Additional flags RES0 */
 };
@@ -87,8 +87,8 @@
 
 struct console_list {
 	uint64_t num_consoles;		/* Number of consoles */
-	struct console_info *consoles;	/* Pointer to ns_dram_bank[] */
-	uint64_t checksum;		/* Checksum of ns_dram_info data */
+	struct console_info *consoles;	/* Pointer to console_info[] */
+	uint64_t checksum;		/* Checksum of console_list data */
 };
 
 CASSERT(offsetof(struct console_list, num_consoles) == 0UL,
diff --git a/include/services/rmm_el3_token_sign.h b/include/services/rmm_el3_token_sign.h
new file mode 100644
index 0000000..154940c
--- /dev/null
+++ b/include/services/rmm_el3_token_sign.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_EL3_TOKEN_SIGN_H
+#define RMM_EL3_TOKEN_SIGN_H
+
+#include <stdint.h>
+#include <lib/cassert.h>
+#include <services/rmmd_svc.h>
+
+/*
+ * Defines member of structure and reserves space
+ * for the next member with specified offset.
+ */
+/* cppcheck-suppress [misra-c2012-20.7] */
+#define SET_MEMBER(member, start, end)	\
+	union {				\
+		member;			\
+		unsigned char reserved##end[((end) - (start))];	\
+	}
+
+#define EL3_TOKEN_RESPONSE_MAX_SIG_LEN U(512)
+
+struct el3_token_sign_request {
+	SET_MEMBER(uint32_t sig_alg_id, 0x0, 0x8);
+	SET_MEMBER(uint64_t rec_granule, 0x8, 0x10);
+	SET_MEMBER(uint64_t req_ticket, 0x10, 0x18);
+	SET_MEMBER(uint32_t hash_alg_id, 0x18, 0x20);
+	SET_MEMBER(uint8_t hash_buf[SHA512_DIGEST_SIZE], 0x20, 0x60);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, sig_alg_id) == 0x0U,
+	assert_el3_token_sign_request_sig_alg_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, rec_granule) == 0x8U,
+	assert_el3_token_sign_request_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, req_ticket) == 0x10U,
+	assert_el3_token_sign_request_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_alg_id) == 0x18U,
+	assert_el3_token_sign_request_hash_alg_id_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_buf) == 0x20U,
+	assert_el3_token_sign_request_hash_buf_mismatch);
+
+
+struct el3_token_sign_response {
+	SET_MEMBER(uint64_t rec_granule, 0x0, 0x8);
+	SET_MEMBER(uint64_t req_ticket, 0x8, 0x10);
+	SET_MEMBER(uint16_t sig_len, 0x10, 0x12);
+	SET_MEMBER(uint8_t signature_buf[EL3_TOKEN_RESPONSE_MAX_SIG_LEN], 0x12, 0x212);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, rec_granule) == 0x0U,
+	assert_el3_token_sign_resp_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, req_ticket) == 0x8U,
+	assert_el3_token_sign_resp_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, sig_len) == 0x10U,
+	assert_el3_token_sign_resp_sig_len_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, signature_buf) == 0x12U,
+	assert_el3_token_sign_resp_sig_buf_mismatch);
+
+#endif /* RMM_EL3_TOKEN_SIGN_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 635c28e..0cc8628 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -129,8 +129,43 @@
 					/* 0x1B3 */
 #define RMM_ATTEST_GET_PLAT_TOKEN	SMC64_RMMD_EL3_FID(U(3))
 
+/* Starting RMM-EL3 interface version 0.4 */
+#define RMM_EL3_FEATURES				SMC64_RMMD_EL3_FID(U(4))
+#define RMM_EL3_FEAT_REG_0_IDX				U(0)
+/* Bit 0 of FEAT_REG_0 */
+/* 1 - the feature is present in EL3 , 0 - the feature is absent */
+#define RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK		U(0x1)
+
+/*
+ * Function codes to support attestation where EL3 is used to sign
+ * realm attestation tokens. In this model, the private key is not
+ * exposed to the RMM.
+ * The arguments to this SMC are:
+ *     arg0 - Function ID.
+ *     arg1 - Opcode, one of:
+ *               RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP,
+ *               RMM_EL3_TOKEN_SIGN_PULL_RESP_OP,
+ *               RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ *     arg2 - Pointer to buffer with request/response structures,
+ *            which is in the RMM<->EL3 shared buffer.
+ *     arg3 - Buffer size of memory pointed by arg2.
+ *     arg4 - ECC Curve, when opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ * The return arguments are:
+ *     ret0 - Status/Error
+ *     ret1 - Size of public key if opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ */
+#define RMM_EL3_TOKEN_SIGN			SMC64_RMMD_EL3_FID(U(5))
+
+/* Opcodes for RMM_EL3_TOKEN_SIGN  */
+#define RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP          U(1)
+#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP         U(2)
+#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP       U(3)
+
 /* ECC Curve types for attest key generation */
-#define ATTEST_KEY_CURVE_ECC_SECP384R1		0
+#define ATTEST_KEY_CURVE_ECC_SECP384R1		U(0)
+
+/* Identifier for the hash algorithm used for attestation signing */
+#define EL3_TOKEN_SIGN_HASH_ALG_SHA384		U(1)
 
 /*
  * RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
@@ -153,7 +188,7 @@
  * Increase this when a bug is fixed, or a feature is added without
  * breaking compatibility.
  */
-#define RMM_EL3_IFC_VERSION_MINOR	(U(3))
+#define RMM_EL3_IFC_VERSION_MINOR	(U(4))
 
 #define RMM_EL3_INTERFACE_VERSION				\
 	(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) |	\
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 374cc5d..fecb56f 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -57,7 +57,7 @@
 	msr	osdlr_el1, x0
 	isb
 
-	apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169
+	apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169, NO_GET_CPU_REV
 
 	dsb	sy
 	ret
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 4c33dda..dce9c73 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A710_BHB_LOOP_COUNT, cortex_a710
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a710, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A710_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a710,  CVE(2024, 5660)
+
+check_erratum_ls cortex_a710, CVE(2024, 5660), CPU_REV(2, 1)
+
 workaround_reset_start cortex_a710, ERRATUM(1987031), ERRATA_A710_1987031
 	ldr x0,=0x6
 	msr S3_6_c15_c8_0,x0
@@ -216,7 +223,7 @@
 	 * ----------------------------------------------------
 	 */
 func cortex_a710_core_pwr_dwn
-	apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768
+	apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768, NO_GET_CPU_REV
 	apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a720_ae.S b/lib/cpus/aarch64/cortex_a720_ae.S
new file mode 100644
index 0000000..42d49c3
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a720_ae.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a720_ae.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A720AE must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A720AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_a720_ae
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_a720_ae
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a720_ae_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_A720_AE_CPUPWRCTLR_EL1, CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+	isb
+	ret
+endfunc cortex_a720_ae_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A720AE specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a720_ae_regs, "aS"
+cortex_a720_ae_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a720_ae_cpu_reg_dump
+	adr	x6, cortex_a720_ae_regs
+	mrs	x8, CORTEX_A720_AE_CPUECTLR_EL1
+	ret
+endfunc cortex_a720_ae_cpu_reg_dump
+
+declare_cpu_ops cortex_a720_ae, CORTEX_A720_AE_MIDR, \
+	cortex_a720_ae_reset_func, \
+	cortex_a720_ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 97e036e..017086a 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -505,7 +505,7 @@
 	 */
 	sysreg_bit_set CORTEX_A76_CPUPWRCTLR_EL1, CORTEX_A76_CORE_PWRDN_EN_MASK
 
-	apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102
+	apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index d1fc41a..766bdc0 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A77_BHB_LOOP_COUNT, cortex_a77
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a77, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a77, CVE(2024, 5660)
+
+check_erratum_ls cortex_a77, CVE(2024, 5660), CPU_REV(1, 1)
+
 workaround_reset_start cortex_a77, ERRATUM(1508412), ERRATA_A77_1508412
 	/* move cpu revision in again and compare against r0p0 */
 	mov	x0, x7
@@ -161,7 +168,7 @@
 	sysreg_bit_set CORTEX_A77_CPUPWRCTLR_EL1, \
 		CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-	apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100
+	apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 5a63e78..9f2ffdf 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -24,6 +24,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation.Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78, CVE(2024, 5660), CPU_REV(1, 2)
+
 workaround_reset_start cortex_a78, ERRATUM(1688305), ERRATA_A78_1688305
 	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_1
 workaround_reset_end cortex_a78, ERRATUM(1688305)
@@ -192,7 +199,7 @@
 func cortex_a78_core_pwr_dwn
 	sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 
-	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
+	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index bc10186..7fa1f9b 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -22,6 +22,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78_ae, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78_ae, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78_ae, CVE(2024, 5660), CPU_REV(0, 3)
+
 workaround_reset_start cortex_a78_ae, ERRATUM(1941500), ERRATA_A78_AE_1941500
 	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
 workaround_reset_end cortex_a78_ae, ERRATUM(1941500)
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 97d5743..3f6944a 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -21,6 +21,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78c, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78c, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78c, CVE(2024, 5660), CPU_REV(0, 2)
+
 workaround_reset_start cortex_a78c, ERRATUM(1827430), ERRATA_A78C_1827430
 	/* Disable allocation of splintered pages in the L2 TLB */
 	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
@@ -132,7 +139,7 @@
 	 */
 	sysreg_bit_set CORTEX_A78C_CPUPWRCTLR_EL1, CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 
-	apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
+	apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_alto.S b/lib/cpus/aarch64/cortex_alto.S
new file mode 100644
index 0000000..c0815f9
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_alto.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_alto.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Alto must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Alto supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_alto
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_alto
+
+func cortex_alto_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+        /* ---------------------------------------------------
+         * Disable SME if enabled and supported
+         * ---------------------------------------------------
+         */
+	mrs     x0, ID_AA64PFR1_EL1
+	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+		#ID_AA64PFR1_EL1_SME_WIDTH
+        cmp     x0, #SME_NOT_IMPLEMENTED
+	b.eq	1f
+	msr	CORTEX_ALTO_SVCRSM, xzr
+	msr	CORTEX_ALTO_SVCRZA, xzr
+1:
+#endif
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_ALTO_IMP_CPUPWRCTLR_EL1, \
+		CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	isb
+	ret
+endfunc cortex_alto_core_pwr_dwn
+
+.section .rodata.cortex_alto_regs, "aS"
+cortex_alto_regs: /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_alto_cpu_reg_dump
+	adr 	x6, cortex_alto_regs
+	mrs	x8, CORTEX_ALTO_IMP_CPUECTLR_EL1
+	ret
+endfunc cortex_alto_cpu_reg_dump
+
+declare_cpu_ops cortex_alto, CORTEX_ALTO_MIDR, \
+	cortex_alto_reset_func, \
+	cortex_alto_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_arcadia.S b/lib/cpus/aarch64/cortex_arcadia.S
new file mode 100644
index 0000000..c97d87d
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_arcadia.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_arcadia.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-ARCADIA must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-ARCADIA supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_arcadia
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_arcadia
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_arcadia_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_ARCADIA_CPUPWRCTLR_EL1, CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_arcadia_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-Arcadia specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_arcadia_regs, "aS"
+cortex_arcadia_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_arcadia_cpu_reg_dump
+	adr	x6, cortex_arcadia_regs
+	mrs	x8, CORTEX_ARCADIA_CPUECTLR_EL1
+	ret
+endfunc cortex_arcadia_cpu_reg_dump
+
+declare_cpu_ops cortex_arcadia, CORTEX_ARCADIA_MIDR, \
+	cortex_arcadia_reset_func, \
+	cortex_arcadia_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index ca6cac9..5bd020c 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Google LLC. All rights reserved.
+ * Copyright (c) 2022-2024, Google LLC. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,6 +23,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X1_BHB_LOOP_COUNT, cortex_x1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x1, CVE(2024, 5660)
+
+check_erratum_ls cortex_x1, CVE(2024, 5660), CPU_REV(1, 2)
+
 workaround_reset_start cortex_x1, ERRATUM(1688305), ERRATA_X1_1688305
 	sysreg_bit_set CORTEX_X1_ACTLR2_EL1, BIT(1)
 workaround_reset_end cortex_x1, ERRATUM(1688305)
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index ab0b19d..2fc357a 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X2_BHB_LOOP_COUNT, cortex_x2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x2, CVE(2024, 5660)
+
+check_erratum_ls cortex_x2, CVE(2024, 5660), CPU_REV(2, 1)
+
 workaround_reset_start cortex_x2, ERRATUM(2002765), ERRATA_X2_2002765
 	ldr	x0, =0x6
 	msr	S3_6_C15_C8_0, x0 /* CPUPSELR_EL3 */
@@ -126,10 +133,10 @@
 
 check_erratum_ls cortex_x2, ERRATUM(2742423), CPU_REV(2, 1)
 
-workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
+workaround_runtime_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
 	/* dsb before isb of power down sequence */
 	dsb	sy
-workaround_reset_end cortex_x2, ERRATUM(2768515)
+workaround_runtime_end cortex_x2, ERRATUM(2768515)
 
 check_erratum_ls cortex_x2, ERRATUM(2768515), CPU_REV(2, 1)
 
@@ -172,12 +179,7 @@
 	 */
 	sysreg_bit_set CORTEX_X2_CPUPWRCTLR_EL1, CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-#if ERRATA_X2_2768515
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	erratum_cortex_x2_2768515_wa
-	mov	x30, x15
-#endif /* ERRATA_X2_2768515 */
+	apply_erratum cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515, NO_GET_CPU_REV
 	isb
 	ret
 endfunc cortex_x2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 248f107..6becf7b 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x3, CVE(2024, 5660)
+
+check_erratum_ls cortex_x3, CVE(2024, 5660), CPU_REV(1, 2)
+
 workaround_reset_start cortex_x3, ERRATUM(2070301), ERRATA_X3_2070301
 	sysreg_bitfield_insert CORTEX_X3_CPUECTLR2_EL1, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV, \
 	CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH
@@ -114,13 +121,13 @@
 	 * ----------------------------------------------------
 	 */
 func cortex_x3_core_pwr_dwn
-	apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
+	apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909, NO_GET_CPU_REV
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set CORTEX_X3_CPUPWRCTLR_EL1, CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	apply_erratum cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088
+	apply_erratum cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088, NO_GET_CPU_REV
 	isb
 	ret
 endfunc cortex_x3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 8820de5..81704da 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -46,6 +46,13 @@
 	ret
 check_erratum_custom_end cortex_x4, ERRATUM(2726228)
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x4, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X4_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x4, CVE(2024, 5660)
+
+check_erratum_ls cortex_x4, CVE(2024, 5660), CPU_REV(0, 2)
+
 workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
 	/* dsb before isb of power down sequence */
 	dsb	sy
@@ -75,6 +82,12 @@
 
 check_erratum_ls cortex_x4, ERRATUM(2897503), CPU_REV(0, 1)
 
+workaround_reset_start cortex_x4, ERRATUM(2923985), ERRATA_X4_2923985
+	sysreg_bit_set CORTEX_X4_CPUACTLR4_EL1, (BIT(11) | BIT(10))
+workaround_reset_end cortex_x4, ERRATUM(2923985)
+
+check_erratum_ls cortex_x4, ERRATUM(2923985), CPU_REV(0, 1)
+
 workaround_reset_start cortex_x4, ERRATUM(3076789), ERRATA_X4_3076789
 	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(14)
 	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(13)
@@ -111,7 +124,7 @@
 	 */
 	sysreg_bit_set CORTEX_X4_CPUPWRCTLR_EL1, CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-	apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
+	apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
index 8109ffb..3a31664 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -21,6 +21,13 @@
 #error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x925, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X925_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x925, CVE(2024, 5660)
+
+check_erratum_ls cortex_x925, CVE(2024, 5660), CPU_REV(0, 1)
+
 cpu_reset_func_start cortex_x925
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 50e1ae3..f727226 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -236,7 +236,7 @@
 	 */
 	sysreg_bit_set NEOVERSE_N1_CPUPWRCTLR_EL1, NEOVERSE_N1_CORE_PWRDN_EN_MASK
 
-	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
+	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 7d7cc44..69aa8ab 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -34,6 +34,13 @@
 .equ erratum_neoverse_n2_2313941_wa, errata_dsu_2313941_wa
 add_erratum_entry neoverse_n2, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_n2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_n2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_n2, CVE(2024, 5660), CPU_REV(0, 3)
+
 workaround_reset_start neoverse_n2, ERRATUM(2002655), ERRATA_N2_2002655
 	/* Apply instruction patching sequence */
 	ldr x0,=0x6
@@ -265,8 +272,7 @@
 cpu_reset_func_end neoverse_n2
 
 func neoverse_n2_core_pwr_dwn
-
-	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478, NO_GET_CPU_REV
 	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
@@ -276,7 +282,7 @@
 	 */
 	sysreg_bit_set NEOVERSE_N2_CPUPWRCTLR_EL1, NEOVERSE_N2_CORE_PWRDN_EN_BIT
 
-	apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089
+	apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 89299b7..d1a2c24 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V1_BHB_LOOP_COUNT, neoverse_v1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v1, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v1, CVE(2024, 5660), CPU_REV(1, 2)
+
 workaround_reset_start neoverse_v1, ERRATUM(1618635), ERRATA_V1_1618635
 	/* Inserts a DMB SY before and after MRS PAR_EL1 */
 	ldr	x0, =0x0
@@ -253,7 +260,7 @@
 	 * ---------------------------------------------
 	 */
 	sysreg_bit_set NEOVERSE_V1_CPUPWRCTLR_EL1, NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
+	apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index d8c32a4..f56a5e8 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -22,6 +22,13 @@
 #error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v2, CVE(2024, 5660), CPU_REV(0, 2)
+
 workaround_reset_start neoverse_v2, ERRATUM(2331132), ERRATA_V2_2331132
 	sysreg_bitfield_insert NEOVERSE_V2_CPUECTLR2_EL1, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
 		NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH
@@ -100,7 +107,7 @@
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set NEOVERSE_V2_CPUPWRCTLR_EL1, NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+	apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index 01ac38f..4346d7d 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v3, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v3, CVE(2024, 5660), CPU_REV(0, 1)
+
 workaround_reset_start neoverse_v3, CVE(2022,23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 4c20785..d532460 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -33,6 +33,12 @@
 WORKAROUND_CVE_2022_23960		?=1
 CPU_FLAG_LIST += WORKAROUND_CVE_2022_23960
 
+# Flag to disable Hardware page aggregation(HPA).
+# This flag is enabled by default.
+WORKAROUND_CVE_2024_5660		?=1
+CPU_FLAG_LIST += WORKAROUND_CVE_2024_5660
+
+
 # Flags to indicate internal or external Last level cache
 # By default internal
 CPU_FLAG_LIST += NEOVERSE_Nx_EXTERNAL_LLC
@@ -843,6 +849,10 @@
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_2897503
 
+# Flag to apply erratum 2923985 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2923985
+
 # Flag to apply erratum 3076789 workaround on reset. This erratum applies
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_3076789
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index ab9d4b6..fed24f0 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -400,10 +400,6 @@
 	/* PMUv3 is presumed to be always present */
 	mrs	x9, pmcr_el0
 	str	x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
-	/* Disable cycle counter when event counting is prohibited */
-	orr	x9, x9, #PMCR_EL0_DP_BIT
-	msr	pmcr_el0, x9
-	isb
 #if CTX_INCLUDE_PAUTH_REGS
 	/* ----------------------------------------------------------
  	 * Save the ARMv8.3-PAuth keys as they are not banked
@@ -443,13 +439,20 @@
  * -----------------------------------------------------------------
  */
 func prepare_el3_entry
-	save_gp_pmcr_pauth_regs
-	enable_serror_at_el3
 	/*
-	 * Set the PSTATE bits not described in the Aarch64.TakeException
-	 * pseudocode to their default values.
+	 * context is about to mutate, so make sure we don't affect any still
+	 * in-flight profiling operations. We don't care that they actually
+	 * finish, that can still be later. NOP if not present
 	 */
-	set_unset_pstate_bits
+#if ENABLE_SPE_FOR_NS
+	psb_csync
+#endif
+#if ENABLE_TRBE_FOR_NS
+	tsb_csync
+#endif
+	isb
+	save_gp_pmcr_pauth_regs
+	setup_el3_execution_context
 	ret
 endfunc prepare_el3_entry
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 6210356..9b97685 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -28,11 +28,13 @@
 #include <lib/extensions/brbe.h>
 #include <lib/extensions/debug_v8p9.h>
 #include <lib/extensions/fgt2.h>
+#include <lib/extensions/fpmr.h>
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
+#include <lib/extensions/sysreg128.h>
 #include <lib/extensions/sys_reg_trace.h>
 #include <lib/extensions/tcr2.h>
 #include <lib/extensions/trbe.h>
@@ -47,7 +49,6 @@
 per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
 static bool has_secure_perworld_init;
 
-static void manage_extensions_common(cpu_context_t *ctx);
 static void manage_extensions_nonsecure(cpu_context_t *ctx);
 static void manage_extensions_secure(cpu_context_t *ctx);
 static void manage_extensions_secure_per_world(void);
@@ -182,6 +183,13 @@
 		scr_el3 |= SCR_EnSCXT_BIT;
 	}
 
+	if (is_feat_sctlr2_supported()) {
+		/* Set the SCTLR2En bit in SCR_EL3 to enable access to
+		 * SCTLR2_ELx registers.
+		 */
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
+
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
 #endif /* ENABLE_RME */
@@ -227,8 +235,9 @@
 	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
 	 *  than EL3
 	 */
-	scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
-
+	if (is_armv8_3_pauth_present()) {
+		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+	}
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 #if HANDLE_EA_EL3_FIRST_NS
@@ -242,7 +251,6 @@
 	 * and RAS ERX registers from EL1 and EL2(from any security state)
 	 * are trapped to EL3.
 	 * Set here to trap only for NS EL1/EL2
-	 *
 	 */
 	scr_el3 |= SCR_TERR_BIT;
 #endif
@@ -260,6 +268,36 @@
 	 */
 	scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
 #endif
+
+	if (is_feat_the_supported()) {
+		/* Set the RCWMASKEn bit in SCR_EL3 to enable access to
+		 * RCWMASK_EL1 and RCWSMASK_EL1 registers.
+		 */
+		scr_el3 |= SCR_RCWMASKEn_BIT;
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		/* Set the SCTLR2En bit in SCR_EL3 to enable access to
+		 * SCTLR2_ELx registers.
+		 */
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
+
+	if (is_feat_d128_supported()) {
+		/* Set the D128En bit in SCR_EL3 to enable access to 128-bit
+		 * versions of TTBR0_EL1, TTBR1_EL1, RCWMASK_EL1, RCWSMASK_EL1,
+		 * PAR_EL1 and TTBR1_EL2, TTBR0_EL2 and VTTBR_EL2 registers.
+		 */
+		scr_el3 |= SCR_D128En_BIT;
+	}
+
+	if (is_feat_fpmr_supported()) {
+		/* Set the EnFPM bit in SCR_EL3 to enable access to FPMR
+		 * register.
+		 */
+		scr_el3 |= SCR_EnFPM_BIT;
+	}
+
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
 	/* Initialize EL2 context registers */
@@ -396,12 +434,21 @@
 	}
 
 	/*
+	 * If FEAT_LS64_ACCDATA is enabled, enable access to ACCDATA_EL1 by
+	 * setting SCR_EL3.ADEn and allow the ST64BV0 instruction by setting
+	 * SCR_EL3.EnAS0.
+	 */
+	if (is_feat_ls64_accdata_supported()) {
+		scr_el3 |= SCR_ADEn_BIT | SCR_EnAS0_BIT;
+	}
+
+	/*
 	 * If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
 	 * registers are trapped to EL3.
 	 */
-#if ENABLE_FEAT_RNG_TRAP
-	scr_el3 |= SCR_TRNDR_BIT;
-#endif
+	if (is_feat_rng_trap_supported()) {
+		scr_el3 |= SCR_TRNDR_BIT;
+	}
 
 #if FAULT_INJECTION_SUPPORT
 	/* Enable fault injection from lower ELs */
@@ -418,7 +465,9 @@
 	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
 	 *  than EL3
 	 */
-	scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+	if (is_armv8_3_pauth_present()) {
+		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+	}
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 	/*
@@ -519,11 +568,12 @@
 			& ~(MDCR_TDA_BIT | MDCR_TDOSA_BIT)) ;
 	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3);
 
-	/*
-	 * Configure MDCR_EL3 register as applicable for each world
-	 * (NS/Secure/Realm) context.
-	 */
-	manage_extensions_common(ctx);
+#if IMAGE_BL31
+	/* Enable FEAT_TRF for Non-Secure and prohibit for Secure state. */
+	if (is_feat_trf_supported()) {
+		trf_enable(ctx);
+	}
+#endif /* IMAGE_BL31 */
 
 	/*
 	 * Store the X0-X7 value from the entrypoint into the context
@@ -674,6 +724,10 @@
 	if (is_feat_mpam_supported()) {
 		mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
 	}
+
+	if (is_feat_fpmr_supported()) {
+		fpmr_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
+	}
 }
 #endif /* IMAGE_BL31 */
 
@@ -729,48 +783,6 @@
 }
 
 /*******************************************************************************
- * Enable architecture extensions on first entry to Non-secure world only
- * and disable for secure world.
- *
- * NOTE: Arch features which have been provided with the capability of getting
- * enabled only for non-secure world and being disabled for secure world are
- * grouped here, as the MDCR_EL3 context value remains same across the worlds.
- ******************************************************************************/
-static void manage_extensions_common(cpu_context_t *ctx)
-{
-#if IMAGE_BL31
-	if (is_feat_spe_supported()) {
-		/*
-		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
-		 */
-		spe_enable(ctx);
-	}
-
-	if (is_feat_trbe_supported()) {
-		/*
-		 * Enable FEAT_TRBE for Non-Secure and prohibit for Secure and
-		 * Realm state.
-		 */
-		trbe_enable(ctx);
-	}
-
-	if (is_feat_trf_supported()) {
-		/*
-		 * Enable FEAT_TRF for Non-Secure and prohibit for Secure state.
-		 */
-		trf_enable(ctx);
-	}
-
-	if (is_feat_brbe_supported()) {
-		/*
-		 * Enable FEAT_BRBE for Non-Secure and prohibit for Secure state.
-		 */
-		brbe_enable(ctx);
-	}
-#endif /* IMAGE_BL31 */
-}
-
-/*******************************************************************************
  * Enable architecture extensions on first entry to Non-secure world.
  ******************************************************************************/
 static void manage_extensions_nonsecure(cpu_context_t *ctx)
@@ -792,6 +804,25 @@
 		debugv8p9_extended_bp_wp_enable(ctx);
 	}
 
+	/*
+	 * SPE, TRBE, and BRBE have multi-field enables that affect which world
+	 * they apply to. Despite this, it is useful to ignore these for
+	 * simplicity in determining the feature's per world enablement status.
+	 * This is only possible when context is written per-world. Relied on
+	 * by SMCCC_ARCH_FEATURE_AVAILABILITY
+	 */
+	if (is_feat_spe_supported()) {
+		spe_enable(ctx);
+	}
+
+	if (is_feat_trbe_supported()) {
+		trbe_enable(ctx);
+	}
+
+	if (is_feat_brbe_supported()) {
+		brbe_enable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 #endif /* IMAGE_BL31 */
 }
@@ -852,6 +883,10 @@
 		sme_init_el2_unused();
 	}
 
+	if (is_feat_mops_supported()) {
+		write_hcrx_el2(read_hcrx_el2() | HCRX_EL2_MSCEn_BIT);
+	}
+
 #if ENABLE_PAUTH
 	enable_pauth_el2();
 #endif /* ENABLE_PAUTH */
@@ -881,6 +916,20 @@
 			sme_disable(ctx);
 		}
 	}
+
+	/*
+	 * SPE and TRBE cannot be fully disabled from EL3 registers alone, only
+	 * sysreg access can. In case the EL1 controls leave them active on
+	 * context switch, we want the owning security state to be NS so Secure
+	 * can't be DOSed.
+	 */
+	if (is_feat_spe_supported()) {
+		spe_disable(ctx);
+	}
+
+	if (is_feat_trbe_supported()) {
+		trbe_disable(ctx);
+	}
 #endif /* IMAGE_BL31 */
 }
 
@@ -1310,12 +1359,13 @@
 	write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
 	write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
 	write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
-	write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2());
 	write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
 	write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
 	write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
 	write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
-	write_el2_ctx_common(ctx, vttbr_el2, read_vttbr_el2());
+
+	write_el2_ctx_common_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
+	write_el2_ctx_common_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
 }
 
 static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
@@ -1391,7 +1441,7 @@
 	if (is_feat_vhe_supported()) {
 		write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
 					read_contextidr_el2());
-		write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
+		write_el2_ctx_vhe_sysreg128(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
 	}
 
 	if (is_feat_ras_supported()) {
@@ -1437,6 +1487,10 @@
 		write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcscr_el2());
 		write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcspr_el2());
 	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2, read_sctlr2_el2());
+	}
 }
 
 /*******************************************************************************
@@ -1524,6 +1578,10 @@
 		write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
 		write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
 	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el2(read_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2));
+	}
 }
 #endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
@@ -1633,15 +1691,12 @@
 	write_el1_ctx_common(ctx, csselr_el1, read_csselr_el1());
 	write_el1_ctx_common(ctx, sp_el1, read_sp_el1());
 	write_el1_ctx_common(ctx, esr_el1, read_esr_el1());
-	write_el1_ctx_common(ctx, ttbr0_el1, read_ttbr0_el1());
-	write_el1_ctx_common(ctx, ttbr1_el1, read_ttbr1_el1());
 	write_el1_ctx_common(ctx, mair_el1, read_mair_el1());
 	write_el1_ctx_common(ctx, amair_el1, read_amair_el1());
 	write_el1_ctx_common(ctx, actlr_el1, read_actlr_el1());
 	write_el1_ctx_common(ctx, tpidr_el1, read_tpidr_el1());
 	write_el1_ctx_common(ctx, tpidr_el0, read_tpidr_el0());
 	write_el1_ctx_common(ctx, tpidrro_el0, read_tpidrro_el0());
-	write_el1_ctx_common(ctx, par_el1, read_par_el1());
 	write_el1_ctx_common(ctx, far_el1, read_far_el1());
 	write_el1_ctx_common(ctx, afsr0_el1, read_afsr0_el1());
 	write_el1_ctx_common(ctx, afsr1_el1, read_afsr1_el1());
@@ -1650,6 +1705,10 @@
 	write_el1_ctx_common(ctx, mdccint_el1, read_mdccint_el1());
 	write_el1_ctx_common(ctx, mdscr_el1, read_mdscr_el1());
 
+	write_el1_ctx_common_sysreg128(ctx, par_el1, read_par_el1());
+	write_el1_ctx_common_sysreg128(ctx, ttbr0_el1, read_ttbr0_el1());
+	write_el1_ctx_common_sysreg128(ctx, ttbr1_el1, read_ttbr1_el1());
+
 	if (CTX_INCLUDE_AARCH32_REGS) {
 		/* Save Aarch32 registers */
 		write_el1_ctx_aarch32(ctx, spsr_abt, read_spsr_abt());
@@ -1712,6 +1771,19 @@
 		write_el1_ctx_gcs(ctx, gcspr_el1, read_gcspr_el1());
 		write_el1_ctx_gcs(ctx, gcspr_el0, read_gcspr_el0());
 	}
+
+	if (is_feat_the_supported()) {
+		write_el1_ctx_the_sysreg128(ctx, rcwmask_el1, read_rcwmask_el1());
+		write_el1_ctx_the_sysreg128(ctx, rcwsmask_el1, read_rcwsmask_el1());
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el1_ctx_sctlr2(ctx, sctlr2_el1, read_sctlr2_el1());
+	}
+
+	if (is_feat_ls64_accdata_supported()) {
+		write_el1_ctx_ls64(ctx, accdata_el1, read_accdata_el1());
+	}
 }
 
 static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
@@ -1807,6 +1879,19 @@
 		write_gcspr_el1(read_el1_ctx_gcs(ctx, gcspr_el1));
 		write_gcspr_el0(read_el1_ctx_gcs(ctx, gcspr_el0));
 	}
+
+	if (is_feat_the_supported()) {
+		write_rcwmask_el1(read_el1_ctx_the(ctx, rcwmask_el1));
+		write_rcwsmask_el1(read_el1_ctx_the(ctx, rcwsmask_el1));
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el1(read_el1_ctx_sctlr2(ctx, sctlr2_el1));
+	}
+
+	if (is_feat_ls64_accdata_supported()) {
+		write_accdata_el1(read_el1_ctx_ls64(ctx, accdata_el1));
+	}
 }
 
 /*******************************************************************************
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index dde0266..f951654 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -16,11 +16,13 @@
 
 	/*
 	 * MDCR_EL3.SBRBE = 0b01
-	 *
 	 * Allows BRBE usage in non-secure world and prohibited in
 	 * secure world.
+	 *
+	 * MDCR_EL3.{E3BREW, E3BREC} = 0b00
+	 * Branch recording at EL3 is disabled
 	 */
-	mdcr_el3_val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
-	mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
+	mdcr_el3_val &= ~((MDCR_SBRBE(MDCR_SBRBE_ALL)) | MDCR_E3BREW_BIT | MDCR_E3BREC_BIT);
+	mdcr_el3_val |= (MDCR_SBRBE(MDCR_SBRBE_NS));
 	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
diff --git a/lib/extensions/fpmr/fpmr.c b/lib/extensions/fpmr/fpmr.c
new file mode 100644
index 0000000..8e37e7a
--- /dev/null
+++ b/lib/extensions/fpmr/fpmr.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/fpmr.h>
+
+void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
+{
+	u_register_t reg;
+
+	/* Disable Floating point Trap in CPTR_EL3. */
+	reg = per_world_ctx->ctx_cptr_el3;
+	reg &= ~TFP_BIT;
+	per_world_ctx->ctx_cptr_el3 = reg;
+}
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d653222..d7df267 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,26 +9,10 @@
 #include <arch.h>
 #include <arch_features.h>
 #include <arch_helpers.h>
-#include <lib/el3_runtime/pubsub.h>
 #include <lib/extensions/spe.h>
 
 #include <plat/common/platform.h>
 
-typedef struct spe_ctx {
-	u_register_t pmblimitr_el1;
-} spe_ctx_t;
-
-static struct spe_ctx spe_ctxs[PLATFORM_CORE_COUNT];
-
-static inline void psb_csync(void)
-{
-	/*
-	 * The assembler does not yet understand the psb csync mnemonic
-	 * so use the equivalent hint instruction.
-	 */
-	__asm__ volatile("hint #17");
-}
-
 void spe_enable(cpu_context_t *ctx)
 {
 	el3_state_t *state = get_el3state_ctx(ctx);
@@ -58,18 +42,14 @@
 	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
-	 * MDCR_EL3.NSPB: Clear these bits to disable SPE feature, as it was enabled
-	 * for Non-secure state only. After clearing these bits Secure state owns
-	 * the Profiling Buffer and accesses to Statistical Profiling and Profiling
-	 * Buffer control registers at EL2 and EL1 generate Trap exceptions to EL3
-	 *
-	 * MDCR_EL3.NSPBE: Don't care as it was cleared during spe_enable and setting
-	 * this to 1 does not make sense as NSPBE{1} and NSPB{0b0x} is RESERVED.
+	 * MDCR_EL3.{NSPB,NSPBE} = 0b00, 0b0
+	 *  Disable access of profiling buffer control registers from lower ELs
+	 *  in any security state. Secure state owns the buffer.
 	 *
 	 * MDCR_EL3.EnPMSN (ARM v8.7): Clear the bit to trap access of PMSNEVFR_EL1
 	 * from EL2/EL1 to EL3.
 	 */
-	mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT);
+	mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_NSPBE_BIT | MDCR_EnPMSN_BIT);
 	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
@@ -90,63 +70,3 @@
 	v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
 	write_mdcr_el2(v);
 }
-
-void spe_stop(void)
-{
-	uint64_t v;
-
-	/* Drain buffered data */
-	psb_csync();
-	dsbnsh();
-
-	/* Disable profiling buffer */
-	v = read_pmblimitr_el1();
-	v &= ~(1ULL << 0);
-	write_pmblimitr_el1(v);
-	isb();
-}
-
-static void *spe_drain_buffers_hook(const void *arg)
-{
-	if (!is_feat_spe_supported())
-		return (void *)-1;
-
-	/* Drain buffered data */
-	psb_csync();
-	dsbnsh();
-
-	return (void *)0;
-}
-
-static void *spe_context_save(const void *arg)
-{
-	unsigned int core_pos;
-	struct spe_ctx *ctx;
-
-	if (is_feat_spe_supported()) {
-		core_pos = plat_my_core_pos();
-		ctx = &spe_ctxs[core_pos];
-		ctx->pmblimitr_el1 = read_pmblimitr_el1();
-	}
-
-	return NULL;
-}
-
-static void *spe_context_restore(const void *arg)
-{
-	unsigned int core_pos;
-	struct spe_ctx *ctx;
-
-	if (is_feat_spe_supported()) {
-		core_pos = plat_my_core_pos();
-		ctx = &spe_ctxs[core_pos];
-		write_pmblimitr_el1(ctx->pmblimitr_el1);
-	}
-
-	return NULL;
-}
-
-SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
-
-SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, spe_context_save);
-SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, spe_context_restore);
diff --git a/lib/extensions/sysreg128/sysreg128.S b/lib/extensions/sysreg128/sysreg128.S
new file mode 100644
index 0000000..08cff2f
--- /dev/null
+++ b/lib/extensions/sysreg128/sysreg128.S
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <lib/extensions/sysreg128.h>
+
+        .global read_par_el1
+        .global write_par_el1
+        .global read_ttbr0_el1
+        .global write_ttbr0_el1
+        .global read_ttbr1_el1
+        .global write_ttbr1_el1
+        .global read_ttbr0_el2
+        .global write_ttbr0_el2
+        .global read_ttbr1_el2
+        .global write_ttbr1_el2
+        .global read_vttbr_el2
+        .global write_vttbr_el2
+        .global read_rcwmask_el1
+        .global write_rcwmask_el1
+        .global read_rcwsmask_el1
+        .global write_rcwsmask_el1
+
+/*
+ * _mrrs - Move System register to two adjacent general-purpose
+ * registers.
+ * Instruction: MRRS <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _mrrs regins:req
+#if ENABLE_FEAT_D128 == 2
+        mrs     x0, ID_AA64MMFR3_EL1
+        tst     x0, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+        bne     1f
+        /* If FEAT_D128 is not implemented then use mrs */
+        .inst   0xD5300000 | (\regins)
+        ret
+#endif
+1:
+        .inst   0xD5700000 | (\regins)
+        ret
+.endm
+
+/*
+ * _msrr - Move two adjacent general-purpose registers to System register.
+ * Instruction: MSRR (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _msrr regins:req
+        /* If FEAT_D128 is not implemented use msr, dont tamper
+         * x0, x1 as they maybe used for mrrs */
+#if ENABLE_FEAT_D128 == 2
+        mrs     x2, ID_AA64MMFR3_EL1
+        tst     x2, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+        bne     1f
+        /* If FEAT_D128 is not implemented then use msr */
+        .inst   0xD5100000 | (\regins)
+        ret
+#endif
+1:
+        .inst   0xD5500000 | (\regins)
+        ret
+.endm
+
+func read_par_el1
+        _mrrs   0x87400 /* S3_0_C7_C4_0 */
+endfunc read_par_el1
+
+func write_par_el1
+        _msrr   0x87400
+endfunc write_par_el1
+
+func read_ttbr0_el1
+        _mrrs   0x82000 /* S3_0_C2_C0_0 */
+endfunc read_ttbr0_el1
+
+func write_ttbr0_el1
+        _msrr 0x82000
+endfunc write_ttbr0_el1
+
+func read_ttbr1_el1
+        _mrrs 0x82020 /* S3_0_C2_C0_1 */
+endfunc read_ttbr1_el1
+
+func write_ttbr1_el1
+        _msrr 0x82020
+endfunc write_ttbr1_el1
+
+func read_ttbr0_el2
+        _mrrs 0xC2000 /* S3_4_C2_C0_0 */
+endfunc read_ttbr0_el2
+
+func write_ttbr0_el2
+        _msrr 0xC2000
+endfunc write_ttbr0_el2
+
+func read_ttbr1_el2
+        _mrrs 0xC2020 /* S3_4_C2_C0_1 */
+endfunc read_ttbr1_el2
+
+func write_ttbr1_el2
+        _msrr 0xC2020
+endfunc write_ttbr1_el2
+
+func read_vttbr_el2
+        _mrrs 0xC2100 /* S3_4_C2_C1_0 */
+endfunc read_vttbr_el2
+
+func write_vttbr_el2
+        _msrr 0xC2100
+endfunc write_vttbr_el2
+
+func read_rcwmask_el1
+        _mrrs 0x8D0C0 /* S3_0_C13_C0_6 */
+endfunc read_rcwmask_el1
+
+func write_rcwmask_el1
+        _msrr 0x8D0C0
+endfunc write_rcwmask_el1
+
+func read_rcwsmask_el1
+        _mrrs 0x8D060 /* S3_0_C13_C0_3 */
+endfunc read_rcwsmask_el1
+
+func write_rcwsmask_el1
+        _msrr 0x8D060
+endfunc write_rcwsmask_el1
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index 8c1c421..24d88ae 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,18 +7,8 @@
 #include <arch.h>
 #include <arch_features.h>
 #include <arch_helpers.h>
-#include <lib/el3_runtime/pubsub.h>
 #include <lib/extensions/trbe.h>
 
-static void tsb_csync(void)
-{
-	/*
-	 * The assembler does not yet understand the tsb csync mnemonic
-	 * so use the equivalent hint instruction.
-	 */
-	__asm__ volatile("hint #18");
-}
-
 void trbe_enable(cpu_context_t *ctx)
 {
 	el3_state_t *state = get_el3state_ctx(ctx);
@@ -45,13 +35,9 @@
 	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
-	 * MDCR_EL3.NSTBE = 0b0
-	 *  Trace Buffer owning Security state is secure state. If FEAT_RME
-	 *  is not implemented, this field is RES0.
-	 *
-	 * MDCR_EL3.NSTB = 0b00
-	 *  Clear these bits to disable access of trace buffer control registers
-	 *  from lower ELs in any security state.
+	 * MDCR_EL3.{NSTBE,NSTB} = 0b0, 0b00
+	 *  Disable access of trace buffer control registers from lower ELs in
+	 *  any security state. Secure state owns the buffer.
 	 */
 	mdcr_el3_val &= ~(MDCR_NSTB(MDCR_NSTB_EL1));
 	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
@@ -68,21 +54,3 @@
 	 */
 	write_mdcr_el2(read_mdcr_el2() & ~MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
 }
-
-static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
-{
-	if (is_feat_trbe_supported()) {
-		/*
-		 * Before switching from normal world to secure world
-		 * the trace buffers need to be drained out to memory. This is
-		 * required to avoid an invalid memory access when TTBR is switched
-		 * for entry to S-EL1.
-		 */
-		tsb_csync();
-		dsbnsh();
-	}
-
-	return (void *)0;
-}
-
-SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook);
diff --git a/lib/hob/hob.c b/lib/hob/hob.c
new file mode 100644
index 0000000..60d8571
--- /dev/null
+++ b/lib/hob/hob.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2006-2014, Intel Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <arch.h>
+#include <common/debug.h>
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/utils_def.h>
+
+#define ALIGN_UP(x, a)		((x + (a - 1)) & ~(a - 1))
+
+static void *_create_hob(struct efi_hob_handoff_info_table *hob_table,
+		uint16_t hob_type, uint16_t hob_length)
+{
+	size_t free_mem_size;
+	struct efi_hob_generic_header *new_hob;
+	struct efi_hob_generic_header *hob_end;
+
+	if ((hob_table == NULL) || (hob_length == 0)) {
+		return NULL;
+	}
+
+	hob_length = ALIGN_UP(hob_length, 8);
+	free_mem_size = hob_table->efi_free_memory_top - hob_table->efi_free_memory_bottom;
+
+	/**
+	 * hob_length already including sizeof(efi_hob_generic_header).
+	 * See the each export interface create_xxx_hob.
+	 */
+	if ((size_t) hob_length > free_mem_size) {
+		return NULL;
+	}
+
+	new_hob = (struct efi_hob_generic_header *) hob_table->efi_end_of_hob_list;
+	new_hob->hob_type = hob_type;
+	new_hob->hob_length = hob_length;
+	new_hob->reserved = 0x00;
+
+	hob_end = (struct efi_hob_generic_header *) (hob_table->efi_end_of_hob_list + hob_length);
+	hob_end->hob_type = EFI_HOB_TYPE_END_OF_HOB_LIST;
+	hob_end->hob_length = sizeof(struct efi_hob_generic_header);
+	hob_end->reserved = 0x00;
+
+	hob_table->efi_end_of_hob_list = (efi_physical_address_t) hob_end;
+	hob_table->efi_free_memory_bottom = (efi_physical_address_t) (hob_end + 1);
+
+	return new_hob;
+}
+
+/*
+ * Create PHIT HOB list.
+ *
+ * On success, return the address PHIT HOB list
+ * On error, return NULL.
+ *
+ * efi_memory_begin
+ *   Base address for partition.
+ * efi_memory_length
+ *   Size of memory for patition.
+ * efi_free_memory_bottom
+ *   Base address PHIT HOB list can be allocated
+ * efi_free_memory_length.
+ *   Maximum size of PHIT HOB list can have
+ */
+struct efi_hob_handoff_info_table *create_hob_list(
+		efi_physical_address_t efi_memory_begin, size_t efi_memory_length,
+		efi_physical_address_t efi_free_memory_bottom, size_t efi_free_memory_length)
+{
+	struct efi_hob_handoff_info_table *hob_table;
+	struct efi_hob_generic_header *hob_end;
+
+	if ((efi_memory_begin == 0) || (efi_free_memory_bottom == 0) ||
+			(efi_memory_length == 0) || (efi_free_memory_length == 0)) {
+		return NULL;
+	}
+
+	hob_table = (struct efi_hob_handoff_info_table *) efi_free_memory_bottom;
+	hob_end = (struct efi_hob_generic_header *) (hob_table + 1);
+
+	hob_table->header.hob_type = EFI_HOB_TYPE_HANDOFF;
+	hob_table->header.hob_length = sizeof(struct efi_hob_handoff_info_table);
+	hob_table->header.reserved = 0;
+
+	hob_end->hob_type = EFI_HOB_TYPE_END_OF_HOB_LIST;
+	hob_end->hob_length = sizeof(struct efi_hob_generic_header);
+	hob_end->reserved = 0;
+
+	hob_table->version = EFI_HOB_HANDOFF_TABLE_VERSION;
+	hob_table->boot_mode = EFI_BOOT_WITH_FULL_CONFIGURATION;
+
+	hob_table->efi_memory_top = efi_memory_begin + efi_memory_length;
+	hob_table->efi_memory_bottom = efi_memory_begin;
+	hob_table->efi_free_memory_top = efi_memory_begin + efi_free_memory_length;
+	hob_table->efi_free_memory_bottom = (efi_physical_address_t) (hob_end + 1);
+	hob_table->efi_end_of_hob_list = (efi_physical_address_t) hob_end;
+
+	return hob_table;
+}
+
+/*
+ * Create resource description HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ *   Address of PHIT HOB list
+ * resource_type
+ *   Resource type see EFI_RESOURCE_* in the include/lib/hob/efi_types.h
+ * resource_attribute
+ *   Resource attribute see EFI_RESOURCE_ATTRIBUTES_*
+ *   in the include/lib/hob/efi_types.h
+ * phy_addr_start
+ *   Physical base address of resource
+ * resource_length
+ *   Size of resource
+ */
+int create_resource_descriptor_hob(
+		struct efi_hob_handoff_info_table *hob_table,
+		efi_resource_type_t resource_type,
+		efi_resource_attribute_type_t resource_attribute,
+		efi_physical_address_t phy_addr_start,
+		uint64_t resource_length)
+{
+	struct efi_hob_resource_descriptor *rd_hop;
+
+	rd_hop = _create_hob(hob_table, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
+			sizeof(struct efi_hob_resource_descriptor));
+
+	if (rd_hop == NULL) {
+		ERROR("No space for creating resource descriptor type hob...\n");
+		return -ENOMEM;
+	}
+
+	rd_hop->resource_type = resource_type;
+	rd_hop->resource_attribute = resource_attribute;
+	rd_hop->physical_start = phy_addr_start;
+	rd_hop->resource_length = resource_length;
+	memset(&rd_hop->owner, 0, sizeof(struct efi_guid));
+
+	return 0;
+}
+
+/*
+ * Create GUID HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ *   Address of PHIT HOB list
+ * guid
+ *   guid.
+ * data length
+ *   Size of data
+ * data
+ *   Data
+ */
+int create_guid_hob(struct efi_hob_handoff_info_table *hob_table,
+		struct efi_guid *guid, uint16_t data_length, void **data)
+{
+	struct efi_hob_guid_type *guid_hob;
+	uint16_t hob_length;
+
+	hob_length = data_length + sizeof(struct efi_hob_guid_type);
+
+	if ((guid == NULL) || (data == NULL) || (hob_length < data_length)) {
+		return -EINVAL;
+	}
+
+	guid_hob = _create_hob(hob_table, EFI_HOB_TYPE_GUID_EXTENSION, hob_length);
+	if (guid_hob == NULL) {
+		ERROR("No space for creating guid type hob...\n");
+		return -ENOMEM;
+	}
+
+	memcpy(&guid_hob->name, guid, sizeof(struct efi_guid));
+
+	*data = (void *) (guid_hob + 1);
+
+	return 0;
+}
+
+/*
+ * Create Firmware Volume HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ *   Address of PHIT HOB list
+ * base_addr
+ *   Base address of firmware volume
+ * size
+ *   Size of Firmware Volume
+ */
+int create_fv_hob(struct efi_hob_handoff_info_table *hob_table,
+		efi_physical_address_t base_addr, uint64_t size)
+{
+	struct efi_hob_firmware_volume *fv_hob;
+
+	fv_hob = _create_hob(hob_table, EFI_HOB_TYPE_FV,
+			sizeof(struct efi_hob_firmware_volume));
+	if (fv_hob == NULL) {
+		ERROR("No space for creating fv type hob...\n");
+		return -ENOMEM;
+	}
+
+	fv_hob->base_address = base_addr;
+	fv_hob->length = size;
+
+	return 0;
+}
diff --git a/lib/hob/hob.mk b/lib/hob/hob.mk
new file mode 100644
index 0000000..332738b
--- /dev/null
+++ b/lib/hob/hob.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+HOB_LIST_SOURCES	+=	$(addprefix lib/hob/,	\
+				hob.c)
+
+INCLUDES	+=	-Iinclude/lib/hob
+
+BL31_SOURCES	+=	$(HOB_LIST_SOURCES)
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index 3b77ab2..cca08c1 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <asm_macros.S>
 #include <assert_macros.S>
+#include <cpu_macros.S>
 #include <lib/psci/psci.h>
 #include <platform_def.h>
 
@@ -124,9 +125,8 @@
  * -----------------------------------------------------------------------
  */
 func psci_power_down_wfi
-#if ERRATA_A510_2684597
-	bl apply_cpu_pwr_dwn_errata
-#endif
+	apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597
+
 	dsb	sy		// ensure write buffer empty
 1:
 	wfi
diff --git a/lib/psci/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
deleted file mode 100644
index 89e3e12..0000000
--- a/lib/psci/aarch64/runtime_errata.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include <cortex_a510.h>
-#include <cpu_macros.S>
-
-/*
- * void apply_cpu_pwr_dwn_errata(void);
- *
- * This function applies various CPU errata during power down.
- */
-	.globl apply_cpu_pwr_dwn_errata
-func apply_cpu_pwr_dwn_errata
-	mov	x19, x30
-	bl      cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A510_2684597
-	bl erratum_cortex_a510_2684597_wa
-#endif
-
-	ret	x19
-endfunc apply_cpu_pwr_dwn_errata
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 375cdba..93d71b8 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,8 @@
 #include <drivers/delay_timer.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/extensions/spe.h>
+#include <lib/pmf/pmf.h>
+#include <lib/runtime_instr.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
@@ -170,9 +172,9 @@
  * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
  * otherwise.
  ******************************************************************************/
-static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
+static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int my_idx, unsigned int end_pwrlvl)
 {
-	unsigned int my_idx, lvl;
+	unsigned int lvl;
 	unsigned int parent_idx = 0;
 	unsigned int cpu_start_idx, ncpus, cpu_idx;
 	plat_local_state_t local_state;
@@ -181,7 +183,6 @@
 		return true;
 	}
 
-	my_idx = plat_my_core_pos();
 	parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
 	for (lvl = PSCI_CPU_PWR_LVL + U(1); lvl < end_pwrlvl; lvl++) {
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
@@ -212,11 +213,9 @@
  * turned OFF and the current CPU is the last running CPU in the system.
  * Returns true, if the current CPU is the last ON CPU or false otherwise.
  ******************************************************************************/
-bool psci_is_last_on_cpu(void)
+bool psci_is_last_on_cpu(unsigned int my_idx)
 {
-	unsigned int cpu_idx, my_idx = plat_my_core_pos();
-
-	for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
+	for (unsigned int cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
 		if (cpu_idx == my_idx) {
 			assert(psci_get_aff_info_state() == AFF_STATE_ON);
 			continue;
@@ -260,13 +259,9 @@
 
 	/*
 	 * Assume that this cpu was suspended and retrieve its target power
-	 * level. If it is invalid then it could only have been turned off
-	 * earlier. PLAT_MAX_PWR_LVL will be the highest power level a
-	 * cpu can be turned off to.
+	 * level. If it wasn't, the cpu is off so this will be PLAT_MAX_PWR_LVL.
 	 */
 	pwrlvl = psci_get_suspend_pwrlvl();
-	if (pwrlvl == PSCI_INVALID_PWR_LVL)
-		pwrlvl = PLAT_MAX_PWR_LVL;
 	assert(pwrlvl < PSCI_INVALID_PWR_LVL);
 	return pwrlvl;
 }
@@ -428,14 +423,14 @@
  * function will be called after a cpu is powered on to find the local state
  * each power domain has emerged from.
  *****************************************************************************/
-void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_get_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				      psci_power_state_t *target_state)
 {
 	unsigned int parent_idx, lvl;
 	plat_local_state_t *pd_state = target_state->pwr_domain_state;
 
 	pd_state[PSCI_CPU_PWR_LVL] = psci_get_cpu_local_state();
-	parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
+	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 
 	/* Copy the local power state from node to state_info */
 	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
@@ -454,7 +449,7 @@
  * enter. This function will be called after coordination of requested power
  * states has been done for each power level.
  *****************************************************************************/
-void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_set_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				      const psci_power_state_t *target_state)
 {
 	unsigned int parent_idx, lvl;
@@ -468,7 +463,7 @@
 	 */
 	psci_flush_cpu_data(psci_svc_cpu_data.local_state);
 
-	parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
+	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 
 	/* Copy the local_state from state_info */
 	for (lvl = 1U; lvl <= end_pwrlvl; lvl++) {
@@ -500,9 +495,9 @@
  * affinity info state, target power state and requested power state for the
  * current CPU and all its ancestor power domains to RUN.
  *****************************************************************************/
-void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl)
+void psci_set_pwr_domains_to_run(unsigned int cpu_idx, unsigned int end_pwrlvl)
 {
-	unsigned int parent_idx, cpu_idx = plat_my_core_pos(), lvl;
+	unsigned int parent_idx, lvl;
 	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 
 	/* Reset the local_state to RUN for the non cpu power domains. */
@@ -544,10 +539,10 @@
  * This function will only be invoked with data cache enabled and while
  * powering down a core.
  *****************************************************************************/
-void psci_do_state_coordination(unsigned int end_pwrlvl,
+void psci_do_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				psci_power_state_t *state_info)
 {
-	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+	unsigned int lvl, parent_idx;
 	unsigned int start_idx;
 	unsigned int ncpus;
 	plat_local_state_t target_state, *req_states;
@@ -620,11 +615,11 @@
  * This function will only be invoked with data cache enabled and while
  * powering down a core.
  *****************************************************************************/
-int psci_validate_state_coordination(unsigned int end_pwrlvl,
+int psci_validate_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				     psci_power_state_t *state_info)
 {
 	int rc = PSCI_E_SUCCESS;
-	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+	unsigned int lvl, parent_idx;
 	unsigned int start_idx;
 	unsigned int ncpus;
 	plat_local_state_t target_state, *req_states;
@@ -674,7 +669,7 @@
 	 * specified power level.
 	 */
 	lvl = state_info->last_at_pwrlvl;
-	if (!psci_is_last_cpu_to_idle_at_pwrlvl(lvl)) {
+	if (!psci_is_last_cpu_to_idle_at_pwrlvl(cpu_idx, lvl)) {
 		rc = PSCI_E_DENIED;
 	}
 
@@ -1004,7 +999,7 @@
 	 */
 	psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
 
-	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
+	psci_get_target_local_pwr_states(cpu_idx, end_pwrlvl, &state_info);
 
 #if ENABLE_PSCI_STAT
 	plat_psci_stat_accounting_stop(&state_info);
@@ -1025,7 +1020,7 @@
 	if (psci_get_aff_info_state() == AFF_STATE_ON_PENDING)
 		psci_cpu_on_finish(cpu_idx, &state_info);
 	else
-		psci_cpu_suspend_finish(cpu_idx, &state_info);
+		psci_cpu_suspend_to_powerdown_finish(cpu_idx, &state_info);
 
 	/*
 	 * Generic management: Now we just need to retrieve the
@@ -1038,16 +1033,10 @@
 	 * Set the requested and target state of this CPU and all the higher
 	 * power domains which are ancestors of this CPU to run.
 	 */
-	psci_set_pwr_domains_to_run(end_pwrlvl);
+	psci_set_pwr_domains_to_run(cpu_idx, end_pwrlvl);
 
 #if ENABLE_PSCI_STAT
-	/*
-	 * Update PSCI stats.
-	 * Caches are off when writing stats data on the power down path.
-	 * Since caches are now enabled, it's necessary to do cache
-	 * maintenance before reading that same data.
-	 */
-	psci_stats_update_pwr_up(end_pwrlvl, &state_info);
+	psci_stats_update_pwr_up(cpu_idx, end_pwrlvl, &state_info);
 #endif
 
 	/*
@@ -1169,7 +1158,16 @@
  ******************************************************************************/
 void psci_pwrdown_cpu(unsigned int power_level)
 {
-	psci_do_manage_extensions();
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+	/*
+	 * Flush cache line so that even if CPU power down happens
+	 * the timestamp update is reflected in memory.
+	 */
+	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		RT_INSTR_ENTER_CFLUSH,
+		PMF_CACHE_MAINT);
+#endif
 
 #if HW_ASSISTED_COHERENCY
 	/*
@@ -1190,6 +1188,12 @@
 	 */
 	psci_do_pwrdown_cache_maintenance(power_level);
 #endif
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		RT_INSTR_EXIT_CFLUSH,
+		PMF_NO_CACHE_MAINT);
+#endif
 }
 
 /*******************************************************************************
@@ -1202,15 +1206,11 @@
  * The function returns 'PSCI_E_DENIED' if some cores failed to stop within the
  * given timeout.
  ******************************************************************************/
-int psci_stop_other_cores(unsigned int wait_ms,
+int psci_stop_other_cores(unsigned int this_cpu_idx, unsigned int wait_ms,
 				   void (*stop_func)(u_register_t mpidr))
 {
-	unsigned int idx, this_cpu_idx;
-
-	this_cpu_idx = plat_my_core_pos();
-
 	/* Invoke stop_func for each core */
-	for (idx = 0U; idx < psci_plat_core_count; idx++) {
+	for (unsigned int idx = 0U; idx < psci_plat_core_count; idx++) {
 		/* skip current CPU */
 		if (idx == this_cpu_idx) {
 			continue;
@@ -1224,11 +1224,11 @@
 
 	/* Need to wait for other cores to shutdown */
 	if (wait_ms != 0U) {
-		while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu())) {
+		while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu(this_cpu_idx))) {
 			mdelay(1U);
 		}
 
-		if (!psci_is_last_on_cpu()) {
+		if (!psci_is_last_on_cpu(this_cpu_idx)) {
 			WARN("Failed to stop all cores!\n");
 			psci_print_power_domain_map();
 			return PSCI_E_DENIED;
@@ -1246,16 +1246,15 @@
  * This API has following differences with psci_is_last_on_cpu
  *  1. PSCI states are locked
  ******************************************************************************/
-bool psci_is_last_on_cpu_safe(void)
+bool psci_is_last_on_cpu_safe(unsigned int this_core)
 {
-	unsigned int this_core = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
 	psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
 
 	psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
 
-	if (!psci_is_last_on_cpu()) {
+	if (!psci_is_last_on_cpu(this_core)) {
 		psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
 		return false;
 	}
@@ -1272,9 +1271,8 @@
  * This API has following differences with psci_are_all_cpus_on
  *  1. PSCI states are locked
  ******************************************************************************/
-bool psci_are_all_cpus_on_safe(void)
+bool psci_are_all_cpus_on_safe(unsigned int this_core)
 {
-	unsigned int this_core = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
 	psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
@@ -1290,20 +1288,3 @@
 
 	return true;
 }
-
-/*******************************************************************************
- * This function performs architectural feature specific management.
- * It ensures the architectural features are disabled during cpu
- * power off/suspend operations.
- ******************************************************************************/
-void psci_do_manage_extensions(void)
-{
-	/*
-	 * On power down we need to disable statistical profiling extensions
-	 * before exiting coherency.
-	 */
-	if (is_feat_spe_supported()) {
-		spe_stop();
-	}
-
-}
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index c71580f..527ad3a 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,8 +21,7 @@
 				lib/psci/${ARCH}/psci_helpers.S
 
 ifeq (${ARCH}, aarch64)
-PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
-				lib/psci/aarch64/runtime_errata.S
+PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index a015531..7ac0e02 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -59,8 +59,8 @@
 	entry_point_info_t ep;
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 	plat_local_state_t cpu_pd_state;
-#if PSCI_OS_INIT_MODE
 	unsigned int cpu_idx = plat_my_core_pos();
+#if PSCI_OS_INIT_MODE
 	plat_local_state_t prev[PLAT_MAX_PWR_LVL];
 #endif
 
@@ -145,7 +145,7 @@
 		plat_psci_stat_accounting_stop(&state_info);
 
 		/* Update PSCI stats */
-		psci_stats_update_pwr_up(PSCI_CPU_PWR_LVL, &state_info);
+		psci_stats_update_pwr_up(cpu_idx, PSCI_CPU_PWR_LVL, &state_info);
 #endif
 
 		return PSCI_E_SUCCESS;
@@ -167,7 +167,8 @@
 	 * might return if the power down was abandoned for any reason, e.g.
 	 * arrival of an interrupt
 	 */
-	rc = psci_cpu_suspend_start(&ep,
+	rc = psci_cpu_suspend_start(cpu_idx,
+				    &ep,
 				    target_pwrlvl,
 				    &state_info,
 				    is_power_down_state);
@@ -181,9 +182,10 @@
 	int rc;
 	psci_power_state_t state_info;
 	entry_point_info_t ep;
+	unsigned int cpu_idx = plat_my_core_pos();
 
 	/* Check if the current CPU is the last ON CPU in the system */
-	if (!psci_is_last_on_cpu())
+	if (!psci_is_last_on_cpu(cpu_idx))
 		return PSCI_E_DENIED;
 
 	/* Validate the entry point and get the entry_point_info */
@@ -212,7 +214,8 @@
 	 * might return if the power down was abandoned for any reason, e.g.
 	 * arrival of an interrupt
 	 */
-	rc = psci_cpu_suspend_start(&ep,
+	rc = psci_cpu_suspend_start(cpu_idx,
+				    &ep,
 				    PLAT_MAX_PWR_LVL,
 				    &state_info,
 				    PSTATE_TYPE_POWERDOWN);
@@ -399,9 +402,11 @@
 		return PSCI_E_SUCCESS;
 	}
 
+	unsigned int this_core = plat_my_core_pos();
+
 	if (mode == PLAT_COORD) {
 		/* Check if the current CPU is the last ON CPU in the system */
-		if (!psci_is_last_on_cpu_safe()) {
+		if (!psci_is_last_on_cpu_safe(this_core)) {
 			return PSCI_E_DENIED;
 		}
 	}
@@ -411,8 +416,8 @@
 		 * Check if all CPUs in the system are ON or if the current
 		 * CPU is the last ON CPU in the system.
 		 */
-		if (!(psci_are_all_cpus_on_safe() ||
-		      psci_is_last_on_cpu_safe())) {
+		if (!(psci_are_all_cpus_on_safe(this_core) ||
+		      psci_is_last_on_cpu_safe(this_core))) {
 			return PSCI_E_DENIED;
 		}
 	}
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index f83753f..d40ee3f 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -102,25 +102,14 @@
 	 * it returns the negotiated state info for each power level upto
 	 * the end level specified.
 	 */
-	psci_do_state_coordination(end_pwrlvl, &state_info);
+	psci_do_state_coordination(idx, end_pwrlvl, &state_info);
 
 	/* Update the target state in the power domain nodes */
-	psci_set_target_local_pwr_states(end_pwrlvl, &state_info);
+	psci_set_target_local_pwr_states(idx, end_pwrlvl, &state_info);
 
 #if ENABLE_PSCI_STAT
 	/* Update the last cpu for each level till end_pwrlvl */
-	psci_stats_update_pwr_down(end_pwrlvl, &state_info);
-#endif
-
-#if ENABLE_RUNTIME_INSTRUMENTATION
-
-	/*
-	 * Flush cache line so that even if CPU power down happens
-	 * the timestamp update is reflected in memory.
-	 */
-	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
-		RT_INSTR_ENTER_CFLUSH,
-		PMF_CACHE_MAINT);
+	psci_stats_update_pwr_down(idx, end_pwrlvl, &state_info);
 #endif
 
 	/*
@@ -128,12 +117,6 @@
 	 */
 	psci_pwrdown_cpu(psci_find_max_off_lvl(&state_info));
 
-#if ENABLE_RUNTIME_INSTRUMENTATION
-	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
-		RT_INSTR_EXIT_CFLUSH,
-		PMF_NO_CACHE_MAINT);
-#endif
-
 	/*
 	 * Plat. management: Perform platform specific actions to turn this
 	 * cpu off e.g. exit cpu coherency, program the power controller etc.
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 2eb4a9b..6622755 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -295,19 +295,19 @@
 void psci_restore_req_local_pwr_states(unsigned int cpu_idx,
 				       plat_local_state_t *prev);
 #endif
-void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_get_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				      psci_power_state_t *target_state);
-void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_set_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				      const psci_power_state_t *target_state);
 int psci_validate_entry_point(entry_point_info_t *ep,
 			uintptr_t entrypoint, u_register_t context_id);
 void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
 				      unsigned int end_lvl,
 				      unsigned int *node_index);
-void psci_do_state_coordination(unsigned int end_pwrlvl,
+void psci_do_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				psci_power_state_t *state_info);
 #if PSCI_OS_INIT_MODE
-int psci_validate_state_coordination(unsigned int end_pwrlvl,
+int psci_validate_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
 				     psci_power_state_t *state_info);
 #endif
 void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
@@ -318,9 +318,9 @@
 			      unsigned int is_power_down_state);
 unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info);
 unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info);
-void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
+void psci_set_pwr_domains_to_run(unsigned int cpu_idx, unsigned int end_pwrlvl);
 void psci_print_power_domain_map(void);
-bool psci_is_last_on_cpu(void);
+bool psci_is_last_on_cpu(unsigned int my_idx);
 int psci_spd_migrate_info(u_register_t *mpidr);
 
 /*
@@ -343,12 +343,13 @@
 int psci_do_cpu_off(unsigned int end_pwrlvl);
 
 /* Private exported functions from psci_suspend.c */
-int psci_cpu_suspend_start(const entry_point_info_t *ep,
+int psci_cpu_suspend_start(unsigned int idx,
+			   const entry_point_info_t *ep,
 			   unsigned int end_pwrlvl,
 			   psci_power_state_t *state_info,
 			   unsigned int is_power_down_state);
 
-void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
 
 /* Private exported functions from psci_helpers.S */
 void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level);
@@ -360,9 +361,9 @@
 u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie);
 
 /* Private exported functions from psci_stat.c */
-void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_down(unsigned int cpu_idx, unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info);
-void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_up(unsigned int cpu_idx, unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info);
 u_register_t psci_stat_residency(u_register_t target_cpu,
 			unsigned int power_state);
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 6bf1ff4..a81ba4a 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,8 +68,8 @@
 		/* Set the Affinity Info for the cores as OFF */
 		svc_cpu_data->aff_info_state = AFF_STATE_OFF;
 
-		/* Invalidate the suspend level for the cpu */
-		svc_cpu_data->target_pwrlvl = PSCI_INVALID_PWR_LVL;
+		/* Default to the highest power level when the cpu is not suspending */
+		svc_cpu_data->target_pwrlvl = PLAT_MAX_PWR_LVL;
 
 		/* Set the power state to OFF state */
 		svc_cpu_data->local_state = PLAT_MAX_OFF_STATE;
@@ -202,6 +202,7 @@
 int __init psci_setup(const psci_lib_args_t *lib_args)
 {
 	const unsigned char *topology_tree;
+	unsigned int cpu_idx = plat_my_core_pos();
 
 	assert(VERIFY_PSCI_LIB_ARGS_V1(lib_args));
 
@@ -218,7 +219,7 @@
 	psci_update_pwrlvl_limits();
 
 	/* Populate the mpidr field of cpu node for this CPU */
-	psci_cpu_pd_nodes[plat_my_core_pos()].mpidr =
+	psci_cpu_pd_nodes[cpu_idx].mpidr =
 		read_mpidr() & MPIDR_AFFINITY_MASK;
 
 	psci_init_req_local_pwr_states();
@@ -227,7 +228,7 @@
 	 * Set the requested and target state of this CPU and all the higher
 	 * power domain levels for this CPU to run.
 	 */
-	psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL);
+	psci_set_pwr_domains_to_run(cpu_idx, PLAT_MAX_PWR_LVL);
 
 	(void) plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep,
 				   &psci_plat_pm_ops);
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index bedb816..1225557 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -73,11 +73,10 @@
  * This function will only be invoked with data cache enabled and while
  * powering down a core.
  ******************************************************************************/
-void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_down(unsigned int cpu_idx, unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info)
 {
 	unsigned int lvl, parent_idx;
-	unsigned int cpu_idx = plat_my_core_pos();
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
 	assert(state_info != NULL);
@@ -106,11 +105,10 @@
  * and NON-CPU power domains.
  * It is called with caches enabled and locks acquired(for NON-CPU domain)
  ******************************************************************************/
-void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_up(unsigned int cpu_idx, unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info)
 {
 	unsigned int lvl, parent_idx;
-	unsigned int cpu_idx = plat_my_core_pos();
 	int stat_idx;
 	plat_local_state_t local_state;
 	u_register_t residency;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index cb12b83..2aadbfd 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,42 +25,18 @@
  * This function does generic and platform specific operations after a wake-up
  * from standby/retention states at multiple power levels.
  ******************************************************************************/
-static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
-					     unsigned int end_pwrlvl)
+static void psci_cpu_suspend_to_standby_finish(unsigned int cpu_idx,
+					     unsigned int end_pwrlvl,
+					     psci_power_state_t *state_info)
 {
-	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
-	psci_power_state_t state_info;
-
-	/* Get the parent nodes */
-	psci_get_parent_pwr_domain_nodes(cpu_idx, end_pwrlvl, parent_nodes);
-
-	psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
-
-	/*
-	 * Find out which retention states this CPU has exited from until the
-	 * 'end_pwrlvl'. The exit retention state could be deeper than the entry
-	 * state as a result of state coordination amongst other CPUs post wfi.
-	 */
-	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
-
-#if ENABLE_PSCI_STAT
-	plat_psci_stat_accounting_stop(&state_info);
-	psci_stats_update_pwr_up(end_pwrlvl, &state_info);
-#endif
-
 	/*
 	 * Plat. management: Allow the platform to do operations
 	 * on waking up from retention.
 	 */
-	psci_plat_pm_ops->pwr_domain_suspend_finish(&state_info);
+	psci_plat_pm_ops->pwr_domain_suspend_finish(state_info);
 
-	/*
-	 * Set the requested and target state of this CPU and all the higher
-	 * power domain levels for this CPU to run.
-	 */
-	psci_set_pwr_domains_to_run(end_pwrlvl);
-
-	psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes);
+	/* This loses its meaning when not suspending, reset so it's correct for OFF */
+	psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL);
 }
 
 /*******************************************************************************
@@ -116,29 +92,12 @@
 	 */
 	cm_init_my_context(ep);
 
-#if ENABLE_RUNTIME_INSTRUMENTATION
-
-	/*
-	 * Flush cache line so that even if CPU power down happens
-	 * the timestamp update is reflected in memory.
-	 */
-	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
-		RT_INSTR_ENTER_CFLUSH,
-		PMF_CACHE_MAINT);
-#endif
-
 	/*
 	 * Arch. management. Initiate power down sequence.
 	 * TODO : Introduce a mechanism to query the cache level to flush
 	 * and the cpu-ops power down to perform from the platform.
 	 */
 	psci_pwrdown_cpu(max_off_lvl);
-
-#if ENABLE_RUNTIME_INSTRUMENTATION
-	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
-		RT_INSTR_EXIT_CFLUSH,
-		PMF_NO_CACHE_MAINT);
-#endif
 }
 
 /*******************************************************************************
@@ -159,14 +118,14 @@
  * the state transition has been done, no further error is expected and it is
  * not possible to undo any of the actions taken beyond that point.
  ******************************************************************************/
-int psci_cpu_suspend_start(const entry_point_info_t *ep,
+int psci_cpu_suspend_start(unsigned int idx,
+			   const entry_point_info_t *ep,
 			   unsigned int end_pwrlvl,
 			   psci_power_state_t *state_info,
 			   unsigned int is_power_down_state)
 {
 	int rc = PSCI_E_SUCCESS;
 	bool skip_wfi = false;
-	unsigned int idx = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
 	/*
@@ -202,7 +161,7 @@
 		 * This function validates the requested state info for
 		 * OS-initiated mode.
 		 */
-		rc = psci_validate_state_coordination(end_pwrlvl, state_info);
+		rc = psci_validate_state_coordination(idx, end_pwrlvl, state_info);
 		if (rc != PSCI_E_SUCCESS) {
 			skip_wfi = true;
 			goto exit;
@@ -214,7 +173,7 @@
 		 * it returns the negotiated state info for each power level upto
 		 * the end level specified.
 		 */
-		psci_do_state_coordination(end_pwrlvl, state_info);
+		psci_do_state_coordination(idx, end_pwrlvl, state_info);
 #if PSCI_OS_INIT_MODE
 	}
 #endif
@@ -230,11 +189,11 @@
 #endif
 
 	/* Update the target state in the power domain nodes */
-	psci_set_target_local_pwr_states(end_pwrlvl, state_info);
+	psci_set_target_local_pwr_states(idx, end_pwrlvl, state_info);
 
 #if ENABLE_PSCI_STAT
 	/* Update the last cpu for each level till end_pwrlvl */
-	psci_stats_update_pwr_down(end_pwrlvl, state_info);
+	psci_stats_update_pwr_down(idx, end_pwrlvl, state_info);
 #endif
 
 	if (is_power_down_state != 0U)
@@ -304,11 +263,32 @@
 	    PMF_NO_CACHE_MAINT);
 #endif
 
+	psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
+	/*
+	 * Find out which retention states this CPU has exited from until the
+	 * 'end_pwrlvl'. The exit retention state could be deeper than the entry
+	 * state as a result of state coordination amongst other CPUs post wfi.
+	 */
+	psci_get_target_local_pwr_states(idx, end_pwrlvl, state_info);
+
+#if ENABLE_PSCI_STAT
+	plat_psci_stat_accounting_stop(state_info);
+	psci_stats_update_pwr_up(idx, end_pwrlvl, state_info);
+#endif
+
 	/*
 	 * After we wake up from context retaining suspend, call the
 	 * context retaining suspend finisher.
 	 */
-	psci_suspend_to_standby_finisher(idx, end_pwrlvl);
+	psci_cpu_suspend_to_standby_finish(idx, end_pwrlvl, state_info);
+
+	/*
+	 * Set the requested and target state of this CPU and all the higher
+	 * power domain levels for this CPU to run.
+	 */
+	psci_set_pwr_domains_to_run(idx, end_pwrlvl);
+
+	psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes);
 
 	return rc;
 }
@@ -318,7 +298,7 @@
  * are called by the common finisher routine in psci_common.c. The `state_info`
  * is the psci_power_state from which this CPU has woken up from.
  ******************************************************************************/
-void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
 {
 	unsigned int counter_freq;
 	unsigned int max_off_lvl;
@@ -363,8 +343,8 @@
 		psci_spd_pm->svc_suspend_finish(max_off_lvl);
 	}
 
-	/* Invalidate the suspend level for the cpu */
-	psci_set_suspend_pwrlvl(PSCI_INVALID_PWR_LVL);
+	/* This loses its meaning when not suspending, reset so it's correct for OFF */
+	psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL);
 
 	PUBLISH_EVENT(psci_suspend_pwrdown_finish);
 }
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 3d2b850..01a0395 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -12,17 +12,26 @@
 BUILD_DIR   = $(BUILD_PLAT)/romlib
 LIB_DIR     = $(BUILD_PLAT)/lib
 WRAPPER_DIR = $(BUILD_PLAT)/libwrapper
-LIBS        = -lmbedtls -lfdt -lc
+LIBS        = $(LIB_DIR)/libfdt.a $(LIB_DIR)/libc.a
 INC         = $(INCLUDES:-I%=-I../../%)
 PPFLAGS     = $(INC) $(DEFINES) -P -x assembler-with-cpp -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld
 OBJS        = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
 MAPFILE     = $(BUILD_PLAT)/romlib/romlib.map
 
-ifneq ($(PLAT_DIR),)
-        WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
-                $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
+PROCESSED_JMPTBL = ../../$(PLAT_DIR)/jmptbl.i
 
-        WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
+# Determine if mbedtls is needed
+ifneq ($(filter $(CRYPTO_SUPPORT),1 2 3),)
+    PROCESSED_JMPTBL = $(BUILD_DIR)/jmptbl_processed.i
+    $(shell mkdir -p $(BUILD_DIR) && cat ../../$(PLAT_DIR)/jmptbl.i ../../$(PLAT_DIR)/jmptbl_mbedtls.i > $(BUILD_DIR)/jmptbl_processed.i)
+    LIBS += $(LIB_DIR)/libmbedtls.a
+endif
+
+ifneq ($(PLAT_DIR),)
+    # Generate wrapper sources and objects
+    WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+                $(WRAPPER_DIR) --list $(PROCESSED_JMPTBL)))
+    WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
 endif
 
 LDFLAGS := -Wl,--gc-sections -nostdlib
@@ -69,21 +78,21 @@
 	$(s)echo "  AR      $@"
 	$(q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
 
-$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+$(BUILD_DIR)/jmptbl.i: $(PROCESSED_JMPTBL) | $$(@D)/
 	$(s)echo "  PRE     $@"
 	$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
 
-$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+$(WRAPPER_SOURCES) $&: $(PROCESSED_JMPTBL) | $$(@D)/
 	$(s)echo "  WRP     $<"
 	$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
 
 $(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s | $$(@D)/
 
-$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+$(BUILD_DIR)/jmptbl.s: $(PROCESSED_JMPTBL) | $$(@D)/
 	$(s)echo "  TBL     $@"
 	$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
 
-$(BUILD_DIR)/romlib.ldflags: ../../$(PLAT_DIR)/jmptbl.i
+$(BUILD_DIR)/romlib.ldflags: $(PROCESSED_JMPTBL) | $$(@D)/
 	$(s)echo "  LDFLAGS $@"
 	$(q)$(ROMLIB_GEN) link-flags $< > $@
 
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
deleted file mode 100644
index 44751a2..0000000
--- a/lib/romlib/jmptbl.i
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# Format:
-# lib	function	[patch]
-# Add "patch" at the end of the line to patch a function. For example:
-# mbedtls	mbedtls_memory_buffer_alloc_init	patch
-# Holes can be introduced in the table by using a special keyword "reserved".
-# Example:
-# reserved	reserved
-# The jump table will contain an invalid instruction instead of branch
-
-rom	rom_lib_init
-fdt	fdt_getprop_namelen
-fdt	fdt_setprop_inplace
-fdt	fdt_check_header
-fdt	fdt_node_offset_by_compatible
-fdt     fdt_setprop_inplace_namelen_partial
-mbedtls	mbedtls_asn1_get_alg
-mbedtls	mbedtls_asn1_get_alg_null
-mbedtls	mbedtls_asn1_get_bitstring_null
-mbedtls	mbedtls_asn1_get_bool
-mbedtls	mbedtls_asn1_get_int
-mbedtls	mbedtls_asn1_get_tag
-mbedtls	mbedtls_free
-mbedtls	mbedtls_md
-mbedtls	mbedtls_md_get_size
-mbedtls	mbedtls_memory_buffer_alloc_init
-mbedtls	mbedtls_oid_get_md_alg
-mbedtls	mbedtls_oid_get_numeric_string
-mbedtls	mbedtls_oid_get_pk_alg
-mbedtls	mbedtls_oid_get_sig_alg
-mbedtls	mbedtls_pk_free
-mbedtls	mbedtls_pk_init
-mbedtls	mbedtls_pk_parse_subpubkey
-mbedtls	mbedtls_pk_verify_ext
-mbedtls	mbedtls_platform_set_snprintf
-mbedtls	mbedtls_x509_get_rsassa_pss_params
-mbedtls	mbedtls_x509_get_sig_alg
-mbedtls	mbedtls_md_info_from_type
-c	exit
-c	atexit
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index 8d82d25..07614a6 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -168,30 +168,29 @@
 	}
 
 	if (tl->signature != TRANSFER_LIST_SIGNATURE) {
-		ERROR("Bad transfer list signature %#" PRIx32 "\n",
-		      tl->signature);
+		ERROR("Bad transfer list signature 0x%x\n", tl->signature);
 		return TL_OPS_NON;
 	}
 
 	if (!tl->max_size) {
-		ERROR("Bad transfer list max size %#" PRIx32 "\n",
+		ERROR("Bad transfer list max size 0x%x\n",
 		      tl->max_size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->size > tl->max_size) {
-		ERROR("Bad transfer list size %#" PRIx32 "\n", tl->size);
+		ERROR("Bad transfer list size 0x%x\n", tl->size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->hdr_size != sizeof(struct transfer_list_header)) {
-		ERROR("Bad transfer list header size %#" PRIx32 "\n",
+		ERROR("Bad transfer list header size 0x%x\n",
 		      tl->hdr_size);
 		return TL_OPS_NON;
 	}
 
 	if (!transfer_list_verify_checksum(tl)) {
-		ERROR("Bad transfer list checksum %#" PRIx32 "\n",
+		ERROR("Bad transfer list checksum 0x%x\n",
 		      tl->checksum);
 		return TL_OPS_NON;
 	}
@@ -521,3 +520,22 @@
 	}
 	return (uint8_t *)entry + entry->hdr_size;
 }
+
+/*******************************************************************************
+ * Verifies that the transfer list has not already been initialized, then
+ * initializes it at the specified memory location.
+ *
+ * Return pointer to the transfer list or NULL on error
+ * *****************************************************************************/
+struct transfer_list_header *transfer_list_ensure(void *addr, size_t size)
+{
+	struct transfer_list_header *tl = NULL;
+
+	if (transfer_list_check_header(addr) == TL_OPS_ALL) {
+		return (struct transfer_list_header *)addr;
+	}
+
+	tl = transfer_list_init((void *)addr, size);
+
+	return tl;
+}
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index f4195f4..f207266 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -66,7 +66,7 @@
  */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101, PARANGE_0110
+	PARANGE_0101, PARANGE_0110, PARANGE_0111
 };
 
 static unsigned long long get_max_supported_pa(void)
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 18e001b..7321fd7 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -109,7 +109,7 @@
  */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101, PARANGE_0110
+	PARANGE_0101, PARANGE_0110, PARANGE_0111
 };
 
 unsigned long long xlat_arch_get_max_supported_pa(void)
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 675779f..3c9e136 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -83,14 +83,15 @@
 
 # Enable the features which are mandatory from ARCH version 8.8 and upwards.
 ifeq "8.8" "$(word 1, $(sort 8.8 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+armv8-8-a-feats		:= ENABLE_FEAT_MOPS
 # 8.7 Compliant
-armv8-7-a-feats         += ${armv8-7-a-feats}
+armv8-8-a-feats         += ${armv8-7-a-feats}
 FEAT_LIST               := ${armv8-8-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.9 and upwards.
 ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-armv8-9-a-feats         := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9
+armv8-9-a-feats         := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9 ENABLE_FEAT_SCTLR2
 # 8.8 Compliant
 armv8-9-a-feats         += ${armv8-8-a-feats}
 FEAT_LIST               := ${armv8-9-a-feats}
@@ -213,12 +214,23 @@
 ENABLE_FEAT_HCX			?=	0
 
 #----
+# 8.8
+#----
+
+# Flag to enable FEAT_MOPS (Standardization of Memory operations)
+# when INIT_UNUSED_NS_EL2 = 1
+ENABLE_FEAT_MOPS		?=	0
+
+#----
 # 8.9
 #----
 
 # Flag to enable access to TCR2 (FEAT_TCR2).
 ENABLE_FEAT_TCR2		?=	0
 
+# Flag to enable access to SCTLR2 (FEAT_SCTLR2).
+ENABLE_FEAT_SCTLR2		?=	0
+
 #
 ################################################################################
 # Optional Features defaulted to 0 or 2, if they are not enabled from
@@ -307,13 +319,6 @@
 # registers, by setting SCR_EL3.TRNDR.
 ENABLE_FEAT_RNG_TRAP			?=	0
 
-ifeq ($(CTX_INCLUDE_MTE_REGS),1)
-        $(warning CTX_INCLUDE_MTE_REGS option is deprecated, Check ENABLE_FEAT_MTE2 usage)
-endif
-ifneq ($(ENABLE_FEAT_MTE),)
-        $(warning ENABLE_FEAT_MTE option is deprecated, Check ENABLE_FEAT_MTE2 usage)
-endif
-
 # Enable FEAT_MTE2. This must be set to 1 if the platform wants
 # to use this feature and is enabled at ELX.
 ENABLE_FEAT_MTE2		        ?=	0
@@ -340,6 +345,16 @@
 # Flag to enable FEAT_FGT2 (Fine Granular Traps 2)
 ENABLE_FEAT_FGT2			?=	0
 
+# LoadStore64Bytes extension using the ACCDATA_EL1 system register
+ENABLE_FEAT_LS64_ACCDATA		?=	0
+
+#----
+# 8.8
+#----
+
+# Flag to enable FEAT_THE (Translation Hardening Extension)
+ENABLE_FEAT_THE				?=	0
+
 #----
 # 8.9
 #----
@@ -402,6 +417,15 @@
 # if FEAT_BRBE is implemented.
 ENABLE_BRBE_FOR_NS			?=	0
 
+# Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
+ENABLE_FEAT_FPMR			?=	0
+
+#----
+# 9.3
+#----
+# Flag to enable access to Arm v9.3 FEAT_D128 extension
+ENABLE_FEAT_D128			?=	0
+
 #----
 #9.4
 #----
diff --git a/make_helpers/build-rules.mk b/make_helpers/build-rules.mk
index d325b3a..959ff94 100644
--- a/make_helpers/build-rules.mk
+++ b/make_helpers/build-rules.mk
@@ -11,6 +11,7 @@
         include $(dir $(build-rules-mk))utilities.mk
 
         .SECONDEXPANSION:
+        .SUFFIXES:
 
         %/:
 		$(s)echo '  MD      '$(call escape-shell,$(abspath $@))
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
deleted file mode 100644
index 13acaae..0000000
--- a/make_helpers/build_env.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# This file contains the logic to identify and include any relevant
-# build environment specific make include files.
-
-ifndef BUILD_ENV_MK
-    BUILD_ENV_MK        :=      $(lastword $(MAKEFILE_LIST))
-
-    # Block possible built-in command definitions that are not fully portable.
-    # This traps occurences that need replacing with our OS portable macros
-    COPY                :=      $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
-    CP                  :=      $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
-    DEL                 :=      $$(error "Replace DEL with call to SHELL_DELETE.")
-    RD                  :=      $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
-    RM                  :=      $$(error "Replace RM with call to SHELL_DELETE.")
-    RMDIR               :=      $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
-
-    ENV_FILE_TO_INCLUDE := unix.mk
-    ifdef OSTYPE
-        ifneq ($(findstring ${OSTYPE}, cygwin),)
-            ENV_FILE_TO_INCLUDE := cygwin.mk
-        else
-            ifneq ($(findstring ${OSTYPE}, MINGW32 mingw msys),)
-                ENV_FILE_TO_INCLUDE := msys.mk
-            endif
-        endif
-    else
-        ifdef MSYSTEM
-            # Although the MINGW MSYS shell sets OSTYPE as msys in its environment,
-            # it does not appear in the GNU make view of environment variables.
-            # We use MSYSTEM as an alternative, as that is seen by make
-            ifneq ($(findstring ${MSYSTEM}, MINGW32 mingw msys),)
-                OSTYPE ?= msys
-                ENV_FILE_TO_INCLUDE := msys.mk
-            endif
-        else
-            ifdef OS
-                ifneq ($(findstring ${OS}, Windows_NT),)
-                    ENV_FILE_TO_INCLUDE := windows.mk
-                endif
-            endif
-        endif
-    endif
-    include $(dir $(lastword $(MAKEFILE_LIST)))${ENV_FILE_TO_INCLUDE}
-    ENV_FILE_TO_INCLUDE :=
-
-    ifndef SHELL_COPY
-        $(error "SHELL_COPY not defined for build environment.")
-    endif
-    ifndef SHELL_COPY_TREE
-        $(error "SHELL_COPY_TREE not defined for build environment.")
-    endif
-    ifndef SHELL_DELETE_ALL
-        $(error "SHELL_DELETE_ALL not defined for build environment.")
-    endif
-    ifndef SHELL_DELETE
-        $(error "SHELL_DELETE not defined for build environment.")
-    endif
-    ifndef SHELL_REMOVE_DIR
-        $(error "SHELL_REMOVE_DIR not defined for build environment.")
-    endif
-
-endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index f523074..b1b299c 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -96,6 +96,10 @@
 
 # Convenience function to check for a given compiler option. A call to
 # $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
+# NOTE: consider assigning to an immediately expanded temporary variable before
+# assigning. This is because variables like TF_CFLAGS are recursively expanded
+# and assigning this directly will cause it to be expanded every time the
+# variable is used, potentially thrashing multicore performance.
 define cc_option
 	$(shell if $($(ARCH)-cc) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
 endef
@@ -183,7 +187,7 @@
 
 define TOOL_ADD_IMG_PAYLOAD
 
-$(eval PRE_TOOL_FILTER := $($(call uppercase,$(1))_PRE_TOOL_FILTER))
+$(eval PRE_TOOL_FILTER := $($(1)_PRE_TOOL_FILTER))
 
 ifneq ($(PRE_TOOL_FILTER),)
 
@@ -220,7 +224,8 @@
 define TOOL_ADD_IMG
     # Build option to specify the image filename (SCP_BL2, BL33, etc)
     # This is the uppercase form of the first parameter
-    $(eval _V := $(call uppercase,$(1)))
+    $(eval BL := $(call uppercase,$(1)))
+    $(eval _V := $(BL))
 
     # $(check_$(1)_cmd) variable is executed in the check_$(1) target and also
     # is put into the ${CHECK_$(3)FIP_CMD} variable which is executed by the
@@ -235,10 +240,10 @@
 ifeq ($(4),1)
     $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
     $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
-    $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
+    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
 		$(ENC_BIN))
 else
-    $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
+    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
 endif
 
 .PHONY: check_$(1)
@@ -277,21 +282,22 @@
 # Auxiliary macros to build TF images from sources
 ################################################################################
 
-MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@ -MP
+MAKE_DEP = -Wp,-MD,$1 -MT $2 -MP
 
 
 # MAKE_C_LIB builds a C source file and generates the dependency file
 #   $(1) = output directory
 #   $(2) = source file (%.c)
 #   $(3) = library name
+#   $(4) = uppercase name of the library
 define MAKE_C_LIB
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval LIB := $(call uppercase, $(notdir $(1))))
+$(eval LIB := $(notdir $(1)))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  CC      $$<"
-	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -301,13 +307,14 @@
 #   $(1) = output directory
 #   $(2) = source file (%.S)
 #   $(3) = library name
+#   $(4) = uppercase name of the library
 define MAKE_S_LIB
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  AS      $$<"
-	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -318,19 +325,20 @@
 #   $(1) = output directory
 #   $(2) = source file (%.c)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_C
 
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
-$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_CFLAGS := $($(4)_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  CC      $$<"
-	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -341,19 +349,20 @@
 #   $(1) = output directory
 #   $(2) = assembly file (%.S)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_S
 
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
-$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_ASFLAGS := $($(4)_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  AS      $$<"
-	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -364,17 +373,18 @@
 #   $(1) = output linker script
 #   $(2) = input template
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_LD
 
 $(eval DEP := $(1).d)
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
 
 $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  PP      $$<"
-	$$(q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+	$$(q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(call MAKE_DEP,$(DEP),$1) -o $$@ $$<
 
 -include $(DEP)
 
@@ -384,14 +394,15 @@
 #   $(1) = output directory
 #   $(2) = list of source files
 #   $(3) = name of the library
+#   $(4) = uppercase name of the library
 define MAKE_LIB_OBJS
         $(eval C_OBJS := $(filter %.c,$(2)))
         $(eval REMAIN := $(filter-out %.c,$(2)))
-        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3),$(4))))
 
         $(eval S_OBJS := $(filter %.S,$(REMAIN)))
         $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
-        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3),$(4))))
 
         $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
 endef
@@ -401,14 +412,15 @@
 #   $(1) = output directory
 #   $(2) = list of source files (both C and assembly)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_OBJS
         $(eval C_OBJS := $(filter %.c,$(2)))
         $(eval REMAIN := $(filter-out %.c,$(2)))
-        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3),$(4))))
 
         $(eval S_OBJS := $(filter %.S,$(REMAIN)))
         $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
-        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3),$(4))))
 
         $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
 endef
@@ -428,13 +440,14 @@
 # Arguments:
 #   $(1) = Library name
 define MAKE_LIB
+        $(eval BL         := $(call uppercase,$(1)))
         $(eval BUILD_DIR  := ${BUILD_PLAT}/lib$(1))
         $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
         $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
-        $(eval SOURCES    := $(LIB$(call uppercase,$(1))_SRCS))
+        $(eval SOURCES    := $(LIB$(BL)_SRCS))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
 
-$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL)))
 
 libraries: ${LIB_DIR}/lib$(1).a
 ifeq ($($(ARCH)-ld-id),arm-link)
@@ -476,8 +489,9 @@
 #   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
 #   $(4) = BL encryption flag (optional) (0, 1)
 define MAKE_BL
+        $(eval BL         := $(call uppercase,$(1)))
         $(eval BUILD_DIR  := ${BUILD_PLAT}/$(1))
-        $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
+        $(eval BL_SOURCES := $($(BL)_SOURCES))
         $(eval SOURCES    := $(sort $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
@@ -485,24 +499,24 @@
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
-        $(eval BL_LIBS    := $($(call uppercase,$(1))_LIBS))
+        $(eval BL_LIBS    := $($(BL)_LIBS))
 
-        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(BL)_DEFAULT_LINKER_SCRIPT_SOURCE))
         $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
 
-        $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+        $(eval LINKER_SCRIPT_SOURCES := $($(BL)_LINKER_SCRIPT_SOURCES))
         $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
 
-$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL)))
 
 # Generate targets to preprocess each required linker script
 $(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
-        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1),$(BL))))
 
-$(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
+$(eval BL_LDFLAGS := $($(BL)_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
-$(ELF): romlib.bin | $$$$(@D)/
+$(ELF): $(BUILD_PLAT)/romlib/romlib.bin | $$$$(@D)/
 endif
 
 # MODULE_OBJS can be assigned by vendors with different compiled
@@ -554,10 +568,10 @@
 
 ifeq ($(4),1)
 $(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
-$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(ENC_BIN),$(3), \
 		$(ENC_BIN)))
 else
-$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(BIN),$(3)))
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(BIN),$(3)))
 endif
 
 endef
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
index 75d9f71..a4b69c7 100644
--- a/make_helpers/common.mk
+++ b/make_helpers/common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,9 +9,11 @@
 
         include $(dir $(common-mk))utilities.mk
 
-        silent = $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
-        verbose = $(if $(silent),,$(call bool,$(V)))
+        silent := $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
+        verbose := $(if $(silent),,$(call bool,$(V)))
 
-        s = @$(if $(or $(verbose),$(silent)),: )
-        q = $(if $(verbose),,@)
+        s := @$(if $(or $(verbose),$(silent)),: )
+        q := $(if $(verbose),,@)
+
+        .exe := $(if $(filter Windows_NT,$(OS)),.exe)
 endif
diff --git a/make_helpers/cygwin.mk b/make_helpers/cygwin.mk
deleted file mode 100644
index 04a963f..0000000
--- a/make_helpers/cygwin.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#
-
-# OS specific definitions for builds in a Cygwin environment.
-# Cygwin allows us to use unix style commands on a windows platform.
-
-ifndef CYGWIN_MK
-    CYGWIN_MK := $(lastword $(MAKEFILE_LIST))
-
-    include ${MAKE_HELPERS_DIRECTORY}unix.mk
-
-    # In cygwin executable files have the Windows .exe extension type.
-    BIN_EXT := .exe
-
-endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 8c884b4..4985c0c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -159,6 +159,9 @@
 # Enable Handoff protocol using transfer lists
 TRANSFER_LIST			:= 0
 
+# Enable HOB list to generate boot information
+HOB_LIST			:= 0
+
 # Enables support for the gcc compiler option "-mharden-sls=all".
 # By default, disables all SLS hardening.
 HARDEN_SLS			:= 0
@@ -207,6 +210,9 @@
 # Enable PSCI OS-initiated mode support
 PSCI_OS_INIT_MODE		:= 0
 
+# SMCCC_ARCH_FEATURE_AVAILABILITY support
+ARCH_FEATURE_AVAILABILITY	:= 0
+
 # By default, BL1 acts as the reset handler, not BL31
 RESET_TO_BL31			:= 0
 
@@ -240,6 +246,10 @@
 # region, platform Makefile is free to override this value.
 SEPARATE_BL2_NOLOAD_REGION	:= 0
 
+# Put RW DATA sections (.rwdata) in a separate memory region, which may be
+# discontiguous from the rest of BL31.
+SEPARATE_RWDATA_REGION		:= 0
+
 # Put SIMD context data structures in a separate memory region. Platforms
 # have the choice to put it outside of default BSS region of EL3 firmware.
 SEPARATE_SIMD_SECTION		:= 0
@@ -409,3 +419,6 @@
 # Allow platforms to save/restore DSU PMU registers over a power cycle.
 # Disabled by default and must be enabled by individual platforms.
 PRESERVE_DSU_PMU_REGS		:= 0
+
+# Enable RMMD to forward attestation requests from RMM to EL3.
+RMMD_ENABLE_EL3_TOKEN_SIGN	:= 0
diff --git a/make_helpers/msys.mk b/make_helpers/msys.mk
deleted file mode 100644
index 7e60d57..0000000
--- a/make_helpers/msys.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#
-
-# OS specific definitions for builds in a Mingw32 MSYS environment.
-# Mingw32 allows us to use some unix style commands on a windows platform.
-
-ifndef MSYS_MK
-    MSYS_MK := $(lastword $(MAKEFILE_LIST))
-
-    include ${MAKE_HELPERS_DIRECTORY}unix.mk
-
-    # In MSYS executable files have the Windows .exe extension type.
-    BIN_EXT := .exe
-
-endif
-
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
index 2ab577c..3b9d984 100644
--- a/make_helpers/toolchain.mk
+++ b/make_helpers/toolchain.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,7 +18,6 @@
 ifndef toolchain-mk
         toolchain-mk := $(lastword $(MAKEFILE_LIST))
 
-        include $(dir $(toolchain-mk))build_env.mk
         include $(dir $(toolchain-mk))utilities.mk
 
         #
@@ -242,28 +241,28 @@
         #
 
         # Arm Compiler for Embedded
-        toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
-        toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
-        toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
-        toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
+        toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armclang")
+        toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: armlink")
+        toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: fromelf")
+        toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armar")
 
         # LLVM Project
-        toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
-        toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
-        toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
-        toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
-        toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
+        toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 </dev/null | grep -o "clang version")
+        toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 </dev/null | grep -o "OVERVIEW: lld")
+        toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm-objcopy tool")
+        toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm object file dumper")
+        toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 </dev/null | grep -o "LLVM Archiver")
 
         # GNU Compiler Collection & GNU Binary Utilities
-        toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
-        toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
-        toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
-        toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
-        toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
+        toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 </dev/null | grep -o "gcc version")
+        toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 </dev/null | grep -o "GNU ld")
+        toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objcopy")
+        toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objdump")
+        toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU ar")
 
         # Other tools
-        toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
-        toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 <$(nul))
+        toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 </dev/null | grep -o "Version: DTC")
+        toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 </dev/null)
 
         toolchain-guess-tool = $(if $(2),$(firstword $(foreach candidate,$(1),$\
                 $(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate)))))
@@ -330,17 +329,17 @@
 
         toolchain-derive-llvm-clang-cpp = $(1)
         toolchain-derive-llvm-clang-as = $(1)
-        toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
-        toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
-        toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
-        toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
+        toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>/dev/null)
+        toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>/dev/null)
+        toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>/dev/null)
+        toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>/dev/null)
 
         toolchain-derive-gnu-gcc-cpp = $(1)
         toolchain-derive-gnu-gcc-as = $(1)
         toolchain-derive-gnu-gcc-ld = $(1)
-        toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
-        toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
-        toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>$(nul))
+        toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>/dev/null)
+        toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>/dev/null)
+        toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>/dev/null)
 
         toolchain-derive = $(if $3,$(call toolchain-derive-$1-$2,$3))
 
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
deleted file mode 100644
index fa7722a..0000000
--- a/make_helpers/unix.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Trusted Firmware shell command definitions for a Unix style environment.
-
-ifndef UNIX_MK
-    UNIX_MK := $(lastword $(MAKEFILE_LIST))
-
-    DIR_DELIM := /
-    PATH_SEP := :
-
-    # These defines provide Unix style equivalents of the shell commands
-    # required by the Trusted Firmware build environment.
-
-    # ${1} is the file to be copied.
-    # ${2} is the destination file name.
-    define SHELL_COPY
-	$(q)cp -f  "${1}"  "${2}"
-    endef
-
-    # ${1} is the directory to be copied.
-    # ${2} is the destination directory path.
-    define SHELL_COPY_TREE
-	$(q)cp -rf  "${1}"  "${2}"
-    endef
-
-    # ${1} is the file to be deleted.
-    define SHELL_DELETE
-	-$(q)rm -f  "${1}"
-    endef
-
-    # ${1} is a space delimited list of files to be deleted.
-    # Note that we do not quote ${1}, as multiple parameters may be passed.
-    define SHELL_DELETE_ALL
-	-$(q)rm -rf  ${1}
-    endef
-
-    define SHELL_REMOVE_DIR
-	-$(q)rm -rf  "${1}"
-    endef
-
-    nul := /dev/null
-
-    which = $(shell command -v $(call escape-shell,$(1)) 2>$(nul))
-endif
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
index efa0ab9..10645bf 100644
--- a/make_helpers/utilities.mk
+++ b/make_helpers/utilities.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,6 +22,13 @@
 escape-shell = '$(subst ','\'',$(1))'
 
 #
+# The grouped-target symbol. Grouped targets are not supported on versions of
+# GNU Make <= 4.2, which was most recently packaged with Ubuntu 20.04.
+#
+
+& := $(if $(filter grouped-target,$(.FEATURES)),&)
+
+#
 # Upper-case a string value.
 #
 # Parameters:
@@ -120,3 +127,17 @@
 #
 
 defined = $(call bool,$(filter-out undefined,$(origin $(1))))
+
+#
+# Determine the path to a program.
+#
+# Parameters:
+#
+#   - $(1): The program to search for.
+#
+# Example usage:
+#
+#     path-to-gcc := $(call which,gcc) # "/usr/bin/gcc"
+#
+
+which = $(shell command -v $(call escape-shell,$(1)) 2>/dev/null)
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
deleted file mode 100644
index c24aa08..0000000
--- a/make_helpers/windows.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# OS specific parts for builds in a Windows_NT environment. The
-# environment variable OS is set to Windows_NT on all modern Windows platforms
-
-# Include generic windows command definitions.
-
-ifndef WINDOWS_MK
-    WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
-
-    DIR_DELIM := $(strip \)
-    BIN_EXT   := .exe
-    PATH_SEP  := ;
-
-    # For some Windows native commands there is a problem with the directory delimiter.
-    # Make uses / (slash) and the commands expect \ (backslash)
-    # We have to provide a means of translating these, so we define local functions.
-
-    # ${1} is the file to be copied.
-    # ${2} is the destination file name.
-    define SHELL_COPY
-	$(eval tmp_from_file:=$(subst /,\,${1}))
-	$(eval tmp_to_file:=$(subst /,\,${2}))
-	copy "${tmp_from_file}" "${tmp_to_file}"
-    endef
-
-    # ${1} is the directory to be copied.
-    # ${2} is the destination directory path.
-    define SHELL_COPY_TREE
-	$(eval tmp_from_dir:=$(subst /,\,${1}))
-	$(eval tmp_to_dir:=$(subst /,\,${2}))
-	xcopy /HIVE "${tmp_from_dir}" "${tmp_to_dir}"
-    endef
-
-    # ${1} is the file to be deleted.
-    define SHELL_DELETE
-	$(eval tmp_del_file:=$(subst /,\,${*}))
-	-@if exist $(tmp_del_file)  del /Q $(tmp_del_file)
-    endef
-
-    # ${1} is a space delimited list of files to be deleted.
-    define SHELL_DELETE_ALL
-	$(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
-    endef
-
-    # ${1} is the directory to be removed.
-    define SHELL_REMOVE_DIR
-	$(eval tmp_dir:=$(subst /,\,${1}))
-	-@if exist "$(tmp_dir)"  rd /Q /S "$(tmp_dir)"
-    endef
-
-    nul := nul
-
-    which = $(shell where "$(1)" 2>$(nul))
-endif
-
-# Because git is not available from CMD.EXE, we need to avoid
-# the BUILD_STRING generation which uses git.
-# For now we use "development build".
-# This can be overridden from the command line or environment.
-BUILD_STRING ?= development build
-
-MSVC_NMAKE := nmake.exe
diff --git a/package-lock.json b/package-lock.json
index 26caae4..61d05bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.11.0",
+  "version": "2.12.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.11.0",
+      "version": "2.12.0",
       "license": "BSD-3-Clause",
       "devDependencies": {
         "@commitlint/cli": "^19.0.0",
@@ -1963,9 +1963,9 @@
       }
     },
     "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
       "dev": true,
       "dependencies": {
         "path-key": "^3.1.0",
@@ -3572,12 +3572,12 @@
       "dev": true
     },
     "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
       "dev": true,
       "dependencies": {
-        "braces": "^3.0.2",
+        "braces": "^3.0.3",
         "picomatch": "^2.3.1"
       },
       "engines": {
@@ -4903,7 +4903,7 @@
       }
     },
     "tools/conventional-changelog-tf-a": {
-      "version": "2.11.0",
+      "version": "2.12.0",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
diff --git a/package.json b/package.json
index e4c6475..0908528 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.11.0",
+  "version": "2.12.0",
   "license": "BSD-3-Clause",
   "type": "module",
   "private": true,
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index e3c7c52..cced7f0 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# To report supported idle states
+# this has to be defined before allwinner-common.mk
+SUNXI_AMEND_DTB		:=	1
+
 # The differences between the platform are covered by the include files.
 include plat/allwinner/common/allwinner-common.mk
 
diff --git a/plat/allwinner/sun50i_a64/platform_defaults.mk b/plat/allwinner/sun50i_a64/platform_defaults.mk
new file mode 100644
index 0000000..5b61029
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/platform_defaults.mk
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# LTO has to be enabled on this platform due to memory constraints
+ENABLE_LTO			:= 1
+
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
index 3ab3dca..c78d711 100644
--- a/plat/amd/versal2/aarch64/common.c
+++ b/plat/amd/versal2/aarch64/common.c
@@ -31,7 +31,7 @@
 	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-#if defined(TRANSFER_LIST)
+#if TRANSFER_LIST
 	MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_BASE + FW_HANDOFF_SIZE,
 			MT_MEMORY | MT_RW | MT_NS),
 #endif
@@ -72,11 +72,11 @@
 
 void board_detection(void)
 {
-	uint32_t version;
+	uint32_t version_type;
 
-	version = mmio_read_32(PMC_TAP_VERSION);
-	platform_id = FIELD_GET(PLATFORM_MASK, version);
-	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+	version_type = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET((uint32_t)PLATFORM_MASK, version_type);
+	platform_version = FIELD_GET((uint32_t)PLATFORM_VERSION_MASK, version_type);
 
 	if (platform_id == QEMU_COSIM) {
 		platform_id = QEMU;
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 970fca9..6e7fffe 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -20,12 +20,14 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <plat_arm.h>
+#include <plat_console.h>
 #include <scmi.h>
 
 #include <def.h>
 #include <plat_fdt.h>
 #include <plat_private.h>
 #include <plat_startup.h>
+#include <plat_xfer_list.h>
 #include <pm_api_sys.h>
 #include <pm_client.h>
 
@@ -61,7 +63,7 @@
 	bl32_image_ep_info.args.arg3 = XILINX_OF_BOARD_DTB_ADDR;
 #endif
 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
-	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+	bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
 					  DISABLE_ALL_EXCEPTIONS);
 }
 
@@ -125,30 +127,7 @@
 
 	uart_clock = get_uart_clk();
 
-	if (CONSOLE_IS(pl011_0) || CONSOLE_IS(pl011_1)) {
-		static console_t _runtime_console;
-
-		/* Initialize the console to provide early debug support */
-		rc = console_pl011_register(UART_BASE, uart_clock,
-					    UART_BAUDRATE,
-					    &_runtime_console);
-		if (rc == 0) {
-			panic();
-		}
-
-		console_set_scope(&_runtime_console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	} else if (CONSOLE_IS(dcc)) {
-		/* Initialize the dcc console for debug.
-		 * dcc is over jtag and does not configures uart0 or uart1.
-		 */
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-	} else {
-		/* Making MISRA C 2012 15.7 compliant */
-	}
+	setup_console();
 
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
@@ -168,7 +147,12 @@
 	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-	bl31_set_default_config();
+
+	rc = transfer_list_populate_ep_info(&bl32_image_ep_info, &bl33_image_ep_info);
+	if (rc == TL_OPS_NON || rc == TL_OPS_CUS) {
+		NOTICE("BL31: TL not found, using default config\n");
+		bl31_set_default_config();
+	}
 
 	long rev_var = cpu_get_rev_var();
 
@@ -188,7 +172,7 @@
 	uint32_t i;
 
 	/* Validate 'handler' and 'id' parameters */
-	if (handler == NULL || index >= MAX_INTR_EL3) {
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
 		return -EINVAL;
 	}
 
@@ -245,7 +229,7 @@
 
 void bl31_plat_runtime_setup(void)
 {
-	uint64_t flags = 0;
+	uint32_t flags = 0;
 	int32_t rc;
 
 	set_interrupt_rm_flag(flags, NON_SECURE);
@@ -254,6 +238,8 @@
 	if (rc != 0) {
 		panic();
 	}
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -262,10 +248,6 @@
 void bl31_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
-		MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
-				MT_MEMORY | MT_RW | MT_NS),
-#endif
 		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
 			MT_MEMORY | MT_RW | MT_SECURE),
 		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index 67244a4..0c43d1b 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -12,15 +12,26 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
-#define MAX_INTR_EL3			2
+#define MAX_INTR_EL3			2U
 
 /* List all consoles */
-#define CONSOLE_ID_pl011	U(1)
-#define CONSOLE_ID_pl011_0	U(1)
-#define CONSOLE_ID_pl011_1	U(2)
-#define CONSOLE_ID_dcc	U(3)
+#define VERSAL2_CONSOLE_ID_none		0
+#define VERSAL2_CONSOLE_ID_pl011	1
+#define VERSAL2_CONSOLE_ID_pl011_0       1
+#define VERSAL2_CONSOLE_ID_pl011_1       2
+#define VERSAL2_CONSOLE_ID_dcc           3
+#define VERSAL2_CONSOLE_ID_dtb           4
 
-#define CONSOLE_IS(con)	(CONSOLE_ID_ ## con == CONSOLE)
+#define CONSOLE_IS(con) (VERSAL2_CONSOLE_ID_ ## con == VERSAL2_CONSOLE)
+
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011   1
+#define RT_CONSOLE_ID_pl011_0   1
+#define RT_CONSOLE_ID_pl011_1   2
+#define RT_CONSOLE_ID_dcc       3
+#define RT_CONSOLE_ID_dtb       4
+
+#define RT_CONSOLE_IS(con)      (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
 
 /* List all platforms */
 #define SILICON		U(0)
@@ -143,11 +154,35 @@
 
 #define UART_BAUDRATE	115200
 
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE		UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE	    UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE           UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
-/* Default console is UART0 */
-#define UART_BASE            UART0_BASE
+# error "invalid VERSAL2_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
 #endif
 
 #endif /* DEF_H */
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
index 090fe46..42c9b08 100644
--- a/plat/amd/versal2/include/platform_def.h
+++ b/plat/amd/versal2/include/platform_def.h
@@ -91,7 +91,7 @@
 #define PLAT_OCM_BASE			U(0xBBF00000)
 #define PLAT_OCM_LIMIT			U(0xBC000000)
 
-#if defined(TRANSFER_LIST)
+#if TRANSFER_LIST
 /*
  * FIXME: This address should come from firmware before TF-A
  * Having this to make sure the transfer list functionality works
diff --git a/plat/amd/versal2/include/scmi.h b/plat/amd/versal2/include/scmi.h
index 0ab8b34..761535b 100644
--- a/plat/amd/versal2/include/scmi.h
+++ b/plat/amd/versal2/include/scmi.h
@@ -14,6 +14,14 @@
 
 void init_scmi_server(void);
 
+size_t plat_scmi_pd_count(unsigned int agent_id);
+const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id);
+unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id);
+unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id);
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id);
+int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
+				unsigned int state);
+
 #define SCMI_VENDOR	"AMD"
 #define SCMI_PRODUCT	"Versal Gen 2"
 
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
index c08b4b1..218fbf6 100644
--- a/plat/amd/versal2/include/versal2-scmi.h
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -10,96 +10,96 @@
 #ifndef _VERSAL2_SCMI_H
 #define _VERSAL2_SCMI_H
 
-#define CLK_GEM0_0	0
-#define CLK_GEM0_1	1
-#define CLK_GEM0_2	2
-#define CLK_GEM0_3	3
-#define CLK_GEM0_4	4
-#define CLK_GEM1_0	5
-#define CLK_GEM1_1	6
-#define CLK_GEM1_2	7
-#define CLK_GEM1_3	8
-#define CLK_GEM1_4	9
-#define CLK_SERIAL0_0	10
-#define CLK_SERIAL0_1	11
-#define CLK_SERIAL1_0	12
-#define CLK_SERIAL1_1	13
-#define CLK_UFS0_0	14
-#define CLK_UFS0_1	15
-#define CLK_UFS0_2	16
-#define CLK_USB0_0	17
-#define CLK_USB0_1	18
-#define CLK_USB0_2	19
-#define CLK_USB1_0	20
-#define CLK_USB1_1	21
-#define CLK_USB1_2	22
-#define CLK_MMC0_0	23
-#define CLK_MMC0_1	24
-#define CLK_MMC0_2	25
-#define CLK_MMC1_0	26
-#define CLK_MMC1_1	27
-#define CLK_MMC1_2	28
-#define CLK_TTC0_0	29
-#define CLK_TTC1_0	30
-#define CLK_TTC2_0	31
-#define CLK_TTC3_0	32
-#define CLK_TTC4_0	33
-#define CLK_TTC5_0	34
-#define CLK_TTC6_0	35
-#define CLK_TTC7_0	36
-#define CLK_I2C0_0	37
-#define CLK_I2C1_0	38
-#define CLK_I2C2_0	39
-#define CLK_I2C3_0	40
-#define CLK_I2C4_0	41
-#define CLK_I2C5_0	42
-#define CLK_I2C6_0	43
-#define CLK_I2C7_0	44
-#define CLK_OSPI0_0	45
-#define CLK_QSPI0_0	46
-#define CLK_QSPI0_1	47
-#define CLK_WWDT0_0	48
-#define CLK_WWDT1_0	49
-#define CLK_WWDT2_0	50
-#define CLK_WWDT3_0	51
-#define CLK_ADMA0_0	52
-#define CLK_ADMA0_1	53
-#define CLK_ADMA1_0	54
-#define CLK_ADMA1_1	55
-#define CLK_ADMA2_0	56
-#define CLK_ADMA2_1	57
-#define CLK_ADMA3_0	58
-#define CLK_ADMA3_1	59
-#define CLK_ADMA4_0	60
-#define CLK_ADMA4_1	61
-#define CLK_ADMA5_0	62
-#define CLK_ADMA5_1	63
-#define CLK_ADMA6_0	64
-#define CLK_ADMA6_1	65
-#define CLK_ADMA7_0	66
-#define CLK_ADMA7_1	67
-#define CLK_CAN0_0	68
-#define CLK_CAN0_1	69
-#define CLK_CAN1_0	70
-#define CLK_CAN1_1	71
-#define CLK_CAN2_0	72
-#define CLK_CAN2_1	73
-#define CLK_CAN3_0	74
-#define CLK_CAN3_1	75
-#define CLK_PS_GPIO_0	76
-#define CLK_PMC_GPIO_0	77
-#define CLK_SPI0_0	78
-#define CLK_SPI0_1	79
-#define CLK_SPI1_0	80
-#define CLK_SPI1_1	81
-#define CLK_I3C0_0	82
-#define CLK_I3C1_0	83
-#define CLK_I3C2_0	84
-#define CLK_I3C3_0	85
-#define CLK_I3C4_0	86
-#define CLK_I3C5_0	87
-#define CLK_I3C6_0	88
-#define CLK_I3C7_0	89
+#define CLK_GEM0_0	0U
+#define CLK_GEM0_1	1U
+#define CLK_GEM0_2	2U
+#define CLK_GEM0_3	3U
+#define CLK_GEM0_4	4U
+#define CLK_GEM1_0	5U
+#define CLK_GEM1_1	6U
+#define CLK_GEM1_2	7U
+#define CLK_GEM1_3	8U
+#define CLK_GEM1_4	9U
+#define CLK_SERIAL0_0	10U
+#define CLK_SERIAL0_1	11U
+#define CLK_SERIAL1_0	12U
+#define CLK_SERIAL1_1	13U
+#define CLK_UFS0_0	14U
+#define CLK_UFS0_1	15U
+#define CLK_UFS0_2	16U
+#define CLK_USB0_0	17U
+#define CLK_USB0_1	18U
+#define CLK_USB0_2	19U
+#define CLK_USB1_0	20U
+#define CLK_USB1_1	21U
+#define CLK_USB1_2	22U
+#define CLK_MMC0_0	23U
+#define CLK_MMC0_1	24U
+#define CLK_MMC0_2	25U
+#define CLK_MMC1_0	26U
+#define CLK_MMC1_1	27U
+#define CLK_MMC1_2	28U
+#define CLK_TTC0_0	29U
+#define CLK_TTC1_0	30U
+#define CLK_TTC2_0	31U
+#define CLK_TTC3_0	32U
+#define CLK_TTC4_0	33U
+#define CLK_TTC5_0	34U
+#define CLK_TTC6_0	35U
+#define CLK_TTC7_0	36U
+#define CLK_I2C0_0	37U
+#define CLK_I2C1_0	38U
+#define CLK_I2C2_0	39U
+#define CLK_I2C3_0	40U
+#define CLK_I2C4_0	41U
+#define CLK_I2C5_0	42U
+#define CLK_I2C6_0	43U
+#define CLK_I2C7_0	44U
+#define CLK_OSPI0_0	45U
+#define CLK_QSPI0_0	46U
+#define CLK_QSPI0_1	47U
+#define CLK_WWDT0_0	48U
+#define CLK_WWDT1_0	49U
+#define CLK_WWDT2_0	50U
+#define CLK_WWDT3_0	51U
+#define CLK_ADMA0_0	52U
+#define CLK_ADMA0_1	53U
+#define CLK_ADMA1_0	54U
+#define CLK_ADMA1_1	55U
+#define CLK_ADMA2_0	56U
+#define CLK_ADMA2_1	57U
+#define CLK_ADMA3_0	58U
+#define CLK_ADMA3_1	59U
+#define CLK_ADMA4_0	60U
+#define CLK_ADMA4_1	61U
+#define CLK_ADMA5_0	62U
+#define CLK_ADMA5_1	63U
+#define CLK_ADMA6_0	64U
+#define CLK_ADMA6_1	65U
+#define CLK_ADMA7_0	66U
+#define CLK_ADMA7_1	67U
+#define CLK_CAN0_0	68U
+#define CLK_CAN0_1	69U
+#define CLK_CAN1_0	70U
+#define CLK_CAN1_1	71U
+#define CLK_CAN2_0	72U
+#define CLK_CAN2_1	73U
+#define CLK_CAN3_0	74U
+#define CLK_CAN3_1	75U
+#define CLK_PS_GPIO_0	76U
+#define CLK_PMC_GPIO_0	77U
+#define CLK_SPI0_0	78U
+#define CLK_SPI0_1	79U
+#define CLK_SPI1_0	80U
+#define CLK_SPI1_1	81U
+#define CLK_I3C0_0	82U
+#define CLK_I3C1_0	83U
+#define CLK_I3C2_0	84U
+#define CLK_I3C3_0	85U
+#define CLK_I3C4_0	86U
+#define CLK_I3C5_0	87U
+#define CLK_I3C6_0	88U
+#define CLK_I3C7_0	89U
 
 #define RESET_GEM0_0	0
 #define RESET_GEM1_0	1
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
index a55042d..e8dc5d3 100644
--- a/plat/amd/versal2/plat_psci.c
+++ b/plat/amd/versal2/plat_psci.c
@@ -21,6 +21,7 @@
 
 #define PM_RET_ERROR_NOFEATURE U(19)
 #define ALWAYSTRUE true
+#define LINEAR_MODE BIT(1)
 
 static uintptr_t _sec_entry;
 
@@ -34,9 +35,9 @@
 
 static int32_t zynqmp_nopmu_pwr_domain_on(u_register_t mpidr)
 {
-	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
-	uint32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
-	uint32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
+	int32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
+	int32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
+	int32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
 	uintptr_t apu_cluster_base = 0, apu_pcli_base, apu_pcli_cluster = 0;
 	uintptr_t rst_apu_cluster = PSX_CRF + RST_APU0_OFFSET + ((uint64_t)cluster * 0x4U);
 
@@ -47,7 +48,7 @@
 		return PSCI_E_INTERN_FAIL;
 	}
 
-	if (cluster > 3) {
+	if (cluster > 3U) {
 		panic();
 	}
 
@@ -68,7 +69,7 @@
 	mmio_write_32(apu_cluster_base + APU_RVBAR_L_0 + (cpu << 3),
 		      (uint32_t)_sec_entry);
 	mmio_write_32(apu_cluster_base + APU_RVBAR_H_0 + (cpu << 3),
-		      _sec_entry >> 32);
+		      (uint32_t)(_sec_entry >> 32));
 
 	/* de-assert core reset */
 	mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
@@ -166,15 +167,20 @@
 
 	switch (ioctl_id) {
 	case IOCTL_OSPI_MUX_SELECT:
-		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
+		if ((arg1 == 0) || (arg1 == 1)) {
+			mmio_clrsetbits_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, LINEAR_MODE,
+					(arg1 ? LINEAR_MODE : 0));
+		} else {
+			ret = PM_RET_ERROR_ARGS;
+		}
 		break;
 	case IOCTL_UFS_TXRX_CFGRDY_GET:
 		ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY);
 		break;
 	case IOCTL_UFS_SRAM_CSR_SEL:
-		if (arg1 == 1) {
+		if (arg1 == 1U) {
 			ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR);
-		} else if (arg1 == 0) {
+		} else if (arg1 == 0U) {
 			mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2);
 		}
 		break;
@@ -216,11 +222,11 @@
 	}
 	case PM_GET_CHIPID:
 	{
-		uint32_t idcode, version;
+		uint32_t idcode, version_type;
 
 		idcode  = mmio_read_32(PMC_TAP);
-		version = mmio_read_32(PMC_TAP_VERSION);
-		SMC_RET2(handle, ((uint64_t)idcode << 32), version);
+		version_type = mmio_read_32(PMC_TAP_VERSION);
+		SMC_RET2(handle, ((uint64_t)idcode << 32), version_type);
 	}
 	default:
 		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
index 3892fcb..3114976 100644
--- a/plat/amd/versal2/platform.mk
+++ b/plat/amd/versal2/platform.mk
@@ -6,6 +6,9 @@
 
 PLAT_PATH := plat/amd/versal2
 
+override NEED_BL1 := no
+override NEED_BL2 := no
+
 # A78 Erratum for SoC
 ERRATA_A78_AE_1941500 := 1
 ERRATA_A78_AE_1951502 := 1
@@ -28,6 +31,10 @@
 
 override CTX_INCLUDE_AARCH32_REGS    := 0
 
+# Platform to support Dynamic XLAT Table by default
+override PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
 ifdef MEM_BASE
     $(eval $(call add_define,MEM_BASE))
 
@@ -57,13 +64,28 @@
 USE_COHERENT_MEM := 0
 HW_ASSISTED_COHERENCY := 1
 
-CONSOLE	?=	pl011
-ifeq (${CONSOLE}, $(filter ${CONSOLE},pl011 pl011_0 pl011_1 dcc))
-else
-  $(error Please define CONSOLE)
+VERSAL2_CONSOLE  ?=      pl011
+ifeq (${VERSAL2_CONSOLE}, $(filter ${VERSAL2_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
+	else
+	  $(error "Please define VERSAL2_CONSOLE")
+  endif
+
+$(eval $(call add_define_val,VERSAL2_CONSOLE,VERSAL2_CONSOLE_ID_${VERSAL2_CONSOLE}))
+
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
 endif
 
-$(eval $(call add_define_val,CONSOLE,CONSOLE_ID_${CONSOLE}))
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq 	(${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+	$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 
 ifdef XILINX_OF_BOARD_DTB_ADDR
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
@@ -109,6 +131,9 @@
 BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
 
 BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
+				common/fdt_wrappers.c                           \
+				plat/xilinx/common/plat_fdt.c                   \
+				plat/xilinx/common/plat_console.c               \
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c	\
@@ -126,3 +151,9 @@
 CORTEX_A78_AE_H_INC     := 1
 $(eval $(call add_define, CORTEX_A78_AE_H_INC))
 endif
+
+# Enable Handoff protocol using transfer lists
+TRANSFER_LIST                   := 1
+
+include lib/transfer_list/transfer_list.mk
+BL31_SOURCES           +=      plat/xilinx/common/plat_xfer_list.c
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
index 7f4b6df..eec8205 100644
--- a/plat/amd/versal2/scmi.c
+++ b/plat/amd/versal2/scmi.c
@@ -51,8 +51,8 @@
 	CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
 	CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
 	CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
-	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 100000000),
-	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 26000000),
+	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 26000000),
 	CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
 	CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
 	CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
@@ -269,7 +269,7 @@
 
 const char *plat_scmi_clock_get_name(unsigned int agent_id, unsigned int scmi_id)
 {
-	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
 	const char *ret;
 
 	if (clock == NULL) {
@@ -287,13 +287,13 @@
 				    unsigned long *array, size_t *nb_elts,
 				    uint32_t start_idx)
 {
-	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
 
 	if (clock == NULL) {
 		return SCMI_NOT_FOUND;
 	}
 
-	if (start_idx > 0) {
+	if (start_idx > 0U) {
 		return SCMI_OUT_OF_RANGE;
 	}
 
@@ -312,7 +312,7 @@
 
 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
 {
-	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
 	unsigned long ret;
 
 	if ((clock == NULL)) {
@@ -328,7 +328,7 @@
 				 unsigned long rate)
 {
 	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
-	unsigned long ret = UL(SCMI_SUCCESS);
+	int32_t ret = SCMI_SUCCESS;
 
 	if ((clock == NULL)) {
 		ret = SCMI_NOT_FOUND;
@@ -341,7 +341,7 @@
 
 int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
 {
-	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
 	int32_t ret;
 
 	if ((clock == NULL)) {
@@ -564,17 +564,19 @@
 			       unsigned int state)
 {
 	struct scmi_pd *pd = find_pd(agent_id, pd_id);
+	int32_t ret = SCMI_SUCCESS;
 
 	if (pd == NULL) {
-		return SCMI_NOT_SUPPORTED;
+		ret = SCMI_NOT_SUPPORTED;
+	} else {
+
+		NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x,  flags: %x\n",
+				pd_id, pd->state, state, flags);
+
+		pd->state = state;
 	}
 
-	NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x,  flags: %x\n",
-	       pd_id, pd->state, state, flags);
-
-	pd->state = state;
-
-	return 0U;
+	return ret;
 }
 
 
@@ -647,8 +649,13 @@
 		for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
 
 			/* Keep i2c on 100MHz to calculate rates properly */
-			if (i >= CLK_I2C0_0 && i <= CLK_I2C7_0)
+			if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0))
 				continue;
+
+			/* Keep UFS clocks to default values to get the expected rates */
+			if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
+				continue;
+
 			/*
 			 * SPP supports multiple versions.
 			 * The cpu_clock value is set to corresponding SPP
diff --git a/plat/amd/versal2/sip_svc_setup.c b/plat/amd/versal2/sip_svc_setup.c
index 6850030..4a1be3e 100644
--- a/plat/amd/versal2/sip_svc_setup.c
+++ b/plat/amd/versal2/sip_svc_setup.c
@@ -71,7 +71,7 @@
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if ((smc_fid & SIP_FID_MASK) != 0) {
+	if ((smc_fid & SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index dd82a10..6d60cbe 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -75,9 +75,7 @@
 				${DYN_CFG_SOURCES}				\
 				${A5DS_SECURITY_SOURCES}
 
-# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
-ifdef UNIX_MK
-
+# Add the FDT_SOURCES and options for Dynamic Config
 FW_CONFIG	:=      ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
 TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
 
@@ -94,7 +92,6 @@
 FDT_SOURCES		+=	plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
 				plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
 					${FVP_HW_CONFIG_DTS}
-endif
 
 NEED_BL32 := yes
 
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 82401db..967bf21 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -47,6 +47,7 @@
 ENABLE_TRF_FOR_NS		:= 2
 ENABLE_SME_FOR_NS		:= 2
 ENABLE_SME2_FOR_NS		:= 2
+ENABLE_FEAT_LS64_ACCDATA	:= 2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -127,9 +128,9 @@
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
-$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31))
-$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31))
-$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31))
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31,BL31))
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31,BL31))
+$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31,BL31))
 
 ifeq ($($(ARCH)-ld-id),gnu-gcc)
         AXF_LDFLAGS	+=	-Wl,--build-id=none -mno-fix-cortex-a53-843419
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
index 53cd3b0..89e30e9 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
@@ -12,6 +12,12 @@
 	dtb-registry {
 		compatible = "fconf,dyn_cfg-dtb_registry";
 
+		tos_fw-config {
+			load-address = <0x0 0x70000>;
+			max-size = <0x1000>;
+			id = <TOS_FW_CONFIG_ID>;
+		};
+
 		hw-config {
 			load-address = <0x0 0x83000000>;
 			max-size = <0x8000>;
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts
new file mode 100644
index 0000000..c28cadf
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	/*
+	 * BL32 image details needed by SPMC
+	 */
+
+	attribute {
+		spmc_id = <0x8000>;
+		maj_ver = <0x1>;
+		min_ver = <0x0>;
+		exec_state = <0x0>;
+		load_address = <0x0 0xffc00000>;
+		entrypoint = <0x0 0xffc00000>;
+		binary_size = <0x00400000>;
+	};
+};
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
index 44c8ee3..b71be40 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
@@ -45,6 +45,9 @@
 #define PLAT_CSS_MHU_BASE			UL(0x2A920000)
 #define PLAT_ARM_NSTIMER_FRAME_ID		U(0)
 
+#define PLAT_ARM_SPMC_BASE		        UL(0xFFC00000)
+#define PLAT_ARM_SPMC_SIZE		        UL(0x00400000)
+
 #define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
 #define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
 #define SOC_CSS_UART_SIZE			UL(0x10000)
@@ -115,10 +118,14 @@
 						MT_SECURE)
 
 #define RD1AE_MAP_NS_DRAM1	MAP_REGION_FLAT(ARM_DRAM1_BASE,	\
-						ARM_DRAM1_SIZE,	\
+						ARM_DRAM1_SIZE - PLAT_ARM_SPMC_SIZE, \
 						MT_MEMORY | MT_RW | \
 						MT_NS)
 
+#define RD1AE_MAP_S_DRAM1	MAP_REGION_FLAT(PLAT_ARM_SPMC_BASE, \
+						PLAT_ARM_SPMC_SIZE,	\
+						MT_MEMORY | MT_RW | MT_SECURE)
+
 #define RD1AE_DEVICE_BASE	(0x20000000)
 #define RD1AE_DEVICE_SIZE	(0x20000000)
 #define RD1AE_MAP_DEVICE	MAP_REGION_FLAT(RD1AE_DEVICE_BASE, \
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
index 35cd8a1..6773ae0 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
@@ -32,6 +32,7 @@
 GIC_ENABLE_V4_EXTN			:=	1
 GICV3_SUPPORT_GIC600			:=	1
 HW_ASSISTED_COHERENCY			:=	1
+NEED_BL32				:=	yes
 PLAT_MHU_VERSION			:=	1
 RESET_TO_BL2				:=	1
 SVE_VECTOR_LEN				:=	128
@@ -68,15 +69,19 @@
 
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES	+=	${RD1AE_BASE}/fdts/${PLAT}_fw_config.dts	\
-			fdts/${PLAT}.dts
+			fdts/${PLAT}.dts				\
+			${RD1AE_BASE}/fdts/${PLAT}_optee_spmc_manifest.dts
 
 FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 HW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_optee_spmc_manifest.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 HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TOS_FW_CONFIG},--tos-fw-config,${TOS_FW_CONFIG}))
 
 ifeq (${TRUSTED_BOARD_BOOT},1)
 FIP_BL2_ARGS	:=	tb-fw
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
index 30cc90f..8d0b96f 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
@@ -36,7 +36,7 @@
 		.image_info.image_base = BL31_BASE,
 		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
 
-		.next_handoff_image_id = BL33_IMAGE_ID,
+		.next_handoff_image_id = BL32_IMAGE_ID,
 	},
 	/* Fill HW_CONFIG related information */
 	{
@@ -48,6 +48,30 @@
 			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+		.ep_info.pc = BL32_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	/* Fill TOS_FW_CONFIG related information */
+	{
+		.image_id = TOS_FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
 	/* Fill BL33 related information */
 	{
 		.image_id = BL33_IMAGE_ID,
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
index ce7bad7..6cfe34a 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
@@ -26,3 +26,14 @@
 {
 	return css_scmi_override_pm_ops(ops);
 }
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /* defined(SPD_spmd) && (SPMC_AT_EL3 == 0) */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
index e917330..229ab24 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
@@ -19,6 +19,7 @@
 #if IMAGE_BL2
 	RD1AE_MAP_NS_DRAM1,
 #endif
+	RD1AE_MAP_S_DRAM1,
 	{0}
 };
 
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 4a2572f..b1f7b11 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -44,11 +44,11 @@
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
 
-extern unsigned char arm_rotpk_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
+extern unsigned char arm_rotpk_hash_der_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
        arm_rotpk_key_end[];
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
-static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+static unsigned char rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN + ARM_ROTPK_HASH_LEN];
 #endif
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
@@ -68,8 +68,8 @@
 
 	/* Copy the DER header */
 
-	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
-	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+	memcpy(rotpk_hash_der, arm_rotpk_hash_der_header, ARM_ROTPK_HASH_DER_HEADER_LEN);
+	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN];
 
 	words = ARM_ROTPK_HASH_LEN >> 2;
 
@@ -95,8 +95,8 @@
 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
 			unsigned int *flags)
 {
-	*key_ptr = arm_rotpk_header;
-	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
+	*key_ptr = arm_rotpk_hash_der_header;
+	*key_len = arm_rotpk_hash_end - arm_rotpk_hash_der_header;
 	*flags = ROTPK_IS_HASH;
 	return 0;
 }
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 365a960..124a44b 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,63 +13,70 @@
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
 ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_dev_rotpk.S
+ARM_ROTPK = $(BUILD_PLAT)/arm_rotpk.bin
+ARM_ROTPK_IS_HASH := 1
+$(eval $(call add_define_val,ARM_ROTPK,'"$(ARM_ROTPK)"'))
 
 # ROTPK hash location
 ifeq (${ARM_ROTPK_LOCATION}, regs)
 	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
-else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+else
+# The ROTPK is a development key
+ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
 	CRYPTO_ALG=rsa
 	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
-	ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
-$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
-$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+	ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
 else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
 	CRYPTO_ALG=ec
 	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
-	ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
-$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
-$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+	ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
 else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_rsa_key)
 	CRYPTO_ALG=rsa
 	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID
-	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+	ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+	ARM_ROTPK_IS_HASH = 0
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
 else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_ecdsa_key)
 	CRYPTO_ALG=ec
 	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID
-ifeq (${KEY_SIZE},384)
-	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
-else
-	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
-endif
+	ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem
+	ARM_ROTPK_IS_HASH = 0
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
 else
 $(error "Unsupported ARM_ROTPK_LOCATION value")
 endif
+$(BUILD_PLAT)/bl1/arm_dev_rotpk.o : $(ARM_ROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK)
+endif
 
 $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+$(eval $(call add_define,ARM_ROTPK_IS_HASH))
 
 ifeq (${ENABLE_RME}, 1)
 COT	:=	cca
 endif
 
-# Force generation of the new hash if ROT_KEY is specified
+# Force generation of the ROT public key if ROT_KEY is specified
 ifdef ROT_KEY
-	HASH_PREREQUISITES = $(ROT_KEY) FORCE
+	PK_PREREQUISITES = $(ROT_KEY) FORCE
 endif
 
-$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+$(ARM_ROTPK) : $(PK_PREREQUISITES)
 ifndef ROT_KEY
-	$(error Cannot generate hash: no ROT_KEY defined)
+	$(error Cannot generate public key: no ROT_KEY defined)
 endif
+ifeq ($(ARM_ROTPK_IS_HASH), 1)
 	${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | \
-	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@
+	${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
+else
+	${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in $< -pubout -outform DER -out $@
+endif
 
 # Certificate NV-Counters. Use values corresponding to tied off values in
 # ARM development platforms
@@ -85,50 +92,73 @@
 BL2_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
 				${ARM_ROTPK_S}
 
+ifeq ($(CRYPTO_ALG), ec)
+ifeq ($(KEY_SIZE), 384)
+ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
+ARM_SWD_ROT_KEY		:=	plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
+else
+ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
+ARM_SWD_ROT_KEY		:=	plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
+endif
+else
+ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_SWD_ROT_KEY		:=	plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
+endif
+
 # Allows platform code to provide implementation variants depending on the
 # selected chain of trust.
 $(eval $(call add_define,ARM_COT_${COT}))
 
 ifeq (${COT},dualroot)
 # Platform Root of Trust key files.
-ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_rsa.pem
-ARM_PROTPK_HASH		:=	plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+ARM_PROTPK			:=	$(BUILD_PLAT)/arm_protpk.bin
 
 # Provide the private key to cert_create tool. It needs it to sign the images.
 PROT_KEY		:=	${ARM_PROT_KEY}
 
-$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_PROTPK,'"$(ARM_PROTPK)"'))
 
 BL1_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S
 BL2_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S
 
-$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK)
 endif
 
 ifeq (${COT},cca)
 # Platform and Secure World Root of Trust key files.
-ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_rsa.pem
-ARM_PROTPK_HASH		:=	plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
-ARM_SWD_ROT_KEY		:=	plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
-ARM_SWD_ROTPK_HASH	:=	plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+ARM_PROTPK			:=	$(BUILD_PLAT)/arm_protpk.bin
+ARM_SWD_ROTPK		:=	$(BUILD_PLAT)/arm_swd_rotpk.bin
 
 # Provide the private keys to cert_create tool. It needs them to sign the images.
 PROT_KEY		:=	${ARM_PROT_KEY}
 SWD_ROT_KEY		:=	${ARM_SWD_ROT_KEY}
 
-$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
-$(eval $(call add_define_val,ARM_SWD_ROTPK_HASH,'"$(ARM_SWD_ROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_PROTPK,'"$(ARM_PROTPK)"'))
+$(eval $(call add_define_val,ARM_SWD_ROTPK,'"$(ARM_SWD_ROTPK)"'))
 
 BL1_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S \
 				plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
 BL2_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S \
 				plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
 
-$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK)
 endif
 
+$(ARM_PROTPK): $(ARM_PROT_KEY)
+ifndef ARM_PROT_KEY
+	$(error Cannot generate hash: no PROT_KEY defined)
+endif
+	${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in ${ARM_PROT_KEY} -pubout -outform DER | \
+	${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
+
+$(ARM_SWD_ROTPK): $(ARM_SWD_ROT_KEY)
+ifndef ARM_SWD_ROT_KEY
+	$(error Cannot generate hash: no SWD_KEY defined)
+endif
+	${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in ${ARM_SWD_ROT_KEY} -pubout -outform DER | \
+	${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
 endif
diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README
index 3aca180..15a0a9a 100644
--- a/plat/arm/board/common/protpk/README
+++ b/plat/arm/board/common/protpk/README
@@ -6,9 +6,12 @@
 
   openssl genrsa 2048 > arm_protprivk_rsa.pem
 
-* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
-  associated with the above private key. It has been generated using the openssl
-  command line tool:
+* arm_protprivk_ecdsa.pem is a P-256 ECSA private key in PEM format. It has been
+  generated using the openssl command line tool:
 
-  openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \
-    openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin
+  openssl ecparam -name prime256v1 -genkey -outform PEM -noout -out arm_protprivk_ecdsa.pem
+
+* arm_protprivk_ecdsa_secp384r1.pem is a P-384 ECSA private key in PEM format. It has been
+  generated using the openssl command line tool:
+
+  openssl ecparam -name secp384r1 -genkey -outform PEM -noout -out arm_protprivk_ecdsa_secp384r1.pem
\ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S
index 2688cbb..79b8c36 100644
--- a/plat/arm/board/common/protpk/arm_dev_protpk.S
+++ b/plat/arm/board/common/protpk/arm_dev_protpk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,10 +9,31 @@
 
 	.section .rodata.arm_protpk_hash, "a"
 
+/*
+* The protpk header is dependent only on the algorithm used to
+* generate the hash.
+* ASN1_HASH_ALG is the last byte used to encode the OID for
+* the hash algorithm into the header,
+* this byte distinguishes between SHA256, SHA384 and SHA512.
+*/
+.equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+#if ARM_ROTPK_HASH_LEN == 48
+	.equ ASN1_HASH_ALG, 0x02
+	.equ TOTAL_ASN1_LEN, 0x41
+#elif ARM_ROTPK_HASH_LEN == 64
+	.equ ASN1_HASH_ALG, 0x03
+	.equ TOTAL_ASN1_LEN, 0x51
+#elif ARM_ROTPK_HASH_LEN == 32
+	.equ ASN1_HASH_ALG, 0x01
+	.equ TOTAL_ASN1_LEN, 0x31
+#else
+	.error "Invalid PROTPK hash length."
+#endif
+
 arm_protpk_hash:
 	/* DER header. */
-	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
-	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+	.byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
 	/* Key hash. */
-	.incbin ARM_PROTPK_HASH
+	.incbin ARM_PROTPK
 arm_protpk_hash_end:
diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
deleted file mode 100644
index 587da66..0000000
--- a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-œó6{W*…`Ÿtíve×·§è£	€¾PžÆK{9
\ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem b/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
new file mode 100644
index 0000000..5888e10
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEILviumKhnibRT6+73/WOURk8lCxu/AHRQVcbCn/nGAr8oAoGCCqGSM49
+AwEHoUQDQgAE2HPZeAd+P8kZKHcCMfNUE+MlZSKJV360gYYC1JEdogyYztJ/QbKj
+26CZijUU/He2b9kkCOpZoJp3UuMRlsQE4Q==
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..d9db645
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCn+L3kRlvrZKnemt8aDOH+ujwuhpdwAM2ZxacxudJPy5qrWCjXGIh1
+gOAMHlGESySgBwYFK4EEACKhZANiAASM5exqdUZi0msFLGi42bIMW7FPqWsJ8YmL
+scDkI6BUYRoP0V4XZWB7NOjP6y/tm5Uwid9q25QTlhNKUo5qki1YH3T6unHuylWN
+63KRHQLOaXCXZqhMhT0wccg0gG3hs+0=
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
index 22ae9d3..f4a1875 100644
--- a/plat/arm/board/common/rotpk/arm_dev_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -6,20 +6,64 @@
 
 #include <plat/arm/board/common/rotpk/rotpk_def.h>
 
-	.global arm_rotpk_header
+#if ARM_ROTPK_IS_HASH == 1
+	.global arm_rotpk_hash_der_header
+	.global arm_rotpk_hash_end
 	.section .rodata.arm_rotpk_hash, "a"
 
-arm_rotpk_header:
-	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
-	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
-arm_rotpk_header_len:
+	#ifndef ARM_ROTPK_HASH_LEN
+	.error "ROTPK hash not defined."
+	#endif
 
-#ifdef ARM_ROTPK_HASH
-	.global arm_rotpk_hash_end
-	.incbin ARM_ROTPK_HASH
+	/*
+	* The rotpk header is dependent only on the algorithm used to
+	* generate the hash.
+	* ASN1_HASH_ALG is the last byte used to encode the OID for
+	* the hash algorithm into the header,
+	* this byte distinguishes between SHA256, SHA384 and SHA512.
+	*/
+	.equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+	#if ARM_ROTPK_HASH_LEN == 48
+		.equ ASN1_HASH_ALG, 0x02
+		.equ TOTAL_ASN1_LEN, 0x41
+	#elif ARM_ROTPK_HASH_LEN == 64
+		.equ ASN1_HASH_ALG, 0x03
+		.equ TOTAL_ASN1_LEN, 0x51
+	#elif ARM_ROTPK_HASH_LEN == 32
+		.equ ASN1_HASH_ALG, 0x01
+		.equ TOTAL_ASN1_LEN, 0x31
+	#else
+		.error "Invalid ROTPK hash length."
+	#endif
+
+arm_rotpk_hash_der_header:
+	.byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
+arm_rotpk_hash_der_header_len:
+
+#ifdef ARM_ROTPK
+	.incbin ARM_ROTPK
 arm_rotpk_hash_end:
 #endif
 
-.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
-.error "Invalid ROTPK header length."
-.endif
+	.if ARM_ROTPK_HASH_DER_HEADER_LEN != arm_rotpk_hash_der_header_len - arm_rotpk_hash_der_header
+		.error "Invalid ROTPK header length."
+	.endif
+
+#else
+	/*
+	* The rotpk is an unhashed public key in DER format.
+	* We do not need a header in this case.
+	*/
+	.global arm_rotpk_key
+	.section .rodata.arm_rotpk_key, "a"
+
+arm_rotpk_key:
+	#ifdef ARM_ROTPK
+		.global arm_rotpk_key_end
+		.incbin ARM_ROTPK
+arm_rotpk_key_end:
+	#else
+		.error "ROTPK not found."
+	#endif
+#endif
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
deleted file mode 100644
index 690bdbc..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-	.global arm_rotpk_key
-	.global arm_rotpk_key_end
-
-	.section .rodata.arm_rotpk_key, "a"
-
-/* Derived from arm_rotprivk_ecdsa.pem private key file. */
-arm_rotpk_key:
-	.byte 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
-	.byte 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01
-	.byte 0x07, 0x03, 0x42, 0x00, 0x04, 0x9B, 0xE6, 0x48, 0xBD, 0x34, 0x38
-	.byte 0xE1, 0xA2, 0xA4, 0xF3, 0x70, 0xE1, 0x54, 0xBB, 0x2F, 0xB0, 0x5A
-	.byte 0x4A, 0x0C, 0xFF, 0xC2, 0x87, 0xDB, 0xC0, 0xFB, 0x81, 0xE9, 0xF9
-	.byte 0xF9, 0x95, 0x7D, 0x7E, 0xA0, 0x0C, 0x7F, 0x0A, 0xD4, 0xE0, 0x62
-	.byte 0x4A, 0x94, 0x5F, 0xEC, 0x52, 0x7D, 0x44, 0x63, 0xC8, 0x9F, 0x61
-	.byte 0xFA, 0xC6, 0xCB, 0x7E, 0x6B, 0x53, 0xAD, 0x2C, 0xC5, 0x94, 0x0D
-	.byte 0x1A, 0x86, 0x91
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
deleted file mode 100644
index eaf2de4..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-	.global arm_rotpk_key
-	.global arm_rotpk_key_end
-
-	.section .rodata.arm_rotpk_key, "a"
-
-/* Derived from arm_rotprivk_ecdsa_secp384r1.pem private key file. */
-arm_rotpk_key:
-	.byte 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
-	.byte 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62
-	.byte 0x00, 0x04, 0xB8, 0xB0, 0xC7, 0xC4, 0x57, 0x19, 0xB7, 0x5A, 0x06
-	.byte 0x36, 0xC5, 0xD8, 0x3C, 0x4E, 0xC3, 0xB5, 0xE1, 0x15, 0x60, 0x0E
-	.byte 0x63, 0xD8, 0xAF, 0x22, 0x2C, 0x6D, 0x79, 0x29, 0xDF, 0x46, 0xA9
-	.byte 0x30, 0x12, 0x16, 0x2D, 0x4F, 0x0F, 0x96, 0x6B, 0x1F, 0x87, 0x06
-	.byte 0xDB, 0x8F, 0xD7, 0x08, 0x46, 0xE4, 0x4C, 0x22, 0xF3, 0xDE, 0xCE
-	.byte 0x0F, 0x72, 0x27, 0x00, 0xAA, 0xD8, 0xC3, 0x79, 0x80, 0x5E, 0xF1
-	.byte 0x35, 0x1B, 0x33, 0xB6, 0x31, 0xC4, 0x59, 0xD4, 0xE9, 0x65, 0x91
-	.byte 0x22, 0x58, 0x2F, 0x87, 0xF1, 0x6C, 0x27, 0xBE, 0x99, 0x6F, 0x5F
-	.byte 0x6C, 0x14, 0xC5, 0x37, 0x0C, 0x73, 0xB4, 0xE4, 0x8A, 0x63
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
deleted file mode 100644
index 4532e53..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-	.global arm_rotpk_key
-	.global arm_rotpk_key_end
-
-	.section .rodata.arm_rotpk_key, "a"
-
-arm_rotpk_key:
-	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48
-	.byte 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01
-	.byte 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00
-	.byte 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7
-	.byte 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71
-	.byte 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1
-	.byte 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69
-	.byte 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26
-	.byte 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79
-	.byte 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1
-	.byte 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83
-	.byte 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26
-	.byte 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51
-	.byte 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1
-	.byte 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90
-	.byte 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A
-	.byte 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD
-	.byte 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
-	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0
-	.byte 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D
-	.byte 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C
-	.byte 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE, 0x0E, 0xA3, 0x4D, 0xC7
-	.byte 0xD4, 0x7E, 0xA7, 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8
-	.byte 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40
-	.byte 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3
-	.byte 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21
-	.byte 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der b/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der
deleted file mode 100644
index 2547877..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der
+++ /dev/null
Binary files differ
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin b/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
deleted file mode 100644
index c5e123a..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-.@¿nù»˜1q	=ýÑÌiJ˜ë‹ ° †Nl
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_rsa.der b/plat/arm/board/common/rotpk/arm_rotpk_rsa.der
deleted file mode 100644
index 661f899..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_rsa.der
+++ /dev/null
Binary files differ
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin b/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
deleted file mode 100644
index 7653f7e..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-°ó‚	—Ø:7zrGì2sé’2âIYö^‹JJFØ"šÚ
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem
new file mode 100644
index 0000000..842979d
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQCi82DxdQ1Z88RT
+DBoK8nBZ3SF4YSnOSV3KXODZHtEJq/D1HihLpCITsB1GkR17qGX5XzjcIvrS7tGC
+1Y/ELC+wL1DNoNlLsgwfZdQ3+MGGlkymnK37/b5Q1bvkuthAHg415skvdzX+6tpM
+y3bbGn55oW+hjynGo9lhixZiOA22sKhHFM6TBgpyNyXt/EpxGHcL4HM59LSWgB3I
+UX6l0Fb5MLb3XRzOkPcf6tQwnupDRS8rcRKHlkq8m0kIZ619zDkj4DZVW7VSU3hj
+vnzMMTEqbJ9uBnGFLdTqw2O822jOtKJ8pDqcN1xEe60a0CN0abN5uNzr9WPgLw5d
+ZjWqTx2kFVbjIr5nAiY6KTUoas/radidv/r5BY4wXvbi/SVNHip4oLoKCgu6T+Un
+pIc5DG0osXKO/xtT5gsQUZ/AXEztCsEeuwkueEZ8c1AG+ceoOul/zH4y0YrFGzxV
+apwwRuXZQtjU0lXpFlD1Yy83QzkrxWgEfE5mUm402TRF92oLsY8CAwEAAQKCAYA5
+QBwLyW3G8FPGP8a4mOQrVntncW/AN9uZeRdQgTi9VqkiXZWXudN1Klemzt5Wb1xg
+iHmQMkQArwJyHrlTmZippH4VuNEPfL8wmtS8U4wezpigowSnt8dRXD6XBqRqpoSk
+oHCH2jDg3r+S4ptgMIdGEZeIYiWx0ihSUo0rNflvedKtopxPYHx0E3cijZTT9l4B
+ELs7HgQCqoGMO0GtXSzpgRmPgCnaU2lXz+f8KyEwQFLpxuDVPVMFv+Mhblewjnrn
+IpDUAocRPI1n0cOrObHHnnpVzkKpz4usxBfsvc+9Qg37hS/1ccbOWKPjA/LS9dOC
+w29J6pa3Az9AGQ6OdZlhbaOH7hMj4gmreC/4omtgV+IhOL65TeMeBwIY0Vb4gtCQ
+yHhu2eT99MeL+G/Zw+00RRqzKl898tnYTvBkFG1llIFyT9LRqPY8lRHAQzzgNTRq
+ZpwTAijCRxmBAIDdBkXQai/En2PP3LMuORZ9+2zYu5uIJeZnBoHKONtDlpOpKpkC
+gcEA2HkeVlfmFgiBen4QMRKCseB9II9s+xiPjk8VpWT2TRmsVPEmKRrIKkXER2YO
+yYG97vBocECQXOHB0dNNUTMtbnFvY9B0FAswcUwtWPdjafrqmPe6iIZkynTaFqCG
+nY52P4EYZsSF3YthXkkzZuwzaQ/zyVA5W2HXp/XL8SKj9uPA3dEMP114Of9jNlmH
++gfpNY49tiXomR1DX/k6nmyJyeG9eUVBGlmxERK72g/7OynYLK8o/7T3m8SUW5lq
+R5hZAoHBAMC0ZI36iq2m18xtEx84nrlipbRRRahIeb2bXziPBL3yEbomotwrabDl
+GExl3PpfAEUlNnqseZ3GS2EpESsEbOBnLuWmviF528pX/H/pw87AVjuseUZQOjzI
+GzuJu+Of0DNlt7FJsaWrOJeNqT0t1w0JiII3uEekmIC59740lyUJ2sVZlDq6Gf7i
+etV+7oqGn+aAmXgug0wszezMaYH8ZNjLgrxkxIsLSONQ8tUX3CYXglkqty0/JRVA
+ZCluTQ/cJwKBwHzESlz/qoi2fFIqiJCQF64IMnZq1ChhPpSKNnKun1tO2cnXd+Qn
+IIlkzr1MMGeqFNu7yqYwQESYhgq23BBaC+xlCwufoNfQnyod+uEVLUJvMXnbBrMb
+qsoZ0X1LJmt3KeZuNK8+w90uMX+Td0HyD6uVWzCDwZtO6GpRPCuOiKyLFqWCkKmQ
+6POcpAU2Uy4kEyEgC6eJb+eYOzX8wvF+o2gtaPSVmvFiErFBd+42Wdn+wy72Ag5n
+snMgOVYWNXBweQKBwQCcsBEzAIzSNd8x8V6i/D7TLkreG1cwRf33FeaO7ntElxei
+7Ndvfj0qAJ2JQSo0yhpGHsP1a1hX2WxhTCsRdz+wFzYitTnTrmnwVSqSN1lnOyzi
+yJKzgXhZA7xg5NVJeCCqKgL6vJkdw+L4F8+MV0GM8Dt25ieI2WTHBm9S0SA0lZa0
+8Ol99uQ8Q5rtDZCYQm6x1c7z0Z4gyi2GZY9EihzVymQ7GxRUmpBhhOhuLEBtGKB8
+MCdROw7EAN9wcKdoRfECgcB5zqNzKu2kbpa0oeHLLDpcOK1w9e7khN3/j3dTrpRw
+em8+HoCF54PoyfkPWANTHfg+Bs2gktgvUsxfLy0/DDBIRUBQXo6AyztfB34D5/3L
+QIPyPjSgQKxOCnUCcDAkvVRY+6J7W6J/pW385ZhzikCUrRSKrbc3UYEu3UZwypSC
+mJGKLUzhDhPYvIginpIugE9Pv3WXfKas3HRrk7UdqjIMpJxIRF5CULsEaZua6tje
+1oA5miNwoiXHcxPoo2qMtz8=
+-----END PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem
new file mode 100644
index 0000000..2309ee6
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDGeG6dmMX7DHdx
+LJ5vi3HpqSLVfyiGzYmjN14bcOORf1efCXy+0KfZ4M/N1rw/fVzIH6LP6iKm8rrH
+HQleKMb2rklbu8Azchr9fAJCbbbhENjhbp+lnh5W+bMWlhz4ePoSft/VNDssK/30
+tedSX7AEqs8nXOcqIjcOTnkB1UocNSAd98WP+m7oeqcwrJZGFj2HKHPkZiveX4c6
+5pN7xsdeuJ00FbOau7R3tX+0hInbTCxuA9UfPR9O+TrElMETPBCwvYUDo8SO0Oj9
+Vn3VsMYLuYfOQuHY65pgepBytgu6MTL8mKGxMTZ3HeaBfD2cDzf1tOe3PoN2eeBA
+eGHt/L9R7z0/84kfWDJg8zG9eSfCofXJy3HNlYAWo7fIdRaidNc75vU3DWRYrCE2
+OLwR+3pIRUoP+Pa1Xhaal/mXH9MHKNvK2aBz2QPgjaujMNlh9yLLtBjnBAcO9IXh
+ktS2pnEYwf+Rh2Nepy2sJa4Q88ZD7Uz8MZl7z/zNUjNpehDIe7oM8NXMt/i1DWqe
+XZoLfTdb7C77hgNfporBxkeqduhGGcu+RUgdAOMEJvFA4022iiZIJDkWeaiFZWI4
+iy9bmFd+VOXabCIAjb0Nl6F5TAROJ/mH9UjyT8hKlXYhnRu912+yEaFAlqiXk2rz
+kYbGGzj9zUMzClM52wJ7Btj50dz0eQIDAQABAoICAB62uHePEuRc84cCHqqoa8J7
+ODbN7NmfqTMm+FtKxwzXJhoof7OP2snu7nmuR4eTwO3/Z1TBqQco/RqfNbnqmY/H
+PPcDQSU0/VRJApiBHhIKZ2XLls0sgQl4ruxJ4sXZAuol1EHMSXP2guCB3gBzamvu
+ewxeZi+xB9Ag+Lz94vAmkIfStjIn0U4M3R69Nqw1+OOXsQehgBxzsBu/XweCpYvV
+Cg7rZNYHQlBcOB0ZfbQAP8fus+aXsOapzxxo4NA3NWYEjjcX+u0XC1dZMTQGnT9n
+QMr8srK9EzDnBr+ZyIrR3lAU1sDzGrioWemj7mzeNgzCKDHFbNbC2Z9ggdcwi/K+
+SX3ckR8phNkhGyIWImt5ChY19d/yh53A/FwFEJU4R/HiM0GFj8bxWMRr01R1TJV6
+UUb6c4L/T95URqe05bTAWz/BUUWirGs8F03NUp/8PvXquUJiKs3eEMHeyHDIt2Rj
+mB0bi+nr0qe4C7Y5yU9+Giw9RnV7slBkQvohA7mHXRlneenQx+Lh1v2fNk+Z+eVF
+Y7HBdTiNeavW8ZReoVgicqA8w2KZgbiDAhhJ2pzefpREjVAnY2endbMX4faqfEMF
+y6StIsg4rplrxojVIYftQ+nenSV0H+5I6+YsIk4XTirGYuBhccoko0ApRJx9VdX2
++UJU49UPHK2fTdqqouc5AoIBAQDmEqfyXQdf+5njZ3zx9cJFKRXB8SiFIDNZeSDL
+b8ph7py1YfinM163Xyb2/5oTB19tcNcfAaPoFOHJ8FDzXmSW3aUHKrB+sh8Q+aOH
+/3u6y2+dBEBNGPbtSxmMswVYK2z0K6NzzeZSZnqus0J61RPuG8EnO25PdMx9xOg/
+cPWTrxYNUYIBqSdhjm8K5BaTrkOf49Wur/0MZlcULVoatFzc3H/L3qyePvptKAwT
+V68bZeM2mXWhC3X953kxX5haClWZPJhf9sLESIeoOleaMi5yBvX6r7JKiFJy3Fwk
+dV7lPWr9fEkVtVoveHklCW8Ra6JbMizV7i1S5fmUcaUmgbbTAoIBAQDc1hTMI98o
+7hDEqh1cHtPmh1u9rLgJEMYLirUn/u4QDV6SUpT1Bpu55usLn+NFDyKfpEh1IU4r
+4CjfrjP15e2WLs+IOU+LvbDqbps7mEnq/TFWwr1YcjUVpur4SphJkqFHU/ztV6RC
+FbTA8656kb34YrILDnjgM7G1TKvWRHxzqdDCasPnlv7ch2/vtwv5zcVfTSNjixFb
+b8FCPy8WI6/LIFjKmSliLaeRb0NaUAWwMQ2qMEuP+rsGaq4Lr/6zf/UjSUcTgKzQ
+GSVm5cdJqjcqULFQzFZaOoG7Dht+ZJXumwc0G+k1eTuDAnYRs5CkEggtrnK9WfGm
+nBvGOAdeBvADAoIBAAPayCmNWXRIONnQgA1luq2B9LVdHvqsAXA8UUpXQyLE5qc7
+TvkuKSYVWAfHXIN5GiYxP8lrM53Ny8KgXhrVuAW3DO7DzlUxEsgsBotewmnswp/0
+1Eb2Zhyvp2vuC+bgQ2EL4h8skfFLej63DiQUsdLJcEECA+Uc5dgtll6Ju/OPeWUb
+unvgo6JEyqN6Es7CmqtxG8FjfW/Zvxe9cscDwpKItzNpNacpEvUFOL6SN4LUACyI
+AaqDEKUCXctv+JN5nNmGZF8nOTgkpvEwmQsiUBjk+PYMP4Z0Jj16Z6jMtpxMnSBG
+FstgUHR/JjhyogO+s+enPY0QAn5jD/1msgelILUCggEBAMV5emeBvFBxcfUq2c5C
+kuIWMGdQR9FzemVfx9bYFDGugt79kc359s8qOwzOEQD0I9X1pgV3ntuFO4ep0zUU
+QnyFp3b9KLChE87O0WldKNxFRRV8Vqz8k5OlC4Cz07IWuLl71TS3pl6h4lyYi3F3
+WhT+zI8uhdCW6VZiFVcpLtCPDeqMZlp1n7m8MtB9MuxSoSgzZm3hMcg+CucecRCv
+IMfXSQ8CHwt4H9vhTq032Z5QfxOs1CUP5KY8Rx6UZoJE7gR7xl8eNWpw0g1NdAPf
+fi0Ms0K5No7Aurl2SAeiEqCnaK2kN8plel4QmVwC4liU91NCJ8BC6eA+wGdkOtJO
+CdkCggEAG6v3cc6mw/kA3l+z21NzAXFUnYy7Q9xxl6noNBdNtT+vBQJ2jbEISSqi
+RM48KKtky2pgFWB980XUS1ZI8SiZ9GveM9bCSgpN+zupSdKNBaxT7+AKO/MPKMeO
+hukkWqtNCwFs6opByhLMRMC2UAKRSvTZBlrCUyIBY2EB6IzsqqQGdoAHOw2fDWay
+7C79JxtEl/XH10Et7zeWEI2uz6JK4TmSd2ZZu6m/X1UU6BHZJTHpItZlTnp14QYc
+hpHcRHU5d5i+ARQ+kUUynfEyAabY6sBIn3lxXqa9FplR0vqbtxyZPtQh1ZP11drD
+ihQEUR+haaYi8LFFpxe3Lja8D5eclg==
+-----END PRIVATE KEY-----
diff --git a/plat/arm/board/common/swd_rotpk/README b/plat/arm/board/common/swd_rotpk/README
index b628a5f..18fea4c 100644
--- a/plat/arm/board/common/swd_rotpk/README
+++ b/plat/arm/board/common/swd_rotpk/README
@@ -6,9 +6,12 @@
 
   openssl genrsa 2048 > arm_swd_rotprivk_rsa.pem
 
-* swd_rotpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
-  associated with the above private key. It has been generated using the openssl
-  command line tool:
+* arm_swd_rotprivk_ecdsa.pem is a P-256 ECSA private key in PEM format. It has been
+  generated using the openssl command line tool:
 
-  openssl rsa -in arm_swd_rotprivk_rsa.pem -pubout -outform DER | \
-    openssl dgst -sha256 -binary > arm_swd_rotpk_rsa_sha256.bin
+  openssl ecparam -name prime256v1 -genkey -outform PEM -noout -out arm_swd_rotprivk_ecdsa.pem
+
+* arm_swd_rotprivk_ecdsa_secp384r1.pem is a P-384 ECSA private key in PEM format. It has been
+  generated using the openssl command line tool:
+
+  openssl ecparam -name secp384r1 -genkey -outform PEM -noout -out arm_swd_rotprivk_ecdsa_secp384r1.pem
diff --git a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
index ae4f9d2..2056bbe 100644
--- a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+++ b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,10 +9,31 @@
 
 	.section .rodata.arm_swd_rotpk_hash, "a"
 
+/*
+* The swd_roptpk header is dependent only on the algorithm used to
+* generate the hash.
+* ASN1_HASH_ALG is the last byte used to encode the OID for
+* the hash algorithm into the header,
+* this byte distinguishes between SHA256, SHA384 and SHA512.
+*/
+.equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+#if ARM_ROTPK_HASH_LEN == 48
+	.equ ASN1_HASH_ALG, 0x02
+	.equ TOTAL_ASN1_LEN, 0x41
+#elif ARM_ROTPK_HASH_LEN == 64
+	.equ ASN1_HASH_ALG, 0x03
+	.equ TOTAL_ASN1_LEN, 0x51
+#elif ARM_ROTPK_HASH_LEN == 32
+	.equ ASN1_HASH_ALG, 0x01
+	.equ TOTAL_ASN1_LEN, 0x31
+#else
+	.error "Invalid SWD_ROTPK hash length."
+#endif
+
 arm_swd_rotpk_hash:
 	/* DER header. */
-	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
-	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+	.byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
 	/* Key hash. */
-	.incbin ARM_SWD_ROTPK_HASH
+	.incbin ARM_SWD_ROTPK
 arm_swd_rotpk_hash_end:
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
deleted file mode 100644
index b2f3e60..0000000
--- a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-0¾âÃ’æœÈË“(ì¨0ŠwIӁÕéã¡gk
\ No newline at end of file
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
new file mode 100644
index 0000000..be40565
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFmIjAPUmyqDfKXT+kKRMvyFzQfaZekczIzSPfLeQUGyoAoGCCqGSM49
+AwEHoUQDQgAEtZB8OrBV7hPl+lBrc5ypKetwGsUi+SpTK8OoMw0GwA17rGDYdBTV
+JK2ttZNtCsGzlDrXeHu6bcTmrleMdW9NdQ==
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..14ad7f7
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDC348NhWsLI30vzJnWofKae6t3S6YIb5rdLEJSUyI9XwKj8FyJO8N3G
+DNgvVBwk4NigBwYFK4EEACKhZANiAARodLWP/EGH7/SrImvwDJr1zACOrh8acVH/
+eymfvZW2af4DPRMPyUC5Ftzv6NwGz6yPzBbAg9+qDgLgO7cqwXOwVON+hAU+ECEZ
+3AIQ7zLDfnXcfNz8dv1kwkwhfDJeQCs=
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts b/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
new file mode 100644
index 0000000..df6810f
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <platform_def.h>
+
+/ {
+#define MODE_SEL0	(0x1)
+#define MODE_SEL1	(0x2)
+
+#define SECURE_RO 0x1
+#define SECURE_RW 0x3
+#define SECURE_EXECUTE_RO 0x5
+#define SECURE_EXECUTE_RW 0x7
+#define NON_SECURE_RO 0x9
+#define NON_SECURE_RW 0xB
+#define NON_SECURE_EXECUTE_RO 0xD
+#define NON_SECURE_EXECUTE_RW 0xF
+	/*
+	 * FF-A compatible Secure Partition Manager parses the
+	 * config file and fetch the following booting arguments to
+	 * pass on to the StandAloneMM(StMM) Secure Partition.
+	 */
+	compatible = "arm,ffa-manifest-1.0";
+
+	description = "FVP Base StandaloneMm";
+	ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0xdcae8d37 0x46446bf0 0xab401483 0xa3873c93>;
+	id = <0x8001>;
+	execution-ctx-count = <PLATFORM_CORE_COUNT>;
+	exception-level = <MODE_SEL0>; /* SEL0*/
+	execution-state = <0>; /* AArch64*/
+	load-address = <0x0 0xff200000>;
+	image-size = <0x0 0x00300000>;
+	xlat-granule = <0>; /* 4KiB */
+	boot-order = <0>;
+	messaging-method = <0x603>; /* Direct req/resp/req2/resp2 supported. */
+	gp-register-num = <0>;
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		/**
+		 * System registers, rtc, uart and etc regions for access from S-EL0.
+		 */
+		io_fpga {
+			base-address = <0x0 0x1C000000>;
+			pages-count = <0x3000>;
+			attributes = <SECURE_RW>;
+		};
+
+		system_reg_el0 {
+			base-address = <0x0 0x1C010000>;
+			pages-count = <0x10>;
+			attributes = <SECURE_RW>;
+		};
+
+		/**
+		 * ARM CSS SoC Peripherals area.
+		 * Similar to SOC_CSS_MAP_DEVICE.
+		 */
+		soc_components {
+			base-address = <0x0 0x20000000>;
+			pages-count = <0xc200>;
+			attributes = <SECURE_RO>;
+		};
+
+		/**
+		 * NOR0 Flash region, used for Firmware Image Update.
+		 */
+		nor_flash0 {
+			base-address = <0x0 0x08000000>;
+			pages-count = <0x4000>;
+			attributes = <SECURE_RW>;
+		};
+
+		/**
+		 * NOR1 Flash region, used for Secure booting.
+		 */
+		nor_flash1 {
+			base-address = <0x0 0x0c000000>;
+			pages-count = <0x4000>;
+			attributes = <SECURE_RW>;
+		};
+	};
+
+	memory-regions {
+		compatible = "arm,ffa-manifest-memory-regions";
+
+		/*
+		 * SPM Payload memory. Mapped as code region for S-EL0
+		 * Similar to ARM_SP_IMAGE_MMAP.
+		 */
+		stmm_region {
+			description = "image";
+			base-address = <0x0 0xff200000>;
+			pages-count = <0x300>;
+			/* StMM will remap the regions during runtime */
+			attributes = <SECURE_EXECUTE_RO>;
+		};
+
+		/*
+		 * Memory shared between EL3 and S-EL0.
+		 * Similar to ARM_SPM_BUF_EL0_MMAP.
+		 */
+		rx-tx-buffers {
+			description = "shared-buff";
+			base-address = <0x0 0xff500000>;
+			pages-count = <0x100>;
+			attributes = <SECURE_RW>;
+		};
+
+		/*
+		 * Memory shared between Normal world and S-EL0.
+		 * Similar to ARM_SP_IMAGE_NS_BUF_MMAP.
+		 */
+		ns_comm_buffer {
+			/*
+			 * Description is needed for StMM to identify
+			 * ns-communication buffer.
+			 */
+			description = "ns-comm";
+			base-address = <0x0 0xff600000>;
+			pages-count = <0x10>;
+			attributes = <NON_SECURE_RW>;
+		};
+
+		/*
+		 * Heap used by SP to allocate memory for DMA.
+		 */
+		heap {
+			/*
+			 * Description is needed for StMM to identify
+			 * heap buffer.
+			 */
+			description = "heap";
+			base-address = <0x0 0xFF610000>;
+			pages-count = <0x7F0>;
+			attributes = <SECURE_RW>;
+		};
+	};
+};
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index ebdd80d..8dcdd62 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -48,8 +48,6 @@
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
-	struct transfer_list_entry *te __unused;
-
 #if TRANSFER_LIST
 	arg0 = arg3;
 #endif
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 0c5a76c..bdc2cac 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -575,6 +575,23 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
+/*
+ * Calculate checksum of 64-bit words @buffer with @size length
+ */
+static uint64_t checksum_calc(uint64_t *buffer, size_t size)
+{
+	uint64_t sum = 0UL;
+
+	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
+	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
+
+	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
+		sum += buffer[i];
+	}
+
+	return sum;
+}
+
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
 	uint64_t checksum, num_banks, num_consoles;
@@ -661,16 +678,13 @@
 
 	/* Store FVP DRAM banks data in Boot Manifest */
 	for (unsigned long i = 0UL; i < num_banks; i++) {
-		uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
-		uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
-
-		bank_ptr[i].base = base;
-		bank_ptr[i].size = size;
-
-		/* Update checksum */
-		checksum += base + size;
+		bank_ptr[i].base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
+		bank_ptr[i].size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
 	}
 
+	/* Update checksum */
+	checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct ns_dram_bank) * num_banks);
+
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
 
@@ -678,18 +692,18 @@
 	checksum = num_consoles + (uint64_t)console_ptr;
 
 	/* Zero out the console info struct */
-	memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
+	(void)memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
 
-	console_ptr[0].map_pages = 1;
 	console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
+	console_ptr[0].map_pages = 1UL;
 	console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
 	console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
 
-	strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN-1UL);
+	(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN - 1UL);
 
 	/* Update checksum */
-	checksum += console_ptr[0].base + console_ptr[0].map_pages +
-		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+	checksum += checksum_calc((uint64_t *)console_ptr,
+					sizeof(struct console_info) * num_consoles);
 
 	/* Checksum must be 0 */
 	manifest->plat_console.checksum = ~checksum + 1UL;
diff --git a/plat/arm/board/fvp/fvp_el3_token_sign.c b/plat/arm/board/fvp/fvp_el3_token_sign.c
new file mode 100644
index 0000000..282f94a
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_token_sign.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+#include <services/rmm_el3_token_sign.h>
+
+static struct el3_token_sign_request el3_req = { 0 };
+static bool el3_req_valid;
+
+/*
+ * According to https://www.secg.org/sec1-v2.pdf 2.3.3
+ * the size of the ECDSA P384 public key is 97 bytes,
+ * with the first byte being 0x04.
+ */
+static uint8_t sample_attest_pub_key[] = {
+	0x04, 0x76, 0xf9, 0x88, 0x09, 0x1b, 0xe5, 0x85, 0xed, 0x41,
+	0x80, 0x1a, 0xec, 0xfa, 0xb8, 0x58, 0x54, 0x8c, 0x63, 0x05,
+	0x7e, 0x16, 0xb0, 0xe6, 0x76, 0x12, 0x0b, 0xbd, 0x0d, 0x2f,
+	0x9c, 0x29, 0xe0, 0x56, 0xc5, 0xd4, 0x1a, 0x01, 0x30, 0xeb,
+	0x9c, 0x21, 0x51, 0x78, 0x99, 0xdc, 0x23, 0x14, 0x6b, 0x28,
+	0xe1, 0xb0, 0x62, 0xbd, 0x3e, 0xa4, 0xb3, 0x15, 0xfd, 0x21,
+	0x9f, 0x1c, 0xbb, 0x52, 0x8c, 0xb6, 0xe7, 0x4c, 0xa4, 0x9b,
+	0xe1, 0x67, 0x73, 0x73, 0x4f, 0x61, 0xa1, 0xca, 0x61, 0x03,
+	0x1b, 0x2b, 0xbf, 0x3d, 0x91, 0x8f, 0x2f, 0x94, 0xff, 0xc4,
+	0x22, 0x8e, 0x50, 0x91, 0x95, 0x44, 0xae
+};
+
+/*
+ * FVP does not support HES, so provide 0's as keys.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					 unsigned int type)
+{
+	(void)type;
+	if (*len < sizeof(sample_attest_pub_key)) {
+		return E_RMM_INVAL;
+	}
+
+	if (type != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	*len = sizeof(sample_attest_pub_key);
+
+	(void)memcpy((void *)buf, sample_attest_pub_key,
+		     sizeof(sample_attest_pub_key));
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_push_req(const struct el3_token_sign_request *req)
+{
+	/*
+	 * TODO: Today this function is called with a lock held on the
+	 * RMM<->EL3 shared buffer. In the future, we may move to a
+	 * different design that may require handling multi-threaded
+	 * calls to this function, for example, if we have a per CPU
+	 * buffer between RMM and EL3.
+	 */
+	if (el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	el3_req = *req;
+
+	if ((el3_req.hash_alg_id != EL3_TOKEN_SIGN_HASH_ALG_SHA384) ||
+	    (el3_req.sig_alg_id != ATTEST_KEY_CURVE_ECC_SECP384R1)) {
+		return E_RMM_INVAL;
+	}
+
+	el3_req_valid = true;
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp)
+{
+	if (!el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	resp->rec_granule = el3_req.rec_granule;
+	resp->req_ticket = el3_req.req_ticket;
+	resp->sig_len = (uint16_t)sizeof(resp->signature_buf);
+	/* TODO: Provide real signature */
+	memset(resp->signature_buf, 0, sizeof(resp->signature_buf));
+
+	el3_req_valid = false;
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index b3d503e..80dfd2a 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -323,13 +323,13 @@
 			     unsigned int power_level)
 {
 	unsigned int psysr;
-	int ret;
+	int ret = 0;
 
 	/*
 	 * The format of 'power_level' is implementation-defined, but 0 must
 	 * mean a CPU. We also allow 1 to denote the cluster
 	 */
-	if ((power_level != ARM_PWR_LVL0) && (power_level != ARM_PWR_LVL1))
+	if ((power_level < ARM_PWR_LVL0) || (power_level > ARM_PWR_LVL1))
 		return PSCI_E_INVALID_PARAMS;
 
 	/*
@@ -343,9 +343,14 @@
 
 	if (power_level == ARM_PWR_LVL0) {
 		ret = ((psysr & PSYSR_AFF_L0) != 0U) ? HW_ON : HW_OFF;
-	} else {
-		/* power_level == ARM_PWR_LVL1 */
-		ret = ((psysr & PSYSR_AFF_L1) != 0U) ? HW_ON : HW_OFF;
+	} else if (power_level == ARM_PWR_LVL1) {
+	/*
+	 * Use L1 affinity if MPIDR_EL1.MT bit is not set else use L2 affinity.
+	 */
+		if ((read_mpidr_el1() & MPIDR_MT_MASK) == 0U)
+			ret = ((psysr & PSYSR_AFF_L1) != 0U) ? HW_ON : HW_OFF;
+		else
+			ret = ((psysr & PSYSR_AFF_L2) != 0U) ? HW_ON : HW_OFF;
 	}
 
 	return ret;
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 573d92e..5b97034 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -24,7 +24,7 @@
 
 	const arm_tzc_regions_info_t fvp_tzc_regions[] = {
 		ARM_TZC_REGIONS_DEF,
-#if !SPM_MM && !ENABLE_RME
+#if !SPM_MM && !ENABLE_RME && !(SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 		{FVP_DRAM3_BASE, FVP_DRAM3_END,
 		 ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},
 		{FVP_DRAM4_BASE, FVP_DRAM4_END,
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index e0c9725..df4be8f 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -170,6 +170,8 @@
 # elif SPMC_AT_EL3
 #  define PLAT_ARM_MMAP_ENTRIES		13
 #  define MAX_XLAT_TABLES		11
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	30
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		9
 #  if USE_DEBUGFS
@@ -220,7 +222,8 @@
  * In case of PSA Crypto API, few algorithms like ECDSA needs bigger BL1 RW
  * area.
  */
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO || \
+FVP_TRUSTED_SRAM_SIZE == 512
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xC000)
 #else
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xB000)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 077283e..a23de73 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -37,28 +37,5 @@
 fdt     fdt_get_alias
 fdt     fdt_node_offset_by_phandle
 fdt     fdt_add_subnode
-mbedtls mbedtls_asn1_get_alg
-mbedtls mbedtls_asn1_get_alg_null
-mbedtls mbedtls_asn1_get_bitstring_null
-mbedtls mbedtls_asn1_get_bool
-mbedtls mbedtls_asn1_get_int
-mbedtls mbedtls_asn1_get_len
-mbedtls mbedtls_asn1_get_tag
-mbedtls mbedtls_free
-mbedtls mbedtls_md
-mbedtls mbedtls_md_get_size
-mbedtls mbedtls_memory_buffer_alloc_init
-mbedtls mbedtls_oid_get_md_alg
-mbedtls mbedtls_oid_get_numeric_string
-mbedtls mbedtls_oid_get_pk_alg
-mbedtls mbedtls_oid_get_sig_alg
-mbedtls mbedtls_pk_free
-mbedtls mbedtls_pk_init
-mbedtls mbedtls_pk_parse_subpubkey
-mbedtls mbedtls_pk_verify_ext
-mbedtls mbedtls_platform_set_snprintf
-mbedtls mbedtls_x509_get_rsassa_pss_params
-mbedtls mbedtls_x509_get_sig_alg
-mbedtls mbedtls_md_info_from_type
 c       exit
 c       atexit
diff --git a/plat/arm/board/fvp/jmptbl_mbedtls.i b/plat/arm/board/fvp/jmptbl_mbedtls.i
new file mode 100644
index 0000000..6e1f017
--- /dev/null
+++ b/plat/arm/board/fvp/jmptbl_mbedtls.i
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform-specific ROMLIB MbedTLS functions can be added here.
+# During the build process, this file is appended to jmptbl.i
+# if MbedTLS support is required.
+#
+# Format:
+# lib   function        [patch]
+# Example:
+# mbedtls mbedtls_asn1_get_alg
+# mbedtls mbedtls_asn1_get_alg_null patch
+
+mbedtls mbedtls_asn1_get_alg
+mbedtls mbedtls_asn1_get_alg_null
+mbedtls mbedtls_asn1_get_bitstring_null
+mbedtls mbedtls_asn1_get_bool
+mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
+mbedtls mbedtls_asn1_get_tag
+mbedtls mbedtls_free
+mbedtls mbedtls_md
+mbedtls mbedtls_md_get_size
+mbedtls mbedtls_memory_buffer_alloc_init
+mbedtls mbedtls_oid_get_md_alg
+mbedtls mbedtls_oid_get_numeric_string
+mbedtls mbedtls_oid_get_pk_alg
+mbedtls mbedtls_oid_get_sig_alg
+mbedtls mbedtls_pk_free
+mbedtls mbedtls_pk_init
+mbedtls mbedtls_pk_parse_subpubkey
+mbedtls mbedtls_pk_verify_ext
+mbedtls mbedtls_platform_set_snprintf
+mbedtls mbedtls_x509_get_rsassa_pss_params
+mbedtls mbedtls_x509_get_sig_alg
+mbedtls mbedtls_md_info_from_type
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 1e90bcb..8793840 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -61,6 +61,9 @@
 
       ENABLE_BRBE_FOR_NS	:= 2
       ENABLE_TRBE_FOR_NS	:= 2
+      ENABLE_FEAT_D128		:= 2
+      ENABLE_FEAT_FPMR		:= 2
+      ENABLE_FEAT_MOPS		:= 2
 endif
 
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
@@ -76,12 +79,15 @@
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_FGT2		:= 2
+ENABLE_FEAT_THE			:= 2
 ENABLE_FEAT_TCR2		:= 2
 ENABLE_FEAT_S2PIE		:= 2
 ENABLE_FEAT_S1PIE		:= 2
 ENABLE_FEAT_S2POE		:= 2
 ENABLE_FEAT_S1POE		:= 2
+ENABLE_FEAT_SCTLR2		:= 2
 ENABLE_FEAT_MTE2		:= 2
+ENABLE_FEAT_LS64_ACCDATA	:= 2
 
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -199,6 +205,7 @@
 					lib/cpus/aarch64/cortex_a710.S		\
 					lib/cpus/aarch64/cortex_a715.S		\
 					lib/cpus/aarch64/cortex_a720.S		\
+					lib/cpus/aarch64/cortex_a720_ae.S	\
 					lib/cpus/aarch64/neoverse_n_common.S	\
 					lib/cpus/aarch64/neoverse_n1.S		\
 					lib/cpus/aarch64/neoverse_n2.S		\
@@ -214,10 +221,12 @@
 
 #Build AArch64-only CPUs with no FVP model yet.
 ifeq (${BUILD_CPUS_WITH_NO_FVP_MODEL},1)
-	FVP_CPU_LIBS    +=	lib/cpus/aarch64/neoverse_n3.S	\
+	FVP_CPU_LIBS    +=	lib/cpus/aarch64/neoverse_n3.S		\
 				lib/cpus/aarch64/cortex_gelas.S		\
 				lib/cpus/aarch64/nevis.S		\
-				lib/cpus/aarch64/travis.S
+				lib/cpus/aarch64/travis.S		\
+				lib/cpus/aarch64/cortex_arcadia.S	\
+				lib/cpus/aarch64/cortex_alto.S
 endif
 
 else
@@ -269,7 +278,8 @@
 				plat/arm/board/fvp/fvp_cpu_pwr.c
 
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
-				plat/arm/board/fvp/fvp_realm_attest_key.c
+				plat/arm/board/fvp/fvp_realm_attest_key.c	\
+				plat/arm/board/fvp/fvp_el3_token_sign.c
 endif
 
 ifeq (${ENABLE_FEAT_RNG_TRAP},1)
@@ -334,18 +344,12 @@
 endif
 
 # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
-ifdef UNIX_MK
-FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_HW_CONFIG_DTS	:=	fdts/${FVP_DT_PREFIX}.dts
 
 FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
 $(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
 
-ifeq (${TRANSFER_LIST}, 1)
-FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
-					${PLAT}_tb_fw_config.dts	\
-				)
-else
+ifeq (${TRANSFER_LIST}, 0)
 FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
 					${PLAT}_fw_config.dts		\
 					${PLAT}_tb_fw_config.dts	\
@@ -353,6 +357,7 @@
 					${PLAT}_nt_fw_config.dts	\
 				)
 
+FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 FVP_SOC_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
 FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
@@ -384,13 +389,12 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
-endif
-
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
+endif
+
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
-endif
 
 ifeq (${TRANSFER_LIST}, 1)
 include lib/transfer_list/transfer_list.mk
@@ -404,6 +408,10 @@
 endif
 endif
 
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 327a345..a62661d 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -36,28 +36,5 @@
 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
-mbedtls mbedtls_asn1_get_bool
-mbedtls mbedtls_asn1_get_int
-mbedtls mbedtls_asn1_get_len
-mbedtls mbedtls_asn1_get_tag
-mbedtls mbedtls_free
-mbedtls mbedtls_md
-mbedtls mbedtls_md_get_size
-mbedtls mbedtls_memory_buffer_alloc_init
-mbedtls mbedtls_oid_get_md_alg
-mbedtls mbedtls_oid_get_numeric_string
-mbedtls mbedtls_oid_get_pk_alg
-mbedtls mbedtls_oid_get_sig_alg
-mbedtls mbedtls_pk_free
-mbedtls mbedtls_pk_init
-mbedtls mbedtls_pk_parse_subpubkey
-mbedtls mbedtls_pk_verify_ext
-mbedtls mbedtls_platform_set_snprintf
-mbedtls mbedtls_x509_get_rsassa_pss_params
-mbedtls mbedtls_x509_get_sig_alg
-mbedtls mbedtls_md_info_from_type
 c       exit
 c       atexit
diff --git a/plat/arm/board/juno/jmptbl_mbedtls.i b/plat/arm/board/juno/jmptbl_mbedtls.i
new file mode 100644
index 0000000..6e1f017
--- /dev/null
+++ b/plat/arm/board/juno/jmptbl_mbedtls.i
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform-specific ROMLIB MbedTLS functions can be added here.
+# During the build process, this file is appended to jmptbl.i
+# if MbedTLS support is required.
+#
+# Format:
+# lib   function        [patch]
+# Example:
+# mbedtls mbedtls_asn1_get_alg
+# mbedtls mbedtls_asn1_get_alg_null patch
+
+mbedtls mbedtls_asn1_get_alg
+mbedtls mbedtls_asn1_get_alg_null
+mbedtls mbedtls_asn1_get_bitstring_null
+mbedtls mbedtls_asn1_get_bool
+mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
+mbedtls mbedtls_asn1_get_tag
+mbedtls mbedtls_free
+mbedtls mbedtls_md
+mbedtls mbedtls_md_get_size
+mbedtls mbedtls_memory_buffer_alloc_init
+mbedtls mbedtls_oid_get_md_alg
+mbedtls mbedtls_oid_get_numeric_string
+mbedtls mbedtls_oid_get_pk_alg
+mbedtls mbedtls_oid_get_sig_alg
+mbedtls mbedtls_pk_free
+mbedtls mbedtls_pk_init
+mbedtls mbedtls_pk_parse_subpubkey
+mbedtls mbedtls_pk_verify_ext
+mbedtls mbedtls_platform_set_snprintf
+mbedtls mbedtls_x509_get_rsassa_pss_params
+mbedtls mbedtls_x509_get_sig_alg
+mbedtls mbedtls_md_info_from_type
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
index c730406..2ead454 100644
--- a/plat/arm/board/juno/juno_trusted_boot.c
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,9 +14,9 @@
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
 
-static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+static unsigned char rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN + ARM_ROTPK_HASH_LEN];
 
-extern unsigned char arm_rotpk_header[];
+extern unsigned char arm_rotpk_hash_der_header[];
 
 /*
  * Return the ROTPK hash stored in the registers of Juno board.
@@ -33,8 +33,8 @@
 	assert(flags != NULL);
 
 	/* Copy the DER header */
-	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
-	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+	memcpy(rotpk_hash_der, arm_rotpk_hash_der_header, ARM_ROTPK_HASH_DER_HEADER_LEN);
+	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN];
 
 
 	/*
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 8eca0c5..9530498 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -130,10 +130,10 @@
 endif
 
 ifeq ($(USE_ROMLIB),1)
-all : bl1_romlib.bin
+all: $(BUILD_PLAT)/bl1_romlib.bin
 endif
 
-bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
+$(BUILD_PLAT)/bl1_romlib.bin: $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/romlib/romlib.bin
 	$(s)echo "Building combined BL1 and ROMLIB binary for Juno $@"
 	./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
 
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
index bce8834..39a86b1 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -152,6 +152,9 @@
 	nrd_plat_info.config_id = plat_arm_nrd_get_config_id();
 	nrd_plat_info.multi_chip_mode = plat_arm_nrd_get_multi_chip_mode();
 
+	/* Initialize generic timer */
+	generic_delay_timer_init();
+
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 }
 
@@ -216,7 +219,6 @@
 
 void nrd_bl31_common_platform_setup(void)
 {
-	generic_delay_timer_init();
 
 	arm_bl31_platform_setup();
 
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 613f508..ff79402 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -207,7 +207,21 @@
 #if defined(TARGET_FLAVOUR_FPGA)
 #undef V2M_FLASH0_BASE
 #undef V2M_FLASH0_SIZE
+#if TC_FPGA_FIP_IMG_IN_RAM
+/*
+ * Note that this is just used for the FIP, which is not required
+ * anymore once Linux has commenced booting. So we are safe allowing
+ * Linux to also make use of this memory and it doesn't need to be
+ * carved out of the devicetree.
+ *
+ * This only needs to match the RAM load address that we give the FIP
+ * on either the FPGA or FVP command line so there is no need to link
+ * it to say halfway through the RAM or anything like that.
+ */
+#define V2M_FLASH0_BASE			UL(0xB0000000)
+#else
 #define V2M_FLASH0_BASE			UL(0x0C000000)
+#endif
 #define V2M_FLASH0_SIZE			UL(0x02000000)
 #endif
 
@@ -222,8 +236,11 @@
 #define TC_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
 						V2M_FLASH0_SIZE,	\
 						MT_DEVICE | MT_RO | MT_SECURE)
-
+#if TARGET_PLATFORM == 2
+#define PLAT_ARM_NSTIMER_FRAME_ID	U(0)
+#else
 #define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
+#endif
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x0
 
@@ -239,10 +256,28 @@
 
 #if TARGET_PLATFORM <= 2
 #define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE             ULL(0x180000000)
 #elif TARGET_PLATFORM >= 3
-#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000)
-#endif /* TARGET_PLATFORM >= 3 */
-#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
+
+#if TC_FPGA_ANDROID_IMG_IN_RAM
+/* 10GB reserved for system+userdata+vendor images */
+#define SYSTEM_IMAGE_SIZE		0xC0000000	/* 3GB */
+#define USERDATA_IMAGE_SIZE		0x140000000	/* 5GB */
+#define VENDOR_IMAGE_SIZE		0x20000000 	/* 512MB */
+#define RESERVE_IMAGE_SIZE		0x60000000      /* 1.5GB */
+#define ANDROID_FS_SIZE			(SYSTEM_IMAGE_SIZE + \
+					 USERDATA_IMAGE_SIZE + \
+					 VENDOR_IMAGE_SIZE + RESERVE_IMAGE_SIZE)
+
+#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000) + ANDROID_FS_SIZE
+#define PLAT_ARM_DRAM2_SIZE		ULL(0x380000000) - ANDROID_FS_SIZE
+#else
+#define PLAT_ARM_DRAM2_BASE             ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE             ULL(0x380000000)
+#endif /* TC_FPGA_ANDROID_IMG_IN_RAM */
+
+#endif /* TARGET_VERSION >= 3 */
+
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
 #define TC_NS_MTE_SIZE			(256 * SZ_1M)
@@ -338,13 +373,13 @@
  * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
  * SCP_BL2 size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x20000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x30000
 
 /*
  * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
  * SCP_BL2U size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x20000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x30000
 
 #if TARGET_PLATFORM <= 2
 /* TZC Related Constants */
@@ -408,18 +443,19 @@
 #undef PLAT_ARM_BOOT_UART_CLK_IN_HZ
 #undef PLAT_ARM_RUN_UART_CLK_IN_HZ
 
-#if TARGET_FLAVOUR_FVP
-#define PLAT_ARM_BOOT_UART_BASE		TC_UART1
-#define TC_UARTCLK			7372800
-#else /* TARGET_FLAVOUR_FPGA */
-#define PLAT_ARM_BOOT_UART_BASE		TC_UART0
+#undef  ARM_CONSOLE_BAUDRATE
+#define ARM_CONSOLE_BAUDRATE		38400
+
 #if TARGET_PLATFORM <= 2
 #define TC_UARTCLK			5000000
 #elif TARGET_PLATFORM >= 3
 #define TC_UARTCLK			3750000
 #endif /* TARGET_PLATFORM >= 3 */
-#undef  ARM_CONSOLE_BAUDRATE
-#define ARM_CONSOLE_BAUDRATE		38400
+
+#if TARGET_FLAVOUR_FVP
+#define PLAT_ARM_BOOT_UART_BASE		TC_UART1
+#else /* TARGET_FLAVOUR_FPGA */
+#define PLAT_ARM_BOOT_UART_BASE		TC_UART0
 #endif /* TARGET_FLAVOUR_FPGA */
 
 #define PLAT_ARM_RUN_UART_BASE		TC_UART0
@@ -428,28 +464,41 @@
 #define PLAT_ARM_BOOT_UART_CLK_IN_HZ	TC_UARTCLK
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ	TC_UARTCLK
 
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
 #define NCI_BASE_ADDR			UL(0x4F000000)
-#ifdef TARGET_FLAVOUR_FPGA
+#if (TARGET_PLATFORM == 3) && defined(TARGET_FLAVOUR_FPGA)
 #define MCN_ADDRESS_SPACE_SIZE		0x00120000
 #else
 #define MCN_ADDRESS_SPACE_SIZE		0x00130000
-#endif	/* TARGET_FLAVOUR_FPGA */
+#endif	/* (TARGET_PLATFORM == 3) && defined(TARGET_FLAVOUR_FPGA) */
+#if TARGET_PLATFORM == 3
 #define MCN_OFFSET_IN_NCI		0x00C90000
-#define MCN_BASE_ADDR			(NCI_BASE_ADDR + MCN_OFFSET_IN_NCI)
+#else	/* TARGET_PLATFORM == 4 */
+#ifdef TARGET_FLAVOUR_FPGA
+#define MCN_OFFSET_IN_NCI		0x00420000
+#else
+#define MCN_OFFSET_IN_NCI		0x00D80000
+#endif	/* TARGET_FLAVOUR_FPGA */
+#endif	/* TARGET_PLATFORM == 3 */
+#define MCN_BASE_ADDR(n)		(NCI_BASE_ADDR + MCN_OFFSET_IN_NCI + \
+								((n) * MCN_ADDRESS_SPACE_SIZE))
 #define MCN_PMU_OFFSET			0x000C4000
 #define MCN_MICROARCH_OFFSET		0x000E4000
-#define MCN_MICROARCH_BASE_ADDR		(MCN_BASE_ADDR + MCN_MICROARCH_OFFSET)
+#define MCN_MICROARCH_BASE_ADDR(n)		(MCN_BASE_ADDR(n) + \
+										MCN_MICROARCH_OFFSET)
 #define MCN_SCR_OFFSET			0x4
 #define MCN_SCR_PMU_BIT			10
+#if TARGET_PLATFORM == 3
 #define MCN_INSTANCES			4
-#define MCN_PMU_ADDR(n)			(MCN_BASE_ADDR + \
-					 (n * MCN_ADDRESS_SPACE_SIZE) + \
-					 MCN_PMU_OFFSET)
+#else	/* TARGET_PLATFORM == 4 */
+#define MCN_INSTANCES			8
+#endif	/* TARGET_PLATFORM == 3 */
+#define MCN_PMU_ADDR(n)			(MCN_BASE_ADDR(n) + \
+								MCN_PMU_OFFSET)
 #define MCN_MPAM_NS_OFFSET		0x000D0000
-#define MCN_MPAM_NS_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_NS_OFFSET)
+#define MCN_MPAM_NS_BASE_ADDR(n)		(MCN_BASE_ADDR(n) + MCN_MPAM_NS_OFFSET)
 #define MCN_MPAM_S_OFFSET		0x000D4000
-#define MCN_MPAM_S_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_S_OFFSET)
+#define MCN_MPAM_S_BASE_ADDR(n)		(MCN_BASE_ADDR(n) + MCN_MPAM_S_OFFSET)
 #define MPAM_SLCCFG_CTL_OFFSET		0x00003018
 #define SLC_RDALLOCMODE_SHIFT		8
 #define SLC_RDALLOCMODE_MASK		(3 << SLC_RDALLOCMODE_SHIFT)
@@ -461,7 +510,7 @@
 #define SLC_ALLOC_BUS_SIGNAL_ATTR	2
 
 #define MCN_CONFIG_OFFSET		0x204
-#define MCN_CONFIG_ADDR			(MCN_BASE_ADDR + MCN_CONFIG_OFFSET)
+#define MCN_CONFIG_ADDR(n)			(MCN_BASE_ADDR(n) + MCN_CONFIG_OFFSET)
 #define MCN_CONFIG_SLC_PRESENT_BIT	3
 
 /*
@@ -472,7 +521,7 @@
  */
 #define CPUECTLR_EL1			CORTEX_A520_CPUECTLR_EL1
 #define CPUECTLR_EL1_EXTLLC_BIT		CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT
-#endif /* TARGET_PLATFORM == 3 */
+#endif /* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
 
 #define CPUACTLR_CLUSTERPMUEN		(ULL(1) << 12)
 
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
index 9adf09a..1fde9e9 100644
--- a/plat/arm/board/tc/include/tc_helpers.S
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -54,7 +54,7 @@
 
 func mark_extllc_presence
 #ifdef MCN_CONFIG_ADDR
-	mov_imm x0, (MCN_CONFIG_ADDR)
+	mov_imm	x0, (MCN_CONFIG_ADDR(0))
 	ldr	w1, [x0]
 	ubfx	x1, x1, #MCN_CONFIG_SLC_PRESENT_BIT, #1
 	sysreg_bitfield_insert_from_gpr CPUECTLR_EL1, x1, \
@@ -82,6 +82,9 @@
 endfunc TC_HANDLER(3)
 
 func TC_HANDLER(4)
+	mov	x9, lr
+	bl	enable_dsu_pmu_el1_access
+	mov	lr, x9
 	ret
 endfunc TC_HANDLER(4)
 
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index 4fd8b6b..9118b0b 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -8,7 +8,7 @@
 #define PLAT_TC_MBEDTLS_CONFIG_H
 
 #include <export/lib/utils_def_exp.h>
-#include <mbedtls_config-3.h>
+#include <default_mbedtls_config.h>
 
 #ifndef TF_MBEDTLS_HEAP_SIZE
 #error TF_MBEDTLS_HEAP_SIZE is not defined
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 3ef25de..759c85d 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -61,6 +61,10 @@
 endif
 
 ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
+        $(error Platform ${PLAT}$(TARGET_PLATFORM) is no longer available.)
+endif
+
+ifneq ($(shell expr $(TARGET_PLATFORM) = 2), 0)
         $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
           Some of the features might not work as expected)
 endif
@@ -73,12 +77,24 @@
         $(error TARGET_FLAVOUR must be fvp or fpga)
 endif
 
+# Support for loading Android Image to DRAM
+TC_FPGA_ANDROID_IMG_IN_RAM := 0
+
+# Support Loading of FIP image to DRAM
+TC_FPGA_FIP_IMG_IN_RAM := 0
+
+# Use simple panel instead of vencoder with DPU
+TC_DPU_USE_SIMPLE_PANEL := 0
+
 $(eval $(call add_defines, \
 	TARGET_PLATFORM \
 	TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
 	TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
 	TC_DPU_USE_SCMI_CLK \
 	TC_SCMI_PD_CTRL_EN \
+	TC_FPGA_ANDROID_IMG_IN_RAM \
+	TC_FPGA_FIP_IMG_IN_RAM \
+	TC_DPU_USE_SIMPLE_PANEL \
 ))
 
 CSS_LOAD_SCP_IMAGES	:=	1
@@ -214,18 +230,17 @@
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TC_HW_CONFIG},--hw-config,${TC_HW_CONFIG}))
 
+$(info Including rse_comms.mk)
+include drivers/arm/rse/rse_comms.mk
+
+BL1_SOURCES	+=	${RSE_COMMS_SOURCES}
+BL2_SOURCES	+=	${RSE_COMMS_SOURCES}
+BL31_SOURCES	+=	${RSE_COMMS_SOURCES}
+
 # 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.
-$(info Including rse_comms.mk)
 ifeq (${MEASURED_BOOT},1)
-        $(info Including rse_comms.mk)
-        include drivers/arm/rse/rse_comms.mk
-
-	BL1_SOURCES	+=	${RSE_COMMS_SOURCES}
-	BL2_SOURCES	+=	${RSE_COMMS_SOURCES}
-	PLAT_INCLUDES	+=	-Iinclude/lib/psa
-
     ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
         $(info Including qcbor.mk)
         include drivers/measured_boot/rse/qcbor.mk
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 801872a..bc8f5ec 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -25,6 +25,10 @@
 #include <psa/crypto_types.h>
 #include <psa/crypto_values.h>
 #endif /* PLATFORM_TEST_TFM_TESTSUITE */
+#include <psa/error.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <plat/common/platform.h>
 
 #ifdef PLATFORM_TEST_TFM_TESTSUITE
 /*
@@ -68,19 +72,21 @@
 };
 #endif
 
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
 static void enable_ns_mcn_pmu(void)
 {
 	/*
 	 * Enable non-secure access to MCN PMU registers
 	 */
 	for (int i = 0; i < MCN_INSTANCES; i++) {
-		uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR + MCN_SCR_OFFSET +
-			(i * MCN_ADDRESS_SPACE_SIZE);
+		uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR(i) +
+			MCN_SCR_OFFSET;
 		mmio_setbits_32(mcn_scr, 1 << MCN_SCR_PMU_BIT);
 	}
 }
+#endif	/* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
 
+#if TARGET_PLATFORM == 3
 static void set_mcn_slc_alloc_mode(void)
 {
 	/*
@@ -89,10 +95,10 @@
 	 * attribute from interface).
 	 */
 	for (int i = 0; i < MCN_INSTANCES; i++) {
-		uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR +
-			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
-		uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR +
-			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+		uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR(i) +
+			MPAM_SLCCFG_CTL_OFFSET;
+		uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR(i) +
+			MPAM_SLCCFG_CTL_OFFSET;
 
 		mmio_clrsetbits_32(slccfg_ctl_ns,
 				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
@@ -109,8 +115,10 @@
 void bl31_platform_setup(void)
 {
 	tc_bl31_common_platform_setup();
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
 	enable_ns_mcn_pmu();
+#endif	/* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
+#if TARGET_PLATFORM == 3
 	set_mcn_slc_alloc_mode();
 	plat_arm_ni_setup(NCI_BASE_ADDR);
 #endif
@@ -186,10 +194,18 @@
 #if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
 void tc_bl31_plat_runtime_setup(void)
 {
+	psa_status_t status;
+
 	/* Start secure watchdog timer. */
 	plat_arm_secure_wdt_start();
 
 	arm_bl31_plat_runtime_setup();
+
+	/* Initialise RSE communication channel */
+	status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
+	if (status != PSA_SUCCESS) {
+		ERROR("Failed to initialize RSE communication channel - psa_status = %d\n", status);
+	}
 }
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index fed14f7..1ecfdb9 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -40,6 +40,7 @@
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
 	TC_FLASH0_RO,
+	ARM_V2M_MAP_MEM_PROTECT,
 	TC_MAP_DEVICE,
 	TC_MAP_NS_DRAM1,
 #if defined(SPD_spmd)
@@ -65,6 +66,7 @@
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
 	V2M_MAP_IOFPGA,
+	ARM_V2M_MAP_MEM_PROTECT,
 	TC_MAP_DEVICE,
 	PLAT_DTB_DRAM_NS,
 #if SPM_MM
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index f043f59..b8e5027 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -64,9 +64,7 @@
 /* Boolean variable to hold condition whether firmware update needed or not */
 static bool is_fwu_needed;
 
-#if TRANSFER_LIST
-static struct transfer_list_header *secure_tl;
-#endif
+struct transfer_list_header *secure_tl;
 
 struct meminfo *bl1_plat_sec_mem_layout(void)
 {
@@ -90,6 +88,12 @@
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
 	bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
+
+#if TRANSFER_LIST
+	secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+					 PLAT_ARM_FW_HANDOFF_SIZE);
+	assert(secure_tl != NULL);
+#endif
 }
 
 void bl1_early_platform_setup(void)
@@ -158,7 +162,7 @@
 
 	image_desc_t *desc;
 
-	int err = -1;
+	int err __unused = 1;
 
 	/* Initialise the IO layer and register platform IO devices */
 	plat_arm_io_setup();
@@ -171,35 +175,24 @@
 	}
 
 #if TRANSFER_LIST
-	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
-				       PLAT_ARM_FW_HANDOFF_SIZE);
-
-	if (secure_tl == NULL) {
-		ERROR("Secure transfer list initialisation failed!\n");
-		panic();
-	}
-
-	te = transfer_list_add(secure_tl, TL_TAG_TB_FW_CONFIG,
-			       ARM_TB_FW_CONFIG_MAX_SIZE, NULL);
+#if CRYPTO_SUPPORT
+	te = transfer_list_add(secure_tl, TL_TAG_MBEDTLS_HEAP_INFO,
+			       sizeof(struct crypto_heap_info), NULL);
 	assert(te != NULL);
 
+	struct crypto_heap_info *heap_info =
+		(struct crypto_heap_info *)transfer_list_entry_data(te);
+	arm_get_mbedtls_heap(&heap_info->addr, &heap_info->size);
+#endif /* CRYPTO_SUPPORT */
+
+	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+
 	/*
-	 * Set the load address of TB_FW_CONFIG in the data section of the TE just
-	 * allocated in the secure transfer list.
+	 * The event log might have been updated prior to this, make sure we have an
+	 * up to date tl before setting the handoff arguments.
 	 */
-	SET_PARAM_HEAD(&config_image_info, PARAM_IMAGE_BINARY, VERSION_2, 0);
-	config_image_info.image_base = (uintptr_t)transfer_list_entry_data(te);
-	config_image_info.image_max_size = te->data_size;
-
-	VERBOSE("FCONF: Loading config with image ID: %u\n", TB_FW_CONFIG_ID);
-	err = load_auth_image(TB_FW_CONFIG_ID, &config_image_info);
-	if (err != 0) {
-		VERBOSE("Failed to load config %u\n", TB_FW_CONFIG_ID);
-		plat_error_handler(err);
-	}
-
 	transfer_list_update_checksum(secure_tl);
-	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+	transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
 #else
 	/* Set global DTB info for fixed fw_config information */
 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
@@ -234,22 +227,18 @@
 		ERROR("Invalid FW_CONFIG address\n");
 		plat_error_handler(err);
 	}
-#endif /* TRANSFER_LIST */
 
 	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
 
-#if TRANSFER_LIST
-	transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
-#else
 	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
 	assert(desc != NULL);
 	desc->ep_info.args.arg0 = config_info->config_addr;
-#endif /* TRANSFER_LIST */
 
 #if CRYPTO_SUPPORT
 	/* Share the Mbed TLS heap info with other images */
 	arm_bl1_set_mbedtls_heap();
 #endif /* CRYPTO_SUPPORT */
+#endif /* TRANSFER_LIST */
 
 	/*
 	 * Allow access to the System counter timer module and program
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 90ee70c..17dc0ed 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -52,22 +52,14 @@
 #pragma weak bl2_plat_arch_setup
 #pragma weak bl2_plat_sec_mem_layout
 
-#if ENABLE_RME
 #define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
 					bl2_tzram_layout.total_base,	\
 					bl2_tzram_layout.total_size,	\
-					MT_MEMORY | MT_RW | MT_ROOT)
-#else
-#define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
-					bl2_tzram_layout.total_base,	\
-					bl2_tzram_layout.total_size,	\
-					MT_MEMORY | MT_RW | MT_SECURE)
-#endif /* ENABLE_RME */
+					MT_MEMORY | MT_RW | EL3_PAS)
 
 #pragma weak arm_bl2_plat_handle_post_image_load
 
-static struct transfer_list_header *secure_tl __unused;
-static struct transfer_list_header *ns_tl __unused;
+struct transfer_list_header *secure_tl __unused;
 
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
@@ -129,15 +121,14 @@
 #if TRANSFER_LIST
 /* Assume the secure TL hasn't been initialised if BL2 is running at EL3. */
 #if RESET_TO_BL2
-	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
-				       PLAT_ARM_FW_HANDOFF_SIZE);
+	secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+					 PLAT_ARM_FW_HANDOFF_SIZE);
 
 	if (secure_tl == NULL) {
 		ERROR("Secure transfer list initialisation failed!\n");
 		panic();
 	}
 #endif
-
 	arm_transfer_list_dyn_cfg_init(secure_tl);
 #else
 #if ARM_FW_CONFIG_LOAD_ENABLE
@@ -232,11 +223,10 @@
 	arm_bl2_plat_arch_setup();
 
 #if TRANSFER_LIST
-	te = transfer_list_find(secure_tl, TL_TAG_TB_FW_CONFIG);
-	assert(te != NULL);
-
-	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+#if CRYPTO_SUPPORT
+	te = arm_transfer_list_set_heap_info(secure_tl);
 	transfer_list_rem(secure_tl, te);
+#endif /* CRYPTO_SUPPORT */
 #else
 	/* Fill the properties struct with the info from the config dtb */
 	fconf_populate("FW_CONFIG", config_base);
@@ -246,7 +236,7 @@
 	assert(tb_fw_config_info != NULL);
 
 	fconf_populate("TB_FW", tb_fw_config_info->config_addr);
-#endif
+#endif /* TRANSFER_LIST */
 }
 
 int arm_bl2_handle_post_image_load(unsigned int image_id)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 3650854..4787995 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -25,8 +25,8 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-static struct transfer_list_header *secure_tl __unused;
-static struct transfer_list_header *ns_tl __unused;
+struct transfer_list_header *secure_tl;
+struct transfer_list_header *ns_tl __unused;
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
@@ -367,24 +367,31 @@
 	struct transfer_list_entry *te __unused;
 
 #if TRANSFER_LIST && !RESET_TO_BL31
-	/* Initialise the non-secure world tl, BL31 may modify the HW_CONFIG so defer
-	 * copying it until later.
-	 */
-	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
-				   PLAT_ARM_FW_HANDOFF_SIZE);
-
+	ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
 	if (ns_tl == NULL) {
-		ERROR("Non-secure transfer list initialisation failed!");
+		ERROR("Non-secure transfer list initialisation failed!\n");
 		panic();
 	}
-
-#if !RESET_TO_BL2
+	/* BL31 may modify the HW_CONFIG so defer copying it until later. */
 	te = transfer_list_find(secure_tl, TL_TAG_FDT);
 	assert(te != NULL);
 
+	/*
+	 * A pre-existing assumption is that FCONF is unsupported w/ RESET_TO_BL2 and
+	 * RESET_TO_BL31. In the case of RESET_TO_BL31 this makes sense because there
+	 * isn't a prior stage to load the device tree, but the reasoning for RESET_TO_BL2 is
+	 * less clear. For the moment hardware properties that would normally be
+	 * derived from the DT are statically defined.
+	 */
+#if !RESET_TO_BL2
 	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
-#endif /* !(RESET_TO_BL2 && RESET_TO_BL31) */
-#endif /* TRANSFER_LIST */
+#endif
+
+	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
+			       transfer_list_entry_data(te));
+	assert(te != NULL);
+#endif /* TRANSFER_LIST && !RESET_TO_BL31 */
 
 	/* Initialize the GIC driver, cpu and distributor interfaces */
 	plat_arm_gic_driver_init();
@@ -433,20 +440,13 @@
 	arm_console_runtime_init();
 
 #if TRANSFER_LIST && !RESET_TO_BL31
-	te = transfer_list_find(secure_tl, TL_TAG_FDT);
-	assert(te != NULL);
-
-	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
-			       transfer_list_entry_data(te));
-	assert(te != NULL);
-
 	/*
 	 * We assume BL31 has added all TE's required by BL33 at this stage, ensure
 	 * that data is visible to all observers by performing a flush operation, so
 	 * they can access the updated data even if caching is not enabled.
 	 */
 	flush_dcache_range((uintptr_t)ns_tl, ns_tl->size);
-#endif /* TRANSFER_LIST && !(RESET_TO_BL2 || RESET_TO_BL31) */
+#endif /* TRANSFER_LIST && !RESET_TO_BL31 */
 
 #if RECLAIM_INIT_CODE
 	arm_free_init_memory();
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 21cc39c..2d4165c 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -12,6 +12,8 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/romlib.h>
+#include <common/par.h>
+#include <lib/extensions/sysreg128.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
@@ -196,7 +198,8 @@
  */
 int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
 {
-	uint64_t par, pa;
+	uint64_t pa;
+	sysreg_t par;
 	u_register_t scr_el3;
 
 	/* Doing Non-secure address translation requires SCR_EL3.NS set */
@@ -230,7 +233,7 @@
 		return -1;
 
 	/* Extract Physical Address from PAR */
-	pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+	pa = get_par_el1_pa(par);
 
 	/* Perform NS entry point validation on the physical address */
 	return arm_validate_ns_entrypoint(pa);
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 2fd993c..580ef5f 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -363,7 +363,7 @@
 endif
 
 # Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif
 
@@ -382,12 +382,14 @@
 ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),)
     PLAT_INCLUDES		+=	-Iplat/arm/common	\
 					-Iinclude/drivers/auth/mbedtls
-    # Specify mbed TLS configuration file
-    ifeq (${PSA_CRYPTO},1)
-      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_psa_mbedtls_config.h>"
+    ifeq (${HASH_ALG}, sha512)
+      ARM_ROTPK_HASH_LEN	:=	64
+    else ifeq (${HASH_ALG}, sha384)
+      ARM_ROTPK_HASH_LEN	:=	48
     else
-      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_mbedtls_config.h>"
+      ARM_ROTPK_HASH_LEN	:=	32
     endif
+    $(eval $(call add_define,ARM_ROTPK_HASH_LEN))
 endif
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 18ab5be..a827f05 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -23,7 +23,7 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
-#if CRYPTO_SUPPORT
+#if CRYPTO_SUPPORT && !TRANSFER_LIST
 
 static void *mbedtls_heap_addr;
 static size_t mbedtls_heap_size;
@@ -118,7 +118,7 @@
 #endif /* !MEASURED_BOOT */
 	}
 }
-#endif /* CRYPTO_SUPPORT */
+#endif /* CRYPTO_SUPPORT && !TRANSFER_LIST */
 
 #if IMAGE_BL2
 /*
diff --git a/plat/arm/common/arm_ni.c b/plat/arm/common/arm_ni.c
index b3ad8b3..9c105f7 100644
--- a/plat/arm/common/arm_ni.c
+++ b/plat/arm/common/arm_ni.c
@@ -144,19 +144,33 @@
 
 	for (uint32_t i = 0U; i < vd_count; i++) {
 		vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i));
+
+		VERBOSE("Voltage domain %u at 0x%lx node info: 0x%x\n",
+			i, vd_addr, mmio_read_32(vd_addr));
+
 		pd_count = mmio_read_32(vd_addr + NI_CHILD_NODE_COUNT);
 
 		for (uint32_t j = 0U; j < pd_count; j++) {
 			pd_addr = global_cfg + mmio_read_32(vd_addr + NI_CHILD_POINTER(j));
 			cd_count = mmio_read_32(pd_addr + NI_CHILD_NODE_COUNT);
 
+			VERBOSE("Power domain %u at 0x%lx node info: 0x%x\n",
+				j, pd_addr, mmio_read_32(pd_addr));
+
 			for (uint32_t k = 0U; k < cd_count; k++) {
 				cd_addr = global_cfg + mmio_read_32(pd_addr + NI_CHILD_POINTER(k));
 				comp_count = mmio_read_32(cd_addr + NI_CHILD_NODE_COUNT);
 
+				VERBOSE("Clock domain %u at 0x%lx node info: 0x%x\n",
+					k, cd_addr, mmio_read_32(cd_addr));
+
 				for (uint32_t l = 0U; l < comp_count; l++) {
 					comp_addr = global_cfg +
 						mmio_read_32(cd_addr + NI_CHILD_POINTER(l));
+
+					VERBOSE("Component %u at 0x%lx node info: 0x%x\n",
+						l, comp_addr, mmio_read_32(comp_addr));
+
 					ni_setup_component(comp_addr);
 				}
 			}
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
index 59fb039..6847591 100644
--- a/plat/arm/common/arm_transfer_list.c
+++ b/plat/arm/common/arm_transfer_list.c
@@ -4,10 +4,49 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#if CRYPTO_SUPPORT
+#include <mbedtls/version.h>
+#endif /* CRYPTO_SUPPORT */
+
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
-void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl)
+#if CRYPTO_SUPPORT
+#if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31)
+static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
+
+#define MBEDTLS_HEAP_ADDR heap
+#define MBEDTLS_HEAP_SIZE sizeof(heap)
+#else
+static struct crypto_heap_info heap_info;
+
+#define MBEDTLS_HEAP_ADDR heap_info.addr
+#define MBEDTLS_HEAP_SIZE heap_info.size
+
+struct transfer_list_entry *
+arm_transfer_list_set_heap_info(struct transfer_list_header *tl)
+{
+	struct transfer_list_entry *te =
+		transfer_list_find(tl, TL_TAG_MBEDTLS_HEAP_INFO);
+	assert(te != NULL);
+
+	heap_info = *(struct crypto_heap_info *)transfer_list_entry_data(te);
+	return te;
+}
+#endif /* defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) */
+
+int __init arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+	*heap_addr = MBEDTLS_HEAP_ADDR;
+	*heap_size = MBEDTLS_HEAP_SIZE;
+
+	return 0;
+}
+#endif /* CRYPTO_SUPPORT */
+
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *tl)
 {
 	struct transfer_list_entry *te;
 	bl_mem_params_node_t *next_param_node =
@@ -19,8 +58,7 @@
 	 * mechanism. Pre-allocate a TE for the configuration and update the
 	 * load information so the configuration is loaded directly into the TE.
 	 */
-	te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE,
-			       NULL);
+	te = transfer_list_add(tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, NULL);
 	assert(te != NULL);
 
 	next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
@@ -30,7 +68,7 @@
 }
 
 void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
-					struct transfer_list_header *secure_tl)
+					struct transfer_list_header *tl)
 {
 	uint32_t next_exe_img_id;
 	entry_point_info_t *ep;
@@ -45,7 +83,7 @@
 				next_exe_img_id)];
 		assert(next_param_node != NULL);
 
-		te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64,
+		te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO64,
 				       sizeof(entry_point_info_t),
 				       &next_param_node->ep_info);
 		assert(te != NULL);
@@ -72,5 +110,5 @@
 		next_exe_img_id = next_param_node->next_handoff_image_id;
 	}
 
-	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+	flush_dcache_range((uintptr_t)tl, tl->size);
 }
diff --git a/plat/arm/common/plat_arm_mbedtls_config.h b/plat/arm/common/plat_arm_mbedtls_config.h
deleted file mode 100644
index a5d0ec4..0000000
--- a/plat/arm/common/plat_arm_mbedtls_config.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Ltd. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_ARM_MBEDTLS_CONFIG_H
-#define PLAT_ARM_MBEDTLS_CONFIG_H
-
-#include <mbedtls_config-3.h>
-
-/**
- * On Arm platforms, the ROTPK is always hashed using the SHA-256
- * algorithm.
- * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
- * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
- */
-#define MBEDTLS_SHA256_C
-
-/*
- * Use an implementation of SHA-256 with a smaller memory footprint
- * but reduced speed.
- */
-#define MBEDTLS_SHA256_SMALLER
-
-#endif /* PLAT_ARM_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/common/plat_arm_psa_mbedtls_config.h b/plat/arm/common/plat_arm_psa_mbedtls_config.h
deleted file mode 100644
index fd434c9..0000000
--- a/plat/arm/common/plat_arm_psa_mbedtls_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Ltd. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_ARM_PSA_MBEDTLS_CONFIG_H
-#define PLAT_ARM_PSA_MBEDTLS_CONFIG_H
-
-#include "plat_arm_mbedtls_config.h"
-
-#define MBEDTLS_PSA_CRYPTO_C
-#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
-
-/*
- * Using PSA crypto API requires an RNG right now. If we don't define the macro
- * below then we get build errors.
- *
- * This is a functionality gap in mbedTLS. The technical limitation is that
- * psa_crypto_init() is all-or-nothing, and fixing that would require separate
- * initialization of the keystore, the RNG, etc.
- *
- * By defining MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, we pretend using an external
- * RNG. As a result, the PSA crypto init code does nothing when it comes to
- * initializing the RNG, as we are supposed to take care of that ourselves.
- */
-#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
-
-#endif /* PLAT_ARM_PSA_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index db4a169..bfb6906 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -152,6 +152,8 @@
 {
 	assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
 	css_power_down_common(target_state);
+	/* ask the GIC not to wake us up */
+	plat_arm_gic_redistif_off();
 	css_scp_off(target_state);
 }
 
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index a603f2b..dbb6f81 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -9,6 +9,7 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <lib/transfer_list.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/common/platform.h>
 #include <services/arm_arch_svc.h>
@@ -129,3 +130,13 @@
 	/* Create the page tables to reflect the above mappings */
 	init_xlat_tables();
 }
+
+#if ((MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT) && TRANSFER_LIST)
+int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base)
+{
+	if (!transfer_list_add(tl_base, TL_TAG_TPM_EVLOG, data_size, data))
+		return -1;
+
+	return 0;
+}
+#endif
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 63eca37..b67d3ff 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -152,11 +152,11 @@
 $(BUILD_PLAT)/bl2/hikey_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index c2c3122..c278d8e 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -145,11 +145,11 @@
 $(BUILD_PLAT)/bl2/hikey960_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 2bda3a5..a7e8fe8 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -76,13 +76,13 @@
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/imx/imx8m/imx8m_ccm.c b/plat/imx/imx8m/imx8m_ccm.c
index 10a00c9..6b14446 100644
--- a/plat/imx/imx8m/imx8m_ccm.c
+++ b/plat/imx/imx8m/imx8m_ccm.c
@@ -17,16 +17,16 @@
 } imx8m_uart_info[] = {
 	{	/* UART 1 */
 		.ccm_reg = 0x4490,
-		.uart_base = 0x30860000,
+		.uart_base = IMX_UART1_BASE,
 	}, {	/* UART 2 */
 		.ccm_reg = 0x44a0,
-		.uart_base = 0x30890000,
+		.uart_base = IMX_UART2_BASE,
 	}, {	/* UART 3 */
 		.ccm_reg = 0x44b0,
-		.uart_base = 0x30880000,
+		.uart_base = IMX_UART3_BASE,
 	}, {	/* UART 4 */
 		.ccm_reg = 0x44c0,
-		.uart_base = 0x30a60000,
+		.uart_base = IMX_UART4_BASE,
 	}
 };
 
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index f6e46eb..03edc6e 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -62,7 +62,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M4, DID1),
 
@@ -164,14 +164,14 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
-
-	imx_csu_init(csu_cfg);
-
 	if (console_base == 0U) {
 		console_base = imx8m_uart_get_base();
 	}
 
+	imx_rdc_init(rdc, console_base);
+
+	imx_csu_init(csu_cfg);
+
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 2fa6199..e6ad8fe 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -85,6 +85,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index d1c1259..e54256c 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -132,13 +132,13 @@
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index befa769..42d173e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -48,7 +48,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -136,7 +136,11 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -152,10 +156,6 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 569432d..b76bdbf 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -68,6 +68,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index ffad3d1..141c94b 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -49,7 +49,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -166,7 +166,11 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -175,10 +179,6 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 84a7e00..78f3d5b 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -86,6 +86,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 5df598c..98b99d1 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -129,13 +129,13 @@
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index b04f391..61c0e8e 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -65,6 +65,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	25000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPS_BASE			U(0x30200000)
 #define IMX_AIPS_SIZE			U(0xC00000)
 #define IMX_AIPS1_BASE			U(0x30200000)
diff --git a/plat/imx/imx8m/imx_rdc.c b/plat/imx/imx8m/imx_rdc.c
index 85de191..de15956 100644
--- a/plat/imx/imx8m/imx_rdc.c
+++ b/plat/imx/imx8m/imx_rdc.c
@@ -4,13 +4,78 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
+
 #include <lib/mmio.h>
 
 #include <imx_rdc.h>
 
-void imx_rdc_init(const struct imx_rdc_cfg *rdc_cfg)
+struct imx_uart {
+	int index;
+	unsigned int uart_base;
+};
+
+static const struct imx_uart imx8m_uart_info[] = {
+	{	/* UART 1 */
+		.index = RDC_PDAP_UART1,
+		.uart_base = IMX_UART1_BASE,
+	}, {	/* UART 2 */
+		.index = RDC_PDAP_UART2,
+		.uart_base = IMX_UART2_BASE,
+	}, {	/* UART 3 */
+		.index = RDC_PDAP_UART3,
+		.uart_base = IMX_UART3_BASE,
+	}, {	/* UART 4 */
+		.index = RDC_PDAP_UART4,
+		.uart_base = IMX_UART4_BASE,
+	}
+};
+
+static int imx_rdc_uart_get_pdap_index(unsigned int uart_base)
 {
-	const struct imx_rdc_cfg *rdc = rdc_cfg;
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
+		if (imx8m_uart_info[i].uart_base == uart_base) {
+			return imx8m_uart_info[i].index;
+		}
+	}
+
+	return -ENODEV;
+}
+
+static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg,
+				   unsigned int console_base)
+{
+	struct imx_rdc_cfg *rdc;
+	int console_pdap_index;
+
+	console_pdap_index = imx_rdc_uart_get_pdap_index(console_base);
+	if (console_pdap_index < 0) {
+		return;
+	}
+
+	for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) {
+		if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) {
+			continue;
+		}
+
+		if (rdc->index == console_pdap_index &&
+		    rdc->setting.rdc_pdap == (D0R | D0W)) {
+			return;
+		}
+
+		if (rdc->index == console_pdap_index) {
+			rdc->setting.rdc_pdap = D0R | D0W;
+		}
+	}
+}
+
+void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
+{
+	struct imx_rdc_cfg *rdc = rdc_cfg;
+
+	imx_rdc_console_access_enable(rdc, console_base);
 
 	while (rdc->type != RDC_INVALID) {
 		switch (rdc->type) {
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index a6e10a7..fbdcbf2 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -67,7 +67,7 @@
 	  .setting.rdc_mem_region[2] = (mrc),	\
 	}
 
-void imx_rdc_init(const struct imx_rdc_cfg *cfg);
+void imx_rdc_init(struct imx_rdc_cfg *cfg, unsigned int console_base);
 
 #endif /* IMX_RDC_H */
 
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 36820b2..084539e 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -129,11 +129,13 @@
 
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
+		NOTICE("SDMMC boot\n");
 		dw_mmc_init(&params, &mmc_info);
 		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
+		NOTICE("QSPI boot\n");
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 6e45158..4c10e7b 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,12 +14,16 @@
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
 
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_sip_svc.h"
 
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
@@ -59,9 +64,7 @@
 				u_register_t arg2, u_register_t arg3)
 {
 	static console_t console;
-
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
-
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
 		PLAT_BAUDRATE, &console);
 	/*
@@ -69,6 +72,33 @@
 	 */
 	void *from_bl2 = (void *) arg0;
 
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	void *plat_params_from_bl2 = (void *) arg3;
+
+	assert(plat_params_from_bl2 == NULL);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+	/*
+	 * According to the file ``Documentation/arm64/booting.txt`` of the
+	 * Linux kernel tree, Linux expects the physical address of the device
+	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+	 * must be 0.
+	 */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
 	assert(params_from_bl2 != NULL);
 
@@ -76,28 +106,38 @@
 	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
 	 * They are stored in Secure RAM, in BL31's address space.
 	 */
-
 	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
 		params_from_bl2->h.version >= VERSION_2) {
-
 		bl_params_node_t *bl_params = params_from_bl2->head;
-
 		while (bl_params) {
 			if (bl_params->image_id == BL33_IMAGE_ID)
 				bl33_image_ep_info = *bl_params->ep_info;
-
 			bl_params = bl_params->next_params_info;
 		}
 	} else {
 		struct socfpga_bl31_params *arg_from_bl2 =
 			(struct socfpga_bl31_params *) from_bl2;
-
 		assert(arg_from_bl2->h.type == PARAM_BL31);
 		assert(arg_from_bl2->h.version >= VERSION_1);
-
 		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
 		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 	}
+
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+# if ARM_LINUX_KERNEL_AS_BL33
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+#endif
+
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
 
@@ -172,8 +212,34 @@
 #endif
 		{0}
 	};
-
 	setup_page_tables(bl_regions, plat_agilex_mmap);
 	enable_mmu_el3(0);
 }
 
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 9db4292..f0bbeea 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +28,7 @@
 #define AGX_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define AGX_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index 20a62be..78aabde 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,7 +122,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9ef7598..840ffdd 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,10 +15,16 @@
 
 /* Platform Setting */
 #define PLATFORM_MODEL				PLAT_SOCFPGA_AGILEX
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex is No cache flush.
+ * For Agilex FP8, set to Flush cache.
+ */
+#define CACHE_FLUSH				0
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -27,6 +34,25 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE			(0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE			(0x10000000)
+#define PLAT_MMC_DATA_SIZE			(0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(32768)
+#else
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+#endif
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
@@ -97,7 +123,7 @@
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS			mmc_read_blocks
+#define SDMMC_READ_BLOCKS			sdmmc_read_blocks
 #define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 21cc6a3..d534b2e 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -28,6 +28,7 @@
 			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/drivers/sdmmc/sdmmc.c			\
 			plat/intel/soc/common/lib/sha/sha.c				\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
@@ -87,6 +88,24 @@
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 # Configs for VAB Authentication
 SOCFPGA_SECURE_VAB_AUTH  := 	0
 $(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index 265ee57..fe5dc6e 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -20,9 +20,11 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include "agilex5_clock_manager.h"
+#include "agilex5_ddr.h"
 #include "agilex5_memory_controller.h"
 #include "agilex5_mmc.h"
 #include "agilex5_pinmux.h"
+#include "agilex5_power_manager.h"
 #include "agilex5_system_manager.h"
 #include "ccu/ncore_ccu.h"
 #include "combophy/combophy.h"
@@ -66,33 +68,84 @@
 
 boot_source_type boot_source = BOOT_SOURCE;
 
-void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
-				u_register_t x2, u_register_t x4)
+void bl2_el3_early_platform_setup(u_register_t x0 __unused,
+				  u_register_t x1 __unused,
+				  u_register_t x2 __unused,
+				  u_register_t x3 __unused)
 {
 	static console_t console;
+	handoff reverse_handoff_ptr;
 
-	handoff reverse_handoff_ptr = { 0 };
-
-	generic_delay_timer_init();
-	config_clkmgr_handoff(&reverse_handoff_ptr);
-	mailbox_init();
+	/* Enable nonsecure access for peripherals and other misc components */
 	enable_nonsecure_access();
 
+	/* Bring all the required peripherals out of reset */
 	deassert_peripheral_reset();
-	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
-		ERROR("Combo Phy initialization failed\n");
+
+	/*
+	 * Initialize the UART console early in BL2 EL3 boot flow to get
+	 * the error/notice messages wherever required.
+	 */
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+			       PLAT_BAUDRATE, &console);
+
+	/* Generic delay timer init */
+	generic_delay_timer_init();
+
+	socfpga_delay_timer_init();
+
+	/* Get the handoff data */
+	if ((socfpga_get_handoff(&reverse_handoff_ptr)) != 0) {
+		ERROR("SOCFPGA: Failed to get the correct handoff data\n");
+		panic();
 	}
 
-	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
+	/* Configure the pinmux */
+	config_pinmux(&reverse_handoff_ptr);
 
-	/* Store magic number */
-	// TODO: Temp workaround to ungate testing
-	// mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+	/* Configure OCRAM to NON SECURE ACCESS */
+	mmio_write_32(OCRAM_REGION_0_REG_BASE, OCRAM_NON_SECURE_ENABLE);
+	mmio_write_32(SOCFPGA_L4_PER_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+		SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+	mmio_write_32(SOCFPGA_L4_SYS_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+		SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+	mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE,
+		SOCFPGA_LWSOC2FPGA_ENABLE);
 
+	/* Configure the clock manager */
+	if ((config_clkmgr_handoff(&reverse_handoff_ptr)) != 0) {
+		ERROR("SOCFPGA: Failed to initialize the clock manager\n");
+		panic();
+	}
+
+	/* Configure power manager PSS SRAM power gate */
+	config_pwrmgr_handoff(&reverse_handoff_ptr);
+
+	/* Initialize the mailbox to enable communication between HPS and SDM */
+	mailbox_init();
+
+	/* Perform a handshake with certain peripherals before issuing a reset */
+	config_hps_hs_before_warm_reset();
+
+	/* TODO: watchdog init */
+	//watchdog_init(clkmgr_get_rate(CLKMGR_WDT_CLK_ID));
+
+	/* Initialize the CCU module for hardware cache coherency */
+	init_ncore_ccu();
+
+	socfpga_emac_init();
+
+	/* DDR and IOSSM driver init */
+	agilex5_ddr_init(&reverse_handoff_ptr);
+
+	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
+		ERROR("SOCFPGA: Combo Phy initialization failed\n");
+	}
+
+	/* Enable FPGA bridges as required */
 	if (!intel_mailbox_is_fpga_not_ready()) {
 		socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
-					FPGA2SOC_MASK | F2SDRAM0_MASK);
+				       FPGA2SOC_MASK | F2SDRAM0_MASK);
 	}
 }
 
@@ -101,7 +154,8 @@
 	handoff reverse_handoff_ptr;
 	unsigned long offset = 0;
 
-	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc,
+							   clkmgr_get_rate(CLKMGR_SDMMC_CLK_ID));
 
 	mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
 	mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
@@ -112,7 +166,7 @@
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		NOTICE("SDMMC boot\n");
-		sdmmc_init(&reverse_handoff_ptr, &params, &mmc_info);
+		cdns_mmc_init(&params, &mmc_info);
 		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 96c4161..ab03928 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -58,9 +58,8 @@
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
 
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
+			       PLAT_BAUDRATE, &console);
 
-	init_ncore_ccu();
 	setup_smmu_stream_id();
 
 	/*
@@ -191,12 +190,15 @@
 	uint32_t boot_core = 0x00;
 	uint32_t cpuid = 0x00;
 
-	cpuid = read_mpidr();
-	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
+	boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
 	NOTICE("BL31: Boot Core = %x\n", boot_core);
 	NOTICE("BL31: CPU ID = %x\n", cpuid);
 	INFO("BL31: Invalidate Data cache\n");
 	invalidate_dcache_all();
+
+	/* Invalidate for NS EL2 and EL1 */
+	invalidate_cache_low_el();
 }
 
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
@@ -235,6 +237,9 @@
 	unsigned int pchctlr_new = 0x00;
 	uint32_t boot_core = 0x00;
 
+	/* Store magic number for SMP secondary cores boot */
+	mmio_write_32(L2_RESET_DONE_REG, SMP_SEC_CORE_BOOT_REQ);
+
 	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
 	/* Update the p-channel based on cpu id */
 	pch_cpu = 1 << cpu_id;
diff --git a/plat/intel/soc/agilex5/include/agilex5_cache.h b/plat/intel/soc/agilex5/include/agilex5_cache.h
index 095d99e..f7801b9 100644
--- a/plat/intel/soc/agilex5/include/agilex5_cache.h
+++ b/plat/intel/soc/agilex5/include/agilex5_cache.h
@@ -8,5 +8,6 @@
 #define AGX5_CACHE_H
 
 void invalidate_dcache_all(void);
+void invalidate_cache_low_el(void);
 
 #endif /* AGX5_CACHE_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
index 566a80d..1165c90 100644
--- a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,141 +11,304 @@
 #include "socfpga_handoff.h"
 
 /* Clock Manager Registers */
-#define CLKMGR_OFFSET					0x10d10000
+#define CLKMGR_BASE				0x10D10000
+#define CLKMGR_CTRL				0x00
+#define CLKMGR_STAT				0x04
+#define CLKMGR_TESTIOCTROL			0x08
+#define CLKMGR_INTRGEN				0x0C
+#define CLKMGR_INTRMSK				0x10
+#define CLKMGR_INTRCLR				0x14
+#define CLKMGR_INTRSTS				0x18
+#define CLKMGR_INTRSTK				0x1C
+#define CLKMGR_INTRRAW				0x20
 
-#define CLKMGR_CTRL					0x0
-#define CLKMGR_STAT					0x4
-#define CLKMGR_TESTIOCTROL				0x8
-#define CLKMGR_INTRGEN					0xc
-#define CLKMGR_INTRMSK					0x10
-#define CLKMGR_INTRCLR					0x14
-#define CLKMGR_INTRSTS					0x18
-#define CLKMGR_INTRSTK					0x1c
-#define CLKMGR_INTRRAW					0x20
+/* Clock manager control related macros */
+#define CLKMGR(_reg)				(CLKMGR_BASE + (CLKMGR_##_reg))
+#define CLKMGR_STAT_MAINPLLLOCKED		BIT(8)
+#define CLKMGR_STAT_PERPLLLOCKED		BIT(16)
+
+#define CLKMGR_INTRCLR_MAINLOCKLOST		BIT(2)
+#define CLKMGR_INTRCLR_PERLOCKLOST		BIT(3)
+
+#define CLKMGR_STAT_ALLPLLLOCKED		(CLKMGR_STAT_MAINPLLLOCKED | \
+						CLKMGR_STAT_PERPLLLOCKED)
 
 /* Main PLL Group */
-#define CLKMGR_MAINPLL					0x10d10024
-#define CLKMGR_MAINPLL_EN				0x0
-#define CLKMGR_MAINPLL_ENS				0x4
-#define CLKMGR_MAINPLL_BYPASS				0xc
-#define CLKMGR_MAINPLL_BYPASSS				0x10
-#define CLKMGR_MAINPLL_BYPASSR				0x14
-#define CLKMGR_MAINPLL_NOCCLK				0x1c
-#define CLKMGR_MAINPLL_NOCDIV				0x20
-#define CLKMGR_MAINPLL_PLLGLOB				0x24
-#define CLKMGR_MAINPLL_FDBCK				0x28
-#define CLKMGR_MAINPLL_MEM				0x2c
-#define CLKMGR_MAINPLL_MEMSTAT				0x30
-#define CLKMGR_MAINPLL_VCOCALIB				0x34
-#define CLKMGR_MAINPLL_PLLC0				0x38
-#define CLKMGR_MAINPLL_PLLC1				0x3c
-#define CLKMGR_MAINPLL_PLLC2				0x40
-#define CLKMGR_MAINPLL_PLLC3				0x44
-#define CLKMGR_MAINPLL_PLLM				0x48
-#define CLKMGR_MAINPLL_FHOP				0x4c
-#define CLKMGR_MAINPLL_SSC				0x50
-#define CLKMGR_MAINPLL_LOSTLOCK				0x54
+#define CLKMGR_MAINPLL_BASE			0x10D10024
+#define CLKMGR_MAINPLL_EN			0x00
+#define CLKMGR_MAINPLL_ENS			0x04
+#define CLKMGR_MAINPLL_ENR			0x08
+#define CLKMGR_MAINPLL_BYPASS			0x0C
+#define CLKMGR_MAINPLL_BYPASSS			0x10
+#define CLKMGR_MAINPLL_BYPASSR			0x14
+#define CLKMGR_MAINPLL_NOCCLK			0x1C
+#define CLKMGR_MAINPLL_NOCDIV			0x20
+#define CLKMGR_MAINPLL_PLLGLOB			0x24
+#define CLKMGR_MAINPLL_FDBCK			0x28
+#define CLKMGR_MAINPLL_MEM			0x2C
+#define CLKMGR_MAINPLL_MEMSTAT			0x30
+#define CLKMGR_MAINPLL_VCOCALIB			0x34
+#define CLKMGR_MAINPLL_PLLC0			0x38
+#define CLKMGR_MAINPLL_PLLC1			0x3C
+#define CLKMGR_MAINPLL_PLLC2			0x40
+#define CLKMGR_MAINPLL_PLLC3			0x44
+#define CLKMGR_MAINPLL_PLLM			0x48
+#define CLKMGR_MAINPLL_FHOP			0x4C
+#define CLKMGR_MAINPLL_SSC			0x50
+#define CLKMGR_MAINPLL_LOSTLOCK			0x54
+
+#define CLKMGR_MAINPLL(_reg)			(CLKMGR_MAINPLL_BASE + \
+							(CLKMGR_MAINPLL_##_reg))
+
+#define CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR	BIT(0)
+#define CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS	BIT(29)
 
 /* Peripheral PLL Group */
-#define CLKMGR_PERPLL					0x10d1007c
-#define CLKMGR_PERPLL_EN				0x0
-#define CLKMGR_PERPLL_ENS				0x4
-#define CLKMGR_PERPLL_BYPASS				0xc
-#define CLKMGR_PERPLL_EMACCTL				0x18
-#define CLKMGR_PERPLL_GPIODIV				0x1c
-#define CLKMGR_PERPLL_PLLGLOB				0x20
-#define CLKMGR_PERPLL_FDBCK				0x24
-#define CLKMGR_PERPLL_MEM				0x28
-#define CLKMGR_PERPLL_MEMSTAT				0x2c
-#define CLKMGR_PERPLL_PLLC0				0x30
-#define CLKMGR_PERPLL_PLLC1				0x34
-#define CLKMGR_PERPLL_VCOCALIB				0x38
-#define CLKMGR_PERPLL_PLLC2				0x3c
-#define CLKMGR_PERPLL_PLLC3				0x40
-#define CLKMGR_PERPLL_PLLM				0x44
-#define CLKMGR_PERPLL_LOSTLOCK				0x50
+#define CLKMGR_PERPLL_BASE			0x10D1007C
+#define CLKMGR_PERPLL_EN			0x00
+#define CLKMGR_PERPLL_ENS			0x04
+#define CLKMGR_PERPLL_ENR			0x08
+#define CLKMGR_PERPLL_BYPASS			0x0C
+#define CLKMGR_PERPLL_BYPASSS			0x10
+#define CLKMGR_PERPLL_BYPASSR			0x14
+#define CLKMGR_PERPLL_EMACCTL			0x18
+#define CLKMGR_PERPLL_GPIODIV			0x1C
+#define CLKMGR_PERPLL_PLLGLOB			0x20
+#define CLKMGR_PERPLL_FDBCK			0x24
+#define CLKMGR_PERPLL_MEM			0x28
+#define CLKMGR_PERPLL_MEMSTAT			0x2C
+#define CLKMGR_PERPLL_VCOCALIB			0x30
+#define CLKMGR_PERPLL_PLLC0			0x34
+#define CLKMGR_PERPLL_PLLC1			0x38
+#define CLKMGR_PERPLL_PLLC2			0x3C
+#define CLKMGR_PERPLL_PLLC3			0x40
+#define CLKMGR_PERPLL_PLLM			0x44
+#define CLKMGR_PERPLL_FHOP			0x48
+#define CLKMGR_PERPLL_SSC			0x4C
+#define CLKMGR_PERPLL_LOSTLOCK			0x50
+
+#define CLKMGR_PERPLL(_reg)			(CLKMGR_PERPLL_BASE + \
+							(CLKMGR_PERPLL_##_reg))
 
 /* Altera Group */
-#define CLKMGR_ALTERA					0x10d100d0
-#define CLKMGR_ALTERA_JTAG				0x0
-#define CLKMGR_ALTERA_EMACACTR				0x4
-#define CLKMGR_ALTERA_EMACBCTR				0x8
-#define CLKMGR_ALTERA_EMACPTPCTR			0xc
-#define CLKMGR_ALTERA_GPIODBCTR				0x10
-#define CLKMGR_ALTERA_S2FUSER0CTR			0x18
-#define CLKMGR_ALTERA_S2FUSER1CTR			0x1c
-#define CLKMGR_ALTERA_PSIREFCTR				0x20
-#define CLKMGR_ALTERA_EXTCNTRST				0x24
-#define CLKMGR_ALTERA_USB31CTR				0x28
-#define CLKMGR_ALTERA_DSUCTR				0x2c
-#define CLKMGR_ALTERA_CORE01CTR				0x30
-#define CLKMGR_ALTERA_CORE23CTR				0x34
-#define CLKMGR_ALTERA_CORE2CTR				0x38
-#define CLKMGR_ALTERA_CORE3CTR				0x3c
+#define CLKMGR_ALTERA_BASE			0x10D100D0
+#define CLKMGR_ALTERA_JTAG			0x00
+#define CLKMGR_ALTERA_EMACACTR			0x04
+#define CLKMGR_ALTERA_EMACBCTR			0x08
+#define CLKMGR_ALTERA_EMACPTPCTR		0x0C
+#define CLKMGR_ALTERA_GPIODBCTR			0x10
+#define CLKMGR_ALTERA_S2FUSER0CTR		0x18
+#define CLKMGR_ALTERA_S2FUSER1CTR		0x1C
+#define CLKMGR_ALTERA_PSIREFCTR			0x20
+#define CLKMGR_ALTERA_EXTCNTRST			0x24
+#define CLKMGR_ALTERA_USB31CTR			0x28
+#define CLKMGR_ALTERA_DSUCTR			0x2C
+#define CLKMGR_ALTERA_CORE01CTR			0x30
+#define CLKMGR_ALTERA_CORE23CTR			0x34
+#define CLKMGR_ALTERA_CORE2CTR			0x38
+#define CLKMGR_ALTERA_CORE3CTR			0x3C
+#define CLKMGR_ALTERA_SERIAL_CON_PLL_CTR	0x40
 
-/* Membus */
-#define CLKMGR_MEM_REQ					BIT(24)
-#define CLKMGR_MEM_WR					BIT(25)
-#define CLKMGR_MEM_ERR					BIT(26)
-#define CLKMGR_MEM_WDAT_OFFSET				16
-#define CLKMGR_MEM_ADDR					0x4027
-#define CLKMGR_MEM_WDAT					0x80
+#define CLKMGR_ALTERA(_reg)			(CLKMGR_ALTERA_BASE + \
+							(CLKMGR_ALTERA_##_reg))
+
+#define CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST	BIT(0)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST	BIT(1)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST	BIT(2)
+#define CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST	BIT(3)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST	BIT(5)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST	BIT(6)
+#define CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST	BIT(7)
+#define CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST	BIT(8)
+#define CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST	BIT(10)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST	BIT(11)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST	BIT(12)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST	BIT(13)
+
+#define CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST	\
+						(CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST)
+
+#define CLKMGR_ALTERA_CORE0			0
+#define CLKMGR_ALTERA_CORE1			1
+#define CLKMGR_ALTERA_CORE2			2
+#define CLKMGR_ALTERA_CORE3			3
+
+/* PLL membus configuration macros */
+#define CLKMGR_MEM_REQ				BIT(24)
+#define CLKMGR_MEM_WR				BIT(25)
+#define CLKMGR_MEM_ERR				BIT(26)
+#define CLKMGR_MEM_WDAT_OFFSET			16
+#define CLKMGR_MEM_ADDR_MASK			GENMASK(15, 0)
+#define CLKMGR_MEM_ADDR_START			0x00004000
+#define CLKMGR_PLLCFG_SRC_SYNC_MODE		0x27
+#define CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK	0xB3
+#define CLKMGR_PLLCFG_LOCK_SETTLE_TIME		0xE6
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0	0x03
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1	0x07
 
 /* Clock Manager Macros */
-#define CLKMGR_CTRL_BOOTMODE_SET_MSK			0x00000001
-#define CLKMGR_STAT_BUSY_E_BUSY				0x1
-#define CLKMGR_STAT_BUSY(x)				(((x) & 0x00000001) >> 0)
-#define CLKMGR_STAT_MAINPLLLOCKED(x)			(((x) & 0x00000100) >> 8)
-#define CLKMGR_STAT_PERPLLLOCKED(x)			(((x) & 0x00010000) >> 16)
-#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK		0x00000004
-#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK		0x00000008
-#define CLKMGR_INTOSC_HZ				460000000
+#define CLKMGR_CTRL_BOOTMODE_SET_MSK		0x00000001
+#define CLKMGR_STAT_BUSY_E_BUSY			0x1
+#define CLKMGR_STAT_BUSY(x)			(((x) & 0x00000001) >> 0)
+#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK	0x00000004
+#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK	0x00000008
+#define CLKMGR_INTOSC_HZ			460000000
+#define CLKMGR_CTRL_BOOTMODE			BIT(0)
+#define CLKMGR_STAT_MAINPLL_LOCKED		BIT(8)
+#define CLKMGR_STAT_MAIN_TRANS			BIT(9)
+#define CLKMGR_STAT_PERPLL_LOCKED		BIT(16)
+#define CLKMGR_STAT_PERF_TRANS			BIT(17)
+#define CLKMGR_STAT_BOOTMODE			BIT(24)
+#define CLKMGR_STAT_BOOTCLKSRC			BIT(25)
 
+#define CLKMGR_STAT_ALLPLL_LOCKED_MASK		(CLKMGR_STAT_MAINPLL_LOCKED | \
+						 CLKMGR_STAT_PERPLL_LOCKED)
 /* Main PLL Macros */
-#define CLKMGR_MAINPLL_EN_RESET				0x0000005e
-#define CLKMGR_MAINPLL_ENS_RESET			0x0000005e
+#define CLKMGR_MAINPLL_EN_RESET			0x0000005E
+#define CLKMGR_MAINPLL_ENS_RESET		0x0000005E
+#define CLKMGR_MAINPLL_PLLGLOB_PD_N		BIT(0)
+#define CLKMGR_MAINPLL_PLLGLOB_RST_N		BIT(1)
+#define CLKMGR_MAINPLL_PLLCX_EN			BIT(27)
+#define CLKMGR_MAINPLL_PLLCX_MUTE		BIT(28)
 
-/* Peripheral PLL Macros */
-#define CLKMGR_PERPLL_EN_RESET				0x040007FF
-#define CLKMGR_PERPLL_ENS_RESET			0x040007FF
-
-#define CLKMGR_PERPLL_EN_SDMMCCLK			BIT(5)
-#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)		(((x) << 0) & 0x0000ffff)
+#define CLKMGR_PERPLL_EN_SDMMCCLK		BIT(5)
+#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)	(((x) << 0) & 0x0000FFFF)
+#define CLKMGR_PERPLL_PLLGLOB_PD_N		BIT(0)
+#define CLKMGR_PERPLL_PLLGLOB_RST_N		BIT(1)
+#define CLKMGR_PERPLL_PLLCX_EN			BIT(27)
+#define CLKMGR_PERPLL_PLLCX_MUTE		BIT(28)
 
 /* Altera Macros */
-#define CLKMGR_ALTERA_EXTCNTRST_RESET			0xff
+#define CLKMGR_ALTERA_EXTCNTRST_RESET		0xFF
 
 /* Shared Macros */
-#define CLKMGR_PSRC(x)					(((x) & 0x00030000) >> 16)
-#define CLKMGR_PSRC_MAIN				0
-#define CLKMGR_PSRC_PER					1
+#define CLKMGR_PLLGLOB_PSRC(x)			(((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN			0
+#define CLKMGR_PSRC_PER				1
 
-#define CLKMGR_PLLGLOB_PSRC_EOSC1			0x0
-#define CLKMGR_PLLGLOB_PSRC_INTOSC			0x1
-#define CLKMGR_PLLGLOB_PSRC_F2S				0x2
+#define CLKMGR_PLLGLOB_PSRC_EOSC1		0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC		0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S			0x2
 
-#define CLKMGR_PLLM_MDIV(x)				((x) & 0x000003ff)
-#define CLKMGR_PLLGLOB_PD_SET_MSK			0x00000001
-#define CLKMGR_PLLGLOB_RST_SET_MSK			0x00000002
+#define CLKMGR_PLLM_MDIV(x)			((x) & 0x000003FF)
+#define CLKMGR_PLLGLOB_PD_SET_MSK		0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK		0x00000002
 
-#define CLKMGR_PLLGLOB_REFCLKDIV(x)			(((x) & 0x00003f00) >> 8)
-#define CLKMGR_PLLGLOB_AREFCLKDIV(x)			(((x) & 0x00000f00) >> 8)
-#define CLKMGR_PLLGLOB_DREFCLKDIV(x)			(((x) & 0x00003000) >> 12)
+#define CLKMGR_PLLGLOB_REFCLKDIV(x)		(((x) & 0x00003F00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x)		(((x) & 0x00000F00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x)		(((x) & 0x00003000) >> 12)
 
-#define CLKMGR_VCOCALIB_HSCNT_SET(x)			(((x) << 0) & 0x000003ff)
-#define CLKMGR_VCOCALIB_MSCNT_SET(x)			(((x) << 16) & 0x00ff0000)
+#define CLKMGR_VCOCALIB_HSCNT_SET(x)		(((x) << 0) & 0x000003FF)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x)		(((x) << 16) & 0x00FF0000)
 
-#define CLKMGR_CLR_LOSTLOCK_BYPASS			0x20000000
+#define CLKMGR_CLR_LOSTLOCK_BYPASS		0x20000000
 
-typedef struct {
-	uint32_t  clk_freq_of_eosc1;
-	uint32_t  clk_freq_of_f2h_free;
-	uint32_t  clk_freq_of_cb_intosc_ls;
-} CLOCK_SOURCE_CONFIG;
+#define CLKMGR_CLKSRC_MASK			GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET			16
+#define CLKMGR_CLKSRC_MAIN			0
+#define CLKMGR_CLKSRC_PER			1
+#define CLKMGR_CLKSRC_OSC1			2
+#define CLKMGR_CLKSRC_INTOSC			3
+#define CLKMGR_CLKSRC_FPGA			4
+#define CLKMGR_PLLCX_DIV_MSK			GENMASK(10, 0)
 
-void config_clkmgr_handoff(handoff *hoff_ptr);
-uint32_t get_wdt_clk(void);
-uint32_t get_uart_clk(void);
-uint32_t get_mmc_clk(void);
+#define GET_CLKMGR_CLKSRC(x)			(((x) & CLKMGR_CLKSRC_MASK) >> \
+							CLKMGR_CLKSRC_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_MASK		GENMASK(5, 4)
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET	4
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4MP(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4MP_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_MASK		GENMASK(7, 6)
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET	6
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SP(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4SP_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_MASK		GENMASK(17, 16)
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET	16
+#define GET_CLKMGR_MAINPLL_NOCDIV_SPHY(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_SPHY_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET)
+
+
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK	GENMASK(3, 2)
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET	2
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET)
+
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK	BIT(26)
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET	26
+#define GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(x)	(((x) & CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK) >> \
+						CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET)
+
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK	GENMASK(18, 16)
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET	16
+#define GET_CLKMGR_EMACACTR_CLK_SRC(x)		(((x) & CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK) >> \
+						CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET)
+
+#define CLKMGR_MPU_CLK_ID			0
+#define CLKMGR_MPU_PERIPH_CLK_ID		1
+#define CLKMGR_L4_MAIN_CLK_ID			2
+#define CLKMGR_L4_MP_CLK_ID			3
+#define CLKMGR_L4_SP_CLK_ID			4
+#define CLKMGR_WDT_CLK_ID			5
+#define CLKMGR_UART_CLK_ID			6
+#define CLKMGR_EMAC0_CLK_ID			7
+#define CLKMGR_EMAC1_CLK_ID			8
+#define CLKMGR_EMAC2_CLK_ID			9
+#define CLKMGR_EMAC_PTP_CLK_ID			10
+#define CLKMGR_SDMMC_CLK_ID			11
+
+#define CLKMGR_MAINPLL_BYPASS_ALL		(0xF6)
+#define CLKMGR_PERPLL_BYPASS_ALL		(0xEF)
+#define CLKMGR_PLLCX_STAT			BIT(29)
+#define GET_PLLCX_STAT(x)			((x) & CLKMGR_PLLCX_STAT)
+
+#define CLKMGR_MAINPLL_TYPE			(0)
+#define CLKMGR_PERPLL_TYPE			(1)
+
+#define CLKMGR_MAX_RETRY_COUNT			1000
+
+#define CLKMGR_PLLM_MDIV_MASK			GENMASK(9, 0)
+#define CLKMGR_PLLGLOB_PD_MASK			BIT(0)
+#define CLKMGR_PLLGLOB_RST_MASK			BIT(1)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_MASK		GENMASK(11, 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV_MASK		GENMASK(13, 12)
+#define CLKMGR_PLLGLOB_REFCLKDIV_MASK		GENMASK(13, 8)
+#define CLKMGR_PLLGLOB_MODCLKDIV_MASK		GENMASK(24, 27)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET	8
+#define CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET	12
+#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET		8
+#define CLKMGR_PLLGLOB_MODCLKDIV_OFFSET		24
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK		GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET		16
+#define CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK	BIT(29)
+
+#define CLKMGR_VCOCALIB_MSCNT_MASK		GENMASK(23, 16)
+#define CLKMGR_VCOCALIB_MSCNT_OFFSET		16
+#define CLKMGR_VCOCALIB_HSCNT_MASK		GENMASK(9, 0)
+#define CLKMGR_VCOCALIB_MSCNT_CONST		100
+#define CLKMGR_VCOCALIB_HSCNT_CONST		4
+
+int config_clkmgr_handoff(handoff *hoff_ptr);
+uint32_t clkmgr_get_rate(uint32_t clk_id);
+
+/* PLL configuration data structure in power-down state */
+typedef struct pll_cfg {
+	uint32_t addr;
+	uint32_t data;
+	uint32_t mask;
+} pll_cfg_t;
 
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_ddr.h b/plat/intel/soc/agilex5/include/agilex5_ddr.h
new file mode 100644
index 0000000..631e006
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_ddr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_DDR_H
+#define AGILEX5_DDR_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <lib/utils_def.h>
+
+#include "socfpga_handoff.h"
+
+#define CONFIG_NR_DRAM_BANKS	1
+
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+typedef phys_addr_t fdt_addr_t;
+
+/* DDR/RAM configuration */
+struct ddr_info {
+	phys_addr_t start;
+	phys_size_t size;
+};
+
+int agilex5_ddr_init(handoff *hoff_ptr);
+
+#endif /* AGILEX5_DDR_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
new file mode 100644
index 0000000..1fd8ef6
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_IOSSM_MAILBOX_H
+#define AGILEX5_IOSSM_MAILBOX_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lib/mmio.h"
+#include "agilex5_ddr.h"
+
+#define TIMEOUT_5000MS					5000
+#define TIMEOUT						TIMEOUT_5000MS
+#define IOSSM_STATUS_CAL_SUCCESS			BIT(0)
+#define IOSSM_STATUS_CAL_FAIL				BIT(1)
+#define IOSSM_STATUS_CAL_BUSY				BIT(2)
+#define IOSSM_STATUS_COMMAND_RESPONSE_READY		1
+#define IOSSM_CMD_RESPONSE_STATUS_OFFSET		0x45C
+#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET		0x458
+#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET		0x454
+#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET		0x450
+#define IOSSM_CMD_REQ_OFFSET				0x43C
+#define IOSSM_CMD_PARAM_0_OFFSET			0x438
+#define IOSSM_CMD_PARAM_1_OFFSET			0x434
+#define IOSSM_CMD_PARAM_2_OFFSET			0x430
+#define IOSSM_CMD_PARAM_3_OFFSET			0x42C
+#define IOSSM_CMD_PARAM_4_OFFSET			0x428
+#define IOSSM_CMD_PARAM_5_OFFSET			0x424
+#define IOSSM_CMD_PARAM_6_OFFSET			0x420
+#define IOSSM_STATUS_OFFSET				0x400
+#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK		GENMASK(31, 16)
+#define IOSSM_CMD_RESPONSE_DATA_SHORT(data)		(((data) & \
+							IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
+#define MAX_IO96B_SUPPORTED				2
+#define MAX_MEM_INTERFACES_SUPPORTED			2
+
+/* supported mailbox command type */
+enum iossm_mailbox_cmd_type  {
+	CMD_NOP,
+	CMD_GET_SYS_INFO,
+	CMD_GET_MEM_INFO,
+	CMD_GET_MEM_CAL_INFO,
+	CMD_TRIG_CONTROLLER_OP,
+	CMD_TRIG_MEM_CAL_OP
+};
+
+/* supported mailbox command opcode */
+enum iossm_mailbox_cmd_opcode  {
+	GET_MEM_INTF_INFO = 0x0001,
+	GET_MEM_TECHNOLOGY,
+	GET_MEMCLK_FREQ_KHZ,
+	GET_MEM_WIDTH_INFO,
+	ECC_ENABLE_SET = 0x0101,
+	ECC_ENABLE_STATUS,
+	ECC_INTERRUPT_STATUS,
+	ECC_INTERRUPT_ACK,
+	ECC_INTERRUPT_MASK,
+	ECC_WRITEBACK_ENABLE,
+	ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201,
+	ECC_SCRUB_MODE_0_START,
+	ECC_SCRUB_MODE_1_START,
+	BIST_STANDARD_MODE_START = 0x0301,
+	BIST_RESULTS_STATUS,
+	BIST_MEM_INIT_START,
+	BIST_MEM_INIT_STATUS,
+	BIST_SET_DATA_PATTERN_UPPER,
+	BIST_SET_DATA_PATTERN_LOWER,
+	TRIG_MEM_CAL = 0x000a,
+	GET_MEM_CAL_STATUS
+};
+
+/*
+ * IOSSM mailbox required information
+ *
+ * @num_mem_interface:	Number of memory interfaces instantiated
+ * @ip_type:		IP type implemented on the IO96B
+ * @ip_instance_id:	IP identifier for every IP instance implemented on the IO96B
+ */
+struct io96b_mb_ctrl {
+	uint32_t num_mem_interface;
+	uint32_t ip_type[2];
+	uint32_t ip_instance_id[2];
+};
+
+/*
+ * IOSSM mailbox response outputs
+ *
+ * @cmd_resp_status: Command Interface status
+ * @cmd_resp_data_*: More spaces for command response
+ */
+struct io96b_mb_resp {
+	uint32_t cmd_resp_status;
+	uint32_t cmd_resp_data_0;
+	uint32_t cmd_resp_data_1;
+	uint32_t cmd_resp_data_2;
+};
+
+/*
+ * IO96B instance specific information
+ *
+ * @size:		Memory size
+ * @io96b_csr_addr:	IO96B instance CSR address
+ * @cal_status:		IO96B instance calibration status
+ * @mb_ctrl:		IOSSM mailbox required information
+ */
+struct io96b_instance {
+	uint16_t size;
+	phys_addr_t io96b_csr_addr;
+	bool cal_status;
+	struct io96b_mb_ctrl mb_ctrl;
+};
+
+/*
+ * Overall IO96B instance(s) information
+ *
+ * @num_instance:	Number of instance(s) assigned to HPS
+ * @overall_cal_status: Overall calibration status for all IO96B instance(s)
+ * @ddr_type:		DDR memory type
+ * @ecc_status:		ECC enable status (false = disabled, true = enabled)
+ * @overall_size:	Total DDR memory size
+ * @io96b_0:		IO96B 0 instance specific information
+ * @io96b_1:		IO96B 1 instance specific information
+ */
+struct io96b_info {
+	uint8_t num_instance;
+	bool overall_cal_status;
+	const char *ddr_type;
+	bool ecc_status;
+	uint16_t overall_size;
+	struct io96b_instance io96b_0;
+	struct io96b_instance io96b_1;
+};
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp);
+
+/* Supported IOSSM mailbox function */
+void io96b_mb_init(struct io96b_info *io96b_ctrl);
+int io96b_cal_status(phys_addr_t addr);
+void init_mem_cal(struct io96b_info *io96b_ctrl);
+int trig_mem_cal(struct io96b_info *io96b_ctrl);
+int get_mem_technology(struct io96b_info *io96b_ctrl);
+int get_mem_width_info(struct io96b_info *io96b_ctrl);
+int ecc_enable_status(struct io96b_info *io96b_ctrl);
+int bist_mem_init_start(struct io96b_info *io96b_ctrl);
+
+#endif /* AGILEX5_IOSSM_MAILBOX_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_pinmux.h b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
index 8a8e8c7..78d19af 100644
--- a/plat/intel/soc/agilex5/include/agilex5_pinmux.h
+++ b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,19 +8,13 @@
 #ifndef AGX5_PINMUX_H
 #define AGX5_PINMUX_H
 
-/* PINMUX REGISTER ADDRESS */
-#define AGX5_PINMUX_PIN0SEL					0x10d13000
-#define AGX5_PINMUX_IO0CTRL					0x10d13130
-#define AGX5_PINMUX_EMAC0_USEFPGA				0x10d13300
-#define AGX5_PINMUX_IO0_DELAY					0x10d13400
-#define AGX5_PERIPHERAL						0x10d14044
-
 #include "socfpga_handoff.h"
 
-/* PINMUX DEFINE */
-#define PINMUX_HANDOFF_ARRAY_SIZE(x)				(sizeof(x) / sizeof((x)[0]))
-#define PINMUX_HANDOFF_CONFIG_ADDR				0xbeec
-#define PINMUX_HANDOFF_CONFIG_VAL				0x7e000
+/* PINMUX REGISTER ADDRESS */
+#define AGX5_PINMUX_PIN0SEL					0x10D13000
+#define AGX5_PINMUX_IO0CTRL					0x10D13130
+#define AGX5_PINMUX_EMAC0_USEFPGA				0x10D13300
+#define AGX5_PINMUX_IO0_DELAY					0x10D13400
 
 /* Macros */
 #define SOCFPGA_PINMUX_SEL_NAND					(0x03)
@@ -142,6 +137,9 @@
 #define SOCFPGA_PINMUX_JTAG_USEFPGA				(0x50)
 #define SOCFPGA_PINMUX_SDMMC_USEFPGA				(0x54)
 
+#define SOCFPGA_PINUMX_USEFPGA(_reg)				(AGX5_PINMUX_EMAC0_USEFPGA \
+								+ SOCFPGA_PINMUX_##_reg)
+
 #define SOCFPGA_PINMUX_IO0DELAY					(0x00)
 #define SOCFPGA_PINMUX_IO1DELAY					(0x04)
 #define SOCFPGA_PINMUX_IO2DELAY					(0x08)
@@ -198,5 +196,4 @@
 								+ (SOCFPGA_PINMUX_##_reg))
 
 void config_pinmux(handoff *handoff);
-void config_peripheral(handoff *handoff);
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
index 1bba74b..178fd5b 100644
--- a/plat/intel/soc/agilex5/include/agilex5_power_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,7 +78,5 @@
 #define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY			0x0
 #define AGX5_PWRMGR_PSS_STAT_BUSY(x)				(((x) & 0x000000FF) >> 0)
 
-int pss_sram_power_off(handoff *hoff_ptr);
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
-
+void config_pwrmgr_handoff(handoff *hoff_ptr);
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
index 53dcd13..ac4bf12 100644
--- a/plat/intel/soc/agilex5/include/agilex5_system_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -25,6 +25,7 @@
 #define SOCFPGA_SYSMGR_TSN_0_ACE					0x50
 #define SOCFPGA_SYSMGR_TSN_1_ACE					0x54
 #define SOCFPGA_SYSMGR_TSN_2_ACE					0x58
+#define SOCFPGA_SYSMGR_FPGA_BRIDGE_CTRL				0x5C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_1					0x68
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_2					0x6C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_3					0x70
@@ -122,7 +123,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8				0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9				0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG					0x228
-#define SOCFPGA_SYSMGR_MPFE_status					0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS					0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0				0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1				0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2				0x238
@@ -184,11 +185,28 @@
 #define SDM								0x000A000A
 #define CORE_SIGHT_DEBUG						0x000B000B
 
+/* JTAG ID value for Agilex5 */
+#define A590_JTAG_ID							0x9000
+#define A594_JTAG_ID							0x40009000
+#define A5C0_JTAG_ID							0xC000
+#define A5C4_JTAG_ID							0x4000C000
+#define A5D0_JTAG_ID							0xD000
+#define A5D4_JTAG_ID							0x4000D000
+#define A5F0_JTAG_ID							0xC000
+#define A5F4_JTAG_ID							0x4000F000
+#define A510_JTAG_ID							0x1000
+#define A514_JTAG_ID							0x40001000
+#define A530_JTAG_ID							0x3000
+#define A534_JTAG_ID							0x40003000
+#define JTAG_ID_MASK							0xC000F000
+
 /* Field Masking */
 #define SYSMGR_SDMMC_DRVSEL(x)						(((x) & 0x7) << 0)
 #define SYSMGR_SDMMC_SMPLSEL(x)						(((x) & 0x7) << 4)
 
 #define SYSMGR_F2S_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_SOC_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_LWSOC_BRIDGE_CTRL_EN					BIT(1)
 #define IDLE_DATA_LWSOC2FPGA						BIT(4)
 #define IDLE_DATA_SOC2FPGA						BIT(0)
 #define IDLE_DATA_MASK							(IDLE_DATA_LWSOC2FPGA \
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index 9bfc304..c1f3cc5 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -11,11 +11,15 @@
 
 #include "agilex5_memory_controller.h"
 #include "agilex5_system_manager.h"
+
 #include <platform_def.h>
 
 /* Platform Setting */
 #define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX5
-#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex5 is Cache flush.
+ */
+#define CACHE_FLUSH							1
 #define MMC_DEVICE_TYPE						1  /* MMC = 0, SD = 1 */
 #define XLAT_TABLES_V2						U(1)
 #define PLAT_PRIMARY_CPU_A55					0x000
@@ -23,22 +27,43 @@
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT				MPIDR_AFF2_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT				MPIDR_AFF1_SHIFT
 #define PLAT_L2_RESET_REQ					0xB007C0DE
+#define PLAT_HANDOFF_OFFSET					0x0007F000
+#define PLAT_TIMER_BASE_ADDR					0x10D01000
 
 /* System Counter */
 /* TODO: Update back to 400MHz.
  * This shall be updated to read from L4 clock instead of hardcoded.
  */
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				(400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				(400)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				U(400000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				U(400)
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x80400000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x2000000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x82000000
 
 /* QSPI Setting */
 #define CAD_QSPIDATA_OFST					0x10900000
 #define CAD_QSPI_OFFSET						0x108d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE						(0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE					(0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE					(0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE					(0x90000000)
+#define PLAT_MMC_DATA_SIZE					(0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE					U(32768)
+#else
+#define PLAT_MMC_DATA_BASE					(0x0007D000)
+#define PLAT_MMC_DATA_SIZE					(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE					U(8192)
+#endif
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE				0x1c000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE				0x18001000
@@ -55,10 +80,22 @@
 #define SOCFPGA_L4_SYS_SCR_REG_BASE				0x10d21100
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE				0x10d21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE				0x10d21300
+#define SOCFPGA_SDMMC_SECU_BIT					0x40
+#define SOCFPGA_LWSOC2FPGA_ENABLE				0xffe0301
+#define SOCFPGA_SDMMC_SECU_BIT_ENABLE				0x1010001
+
 
 /* Define maximum page size for NAND flash devices */
 #define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x2000)
 
+/* OCRAM Register*/
+
+#define OCRAM_REG_BASE						0x108CC400
+#define OCRAM_REGION_0_OFFSET					0x18
+#define OCRAM_REGION_0_REG_BASE					(OCRAM_REG_BASE + \
+								OCRAM_REGION_0_OFFSET)
+#define OCRAM_NON_SECURE_ENABLE					0x0
+
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
@@ -88,11 +125,10 @@
 #define GIC_SIZE						(0x00100000)
 
 #define BL2_BASE						(0x00000000)
-#define BL2_LIMIT						(0x0002b000)
+#define BL2_LIMIT						(0x0007E000)
 
 #define BL31_BASE						(0x80000000)
 #define BL31_LIMIT						(0x82000000)
-
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 90678e1..a831c39 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -58,14 +58,16 @@
 		lib/cpus/aarch64/cortex_a76.S				\
 		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
 		plat/intel/soc/agilex5/soc/agilex5_memory_controller.c	\
-		plat/intel/soc/agilex5/soc/agilex5_mmc.c			\
+		plat/intel/soc/agilex5/soc/agilex5_mmc.c		\
 		plat/intel/soc/agilex5/soc/agilex5_pinmux.c		\
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/agilex5/soc/agilex5_ddr.c		\
+		plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c	\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
-		plat/intel/soc/common/socfpga_vab.c				\
+		plat/intel/soc/common/socfpga_vab.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		\
@@ -97,6 +99,7 @@
 		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
 		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_system_manager.c	\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
 # Configs for A76 and A55
@@ -111,6 +114,24 @@
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 # Configs for VAB Authentication
 SOCFPGA_SECURE_VAB_AUTH  := 	0
 $(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
diff --git a/plat/intel/soc/agilex5/soc/agilex5_cache.S b/plat/intel/soc/agilex5/soc/agilex5_cache.S
index a174386..f8c6a2d 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_cache.S
+++ b/plat/intel/soc/agilex5/soc/agilex5_cache.S
@@ -9,6 +9,23 @@
 #include <plat_macros.S>
 
 	.globl invalidate_dcache_all
+	.globl invalidate_cache_low_el
+	/* --------------------------------------------------------
+	 * Invalidate for NS EL2 and EL1
+	 * --------------------------------------------------------
+	 */
+func invalidate_cache_low_el
+	mrs	x0, SCR_EL3
+	orr	x1, x0, #SCR_NS_BIT
+	msr	SCR_EL3, x1
+	isb
+	tlbi	ALLE2
+	dsb	sy
+	tlbi	ALLE1
+	dsb	sy
+	msr	SCR_EL3, x0
+	isb
+endfunc invalidate_cache_low_el
 
 .pushsection .text.asm_dcache_level, "ax"
 func asm_dcache_level
diff --git a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
index fdf1a82..603aaf8 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,244 +14,639 @@
 
 #include "agilex5_clock_manager.h"
 #include "agilex5_system_manager.h"
-#include "socfpga_handoff.h"
 #include "socfpga_system_manager.h"
 
-uint32_t wait_pll_lock(void)
+/* Main and Peripheral PLL configurations in Power Down(PD) state. */
+static const pll_cfg_t pll_cfg_set[] = {
+	{
+		/* Enable source synchronous mode */
+		CLKMGR_PLLCFG_SRC_SYNC_MODE,
+		BIT(7),
+		BIT(7)
+	},
+	{
+		/* Limit the PLL overshoot frequency during lock */
+		CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK,
+		BIT(0),
+		BIT(0)
+	},
+	{
+		/* To give the PLL more time to settle before lock is asserted */
+		CLKMGR_PLLCFG_LOCK_SETTLE_TIME,
+		BIT(0),
+		BIT(0)
+	},
+	{
+		/* To set the PLL centering duty cycle for clock slice 0 */
+		CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0,
+		0x4A,
+		GENMASK(6, 0)
+	},
+	{
+		/* To set the PLL centering duty cycle for clock slice 1 */
+		CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1,
+		0x4A,
+		GENMASK(6, 0)
+	},
+};
+
+static int wait_pll_lock(uint32_t mask)
 {
 	uint32_t data;
 	uint32_t count = 0;
+	uint32_t retry = 0U;
 
 	do {
-		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
-		count++;
-		if (count >= 1000)
+		/* return time out */
+		if (count >= CLKMGR_MAX_RETRY_COUNT) {
+			ERROR("CLKMGR: Timed out to satisfy the PLL mask\n");
 			return -ETIMEDOUT;
+		}
 
-	} while ((CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
-			(CLKMGR_STAT_PERPLLLOCKED(data) == 0));
+		data = mmio_read_32(CLKMGR(STAT)) & mask;
+		/* wait for stable lock, make sure it is stable for these counts */
+		if (data == mask) {
+			retry++;
+		} else {
+			retry = 0U;
+		}
+
+		/* we are good now, break */
+		if (retry >= 5U) {
+			break;
+		}
+
+		count++;
+	} while (1);
+
 	return 0;
 }
 
-uint32_t wait_fsm(void)
+static int wait_fsm(void)
 {
 	uint32_t data;
 	uint32_t count = 0;
 
 	do {
-		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		data = mmio_read_32(CLKMGR(STAT));
 		count++;
-		if (count >= 1000)
+		if (count >= CLKMGR_MAX_RETRY_COUNT) {
+			ERROR("CLKMGR: Timed out on fsm state\n");
 			return -ETIMEDOUT;
-
+		}
 	} while (CLKMGR_STAT_BUSY(data) == CLKMGR_STAT_BUSY_E_BUSY);
 
 	return 0;
 }
 
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
+static uint32_t calc_pll_vcocalibration(uint32_t pllm, uint32_t pllglob)
 {
-	uint32_t val = 0;
-	uint32_t count = 0;
-	uint32_t req_status = 0;
+	uint32_t mdiv, refclkdiv, drefclkdiv, mscnt, hscnt, vcocalib;
 
-	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
-		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
-	mmio_write_32(pll_mem_offset, val);
+	mdiv = pllm & CLKMGR_PLLM_MDIV_MASK;
+	drefclkdiv = ((pllglob & CLKMGR_PLLGLOB_DREFCLKDIV_MASK) >>
+			CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET);
+	refclkdiv = ((pllglob & CLKMGR_PLLGLOB_REFCLKDIV_MASK) >>
+			CLKMGR_PLLGLOB_REFCLKDIV_OFFSET);
+	mscnt = CLKMGR_VCOCALIB_MSCNT_CONST / (mdiv * BIT(drefclkdiv));
+	if (mscnt == 0) {
+		mscnt = 1;
+	}
 
-	do {
-		req_status = mmio_read_32(pll_mem_offset);
+	hscnt = (mdiv * mscnt * BIT(drefclkdiv) / refclkdiv) -
+		CLKMGR_VCOCALIB_HSCNT_CONST;
+
+	vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+			((mscnt << CLKMGR_VCOCALIB_MSCNT_OFFSET) &
+			CLKMGR_VCOCALIB_MSCNT_MASK);
+
+	return vcocalib;
+}
+
+static int pll_source_sync_wait(uint32_t pll_type, int retry_count)
+{
+	int count = 0;
+	uint32_t req_status;
+
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+	} else {
+		req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
+	}
+
+	/* Check for error bit set */
+	if ((req_status & CLKMGR_MEM_ERR) != 0) {
+		INFO("CLKMGR: %s: Memory Error Status Signal Assert\n", __func__);
+	}
+
+	while ((count < retry_count) && (req_status & CLKMGR_MEM_REQ)) {
+		if (pll_type == CLKMGR_MAINPLL_TYPE)
+			req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+		else
+			req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
 		count++;
-	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+	}
 
-	if (count >= 10)
+	if (count >= retry_count) {
+		ERROR("CLKMGR: %s: timeout with pll_type %d\n", __func__, pll_type);
 		return -ETIMEDOUT;
+	}
 
 	return 0;
 }
 
-uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
+static int pll_source_sync_config(uint32_t pll_type, uint32_t addr_offset,
+				  uint32_t wdat, int retry_count)
 {
-	uint32_t val = 0;
-	uint32_t rdata = 0;
-	uint32_t count = 0;
-	uint32_t req_status = 0;
+	uint32_t addr;
+	uint32_t val;
 
-	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_ADDR);
-	mmio_write_32(pll_mem_offset, val);
+	addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_WR |
+		(wdat << CLKMGR_MEM_WDAT_OFFSET) | addr);
 
-	do {
-		req_status = mmio_read_32(pll_mem_offset);
-		count++;
-	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+	} else {
+		mmio_write_32(CLKMGR_PERPLL(MEM), val);
+	}
 
-	if (count >= 10)
-		return -ETIMEDOUT;
-
-	rdata = mmio_read_32(pll_mem_offset + 0x4);
-	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
-
-	return rdata;
+	return pll_source_sync_wait(pll_type, retry_count);
 }
 
-void config_clkmgr_handoff(handoff *hoff_ptr)
+static int pll_source_sync_read(uint32_t pll_type, uint32_t addr_offset,
+				uint32_t *rdata, int retry_count)
 {
-	/* Take both PLL out of reset and power up */
+	uint32_t addr;
+	uint32_t val;
 
-	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
-			CLKMGR_PLLGLOB_PD_SET_MSK |
-			CLKMGR_PLLGLOB_RST_SET_MSK);
-	mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
-			CLKMGR_PLLGLOB_PD_SET_MSK |
-			CLKMGR_PLLGLOB_RST_SET_MSK);
+	addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+	val = ((CLKMGR_MEM_REQ & ~CLKMGR_MEM_WR) | addr);
 
-	/* PLL lock */
-	wait_pll_lock();
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+	} else {
+		mmio_write_32(CLKMGR_PERPLL(MEM), val);
+	}
+
+	*rdata = 0;
+
+	if ((pll_source_sync_wait(pll_type, retry_count)) != 0) {
+		return -ETIMEDOUT;
+	}
+
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		*rdata = mmio_read_32(CLKMGR_MAINPLL(MEMSTAT));
+	} else {
+		*rdata = mmio_read_32(CLKMGR_PERPLL(MEMSTAT));
+	}
+
+	return 0;
+}
+
+static void config_pll_pd_state(uint32_t pll_type)
+{
+	uint32_t rdata;
+
+	for (uint32_t i = 0; i < ARRAY_SIZE(pll_cfg_set); i++) {
+		(void)pll_source_sync_read(pll_type, pll_cfg_set[i].addr, &rdata,
+					   CLKMGR_MAX_RETRY_COUNT);
+
+		(void)pll_source_sync_config(pll_type, pll_cfg_set[i].addr,
+				((rdata & ~pll_cfg_set[i].mask) | pll_cfg_set[i].data),
+				CLKMGR_MAX_RETRY_COUNT);
+	}
+}
+
+int config_clkmgr_handoff(handoff *hoff_ptr)
+{
+	int ret = 0;
+	uint32_t mainpll_vcocalib;
+	uint32_t perpll_vcocalib;
+
+	/* Enter boot mode before any configuration */
+	mmio_setbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
 
 	/* Bypass all mainpllgrp's clocks to input clock ref */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASSS, 0xff);
-	/* Bypass all perpllgrp's clocks to input clock ref */
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0xff);
+	mmio_setbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0)
+		return ret;
 
-	/* Pass clock source frequency into scratch register */
-	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
-		hoff_ptr->hps_osc_clk_hz);
-	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
-		hoff_ptr->fpga_clk_hz);
+	/* Bypass all perpllgrp's clocks to input clock ref */
+	mmio_setbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0)
+		return ret;
+
+	/* Take both PLL out of reset and power down */
+	mmio_clrbits_32(CLKMGR_MAINPLL(PLLGLOB),
+			CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_clrbits_32(CLKMGR_PERPLL(PLLGLOB),
+			CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+	/* Setup main PLL dividers */
+	mainpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->main_pll_pllm,
+						hoff_ptr->main_pll_pllglob);
+	mmio_write_32(CLKMGR_MAINPLL(PLLGLOB),
+			hoff_ptr->main_pll_pllglob & ~CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_write_32(CLKMGR_MAINPLL(FDBCK), hoff_ptr->main_pll_fdbck);
+	mmio_write_32(CLKMGR_MAINPLL(VCOCALIB), mainpll_vcocalib);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC0), hoff_ptr->main_pll_pllc0);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC1), hoff_ptr->main_pll_pllc1);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC2), hoff_ptr->main_pll_pllc2);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC3), hoff_ptr->main_pll_pllc3);
+	mmio_write_32(CLKMGR_MAINPLL(PLLM), hoff_ptr->main_pll_pllm);
+	mmio_write_32(CLKMGR_MAINPLL(NOCCLK), hoff_ptr->main_pll_nocclk);
+	mmio_write_32(CLKMGR_MAINPLL(NOCDIV), hoff_ptr->main_pll_nocdiv);
+
+	/* Setup peripheral PLL dividers */
+	perpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->per_pll_pllm,
+						hoff_ptr->per_pll_pllglob);
+	mmio_write_32(CLKMGR_PERPLL(PLLGLOB),
+			hoff_ptr->per_pll_pllglob & ~CLKMGR_PERPLL_PLLGLOB_RST_N);
+	mmio_write_32(CLKMGR_PERPLL(FDBCK), hoff_ptr->per_pll_fdbck);
+	mmio_write_32(CLKMGR_PERPLL(VCOCALIB), perpll_vcocalib);
+	mmio_write_32(CLKMGR_PERPLL(PLLC0), hoff_ptr->per_pll_pllc0);
+	mmio_write_32(CLKMGR_PERPLL(PLLC1), hoff_ptr->per_pll_pllc1);
+	mmio_write_32(CLKMGR_PERPLL(PLLC2), hoff_ptr->per_pll_pllc2);
+	mmio_write_32(CLKMGR_PERPLL(PLLC3), hoff_ptr->per_pll_pllc3);
+	mmio_write_32(CLKMGR_PERPLL(PLLM), hoff_ptr->per_pll_pllm);
+	mmio_write_32(CLKMGR_PERPLL(EMACCTL), hoff_ptr->per_pll_emacctl);
+	mmio_write_32(CLKMGR_PERPLL(GPIODIV), hoff_ptr->per_pll_gpiodiv);
+
+	/* Configure ping pong counters */
+	mmio_write_32(CLKMGR_ALTERA(EMACACTR), hoff_ptr->alt_emacactr);
+	mmio_write_32(CLKMGR_ALTERA(EMACBCTR), hoff_ptr->alt_emacbctr);
+	mmio_write_32(CLKMGR_ALTERA(EMACPTPCTR), hoff_ptr->alt_emacptpctr);
+	mmio_write_32(CLKMGR_ALTERA(GPIODBCTR), hoff_ptr->alt_gpiodbctr);
+	mmio_write_32(CLKMGR_ALTERA(S2FUSER0CTR), hoff_ptr->alt_s2fuser0ctr);
+	mmio_write_32(CLKMGR_ALTERA(S2FUSER1CTR), hoff_ptr->alt_s2fuser1ctr);
+	mmio_write_32(CLKMGR_ALTERA(PSIREFCTR), hoff_ptr->alt_psirefctr);
+	mmio_write_32(CLKMGR_ALTERA(USB31CTR), hoff_ptr->alt_usb31ctr);
+	mmio_write_32(CLKMGR_ALTERA(DSUCTR), hoff_ptr->alt_dsuctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE01CTR), hoff_ptr->alt_core01ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE23CTR), hoff_ptr->alt_core23ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE2CTR), hoff_ptr->alt_core2ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE3CTR), hoff_ptr->alt_core3ctr);
+
+	/* Take both PLL out of reset and power up */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB),
+			CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB),
+			CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+	/* Main PLL configuration in Powed down state */
+	config_pll_pd_state(CLKMGR_MAINPLL_TYPE);
+
+	/* Peripheral PLL configuration in Powed down state */
+	config_pll_pd_state(CLKMGR_PERPLL_TYPE);
+
+	/* Enable main PLL clkslices */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC0), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC1), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC2), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC3), CLKMGR_MAINPLL_PLLCX_EN);
+
+	/* Enable periheral PLL clkslices */
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC0), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC1), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC2), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC3), CLKMGR_PERPLL_PLLCX_EN);
+
+	/* Wait for main and peri PLL lock state */
+	ret = wait_pll_lock(CLKMGR_STAT_ALLPLLLOCKED);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Main PLL and per PLL lost lock */
+	mmio_setbits_32(CLKMGR_MAINPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+	mmio_setbits_32(CLKMGR_PERPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+
+	/* Main PLL and per PLL clear lostlock bypass */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
+
+	/* Pass clock source frequency into boot scratch register */
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), hoff_ptr->hps_osc_clk_hz);
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), hoff_ptr->fpga_clk_hz);
 
 	/* Take all PLLs out of bypass */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0);
-	wait_fsm();
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0);
-	wait_fsm();
+	mmio_clrbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0) {
+		return ret;
+	}
 
-	/* Enable mainpllgrp's software-managed clock */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_EN,
-			CLKMGR_MAINPLL_EN_RESET);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
-			CLKMGR_PERPLL_EN_RESET);
+	mmio_clrbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Clear the loss of lock bits (write 1 to clear) */
+	mmio_write_32(CLKMGR(INTRCLR),
+			CLKMGR_INTRCLR_MAINLOCKLOST | CLKMGR_INTRCLR_PERLOCKLOST);
+
+	/* Take all ping pong counters out of reset */
+	mmio_clrbits_32(CLKMGR_ALTERA(EXTCNTRST), CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST);
+
+	/* Exit boot mode */
+	mmio_clrbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
+
+	return 0;
 }
 
 /* Extract reference clock from platform clock source */
-uint32_t get_ref_clk(uint32_t pllglob)
+uint32_t get_ref_clk(uint32_t pllglob_reg, uint32_t pllm_reg)
 {
-	uint32_t arefclkdiv, ref_clk;
-	uint32_t scr_reg;
+	uint32_t arefclkdiv, ref_clk, mdiv;
+	uint32_t pllglob_val, pllm_val;
 
-	switch (CLKMGR_PSRC(pllglob)) {
+	/* Read pllglob and pllm registers */
+	pllglob_val = mmio_read_32(pllglob_reg);
+	pllm_val = mmio_read_32(pllm_reg);
+
+	switch (CLKMGR_PLLGLOB_PSRC(pllglob_val)) {
 	case CLKMGR_PLLGLOB_PSRC_EOSC1:
-		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
-		ref_clk = mmio_read_32(scr_reg);
+		ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
 		break;
+
 	case CLKMGR_PLLGLOB_PSRC_INTOSC:
 		ref_clk = CLKMGR_INTOSC_HZ;
 		break;
+
 	case CLKMGR_PLLGLOB_PSRC_F2S:
-		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
-		ref_clk = mmio_read_32(scr_reg);
+		ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
 		break;
+
 	default:
 		ref_clk = 0;
 		assert(0);
 		break;
 	}
 
-	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+	/* Get reference clock divider */
+	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob_val);
 	ref_clk /= arefclkdiv;
 
+	/* Feedback clock divider */
+	mdiv = CLKMGR_PLLM_MDIV(pllm_val);
+	ref_clk *= mdiv;
+
+	VERBOSE("CLKMGR: %s: ref_clk %u\n", __func__, ref_clk);
 	return ref_clk;
 }
 
 /* Calculate clock frequency based on parameter */
-uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t mainpllc_reg,
+		      uint32_t perpllc_reg)
 {
-	uint32_t ref_clk = 0;
+	uint32_t clock = 0;
+	uint32_t clk_psrc;
 
-	uint32_t clk_psrc, mdiv;
-	uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+	/*
+	 * Select source for the active 5:1 clock selection when the PLL
+	 * is not bypassed
+	 */
+	clk_psrc = mmio_read_32(psrc_reg);
+	switch (GET_CLKMGR_CLKSRC(clk_psrc)) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+		clock /= (mmio_read_32(mainpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+		break;
 
+	case CLKMGR_CLKSRC_PER:
+		clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+		clock /= (mmio_read_32(perpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+		break;
 
-	clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
-	clk_psrc = 0;
+	case CLKMGR_CLKSRC_OSC1:
+		clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
+		break;
 
-	switch (clk_psrc) {
-	case 0:
-		pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
-		pllc_reg = CLKMGR_MAINPLL + main_pllc;
-		pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+	case CLKMGR_CLKSRC_INTOSC:
+		clock = CLKMGR_INTOSC_HZ;
+		break;
+
+	case CLKMGR_CLKSRC_FPGA:
+		clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
+		break;
+
+	default:
+		ERROR("CLKMGR: Invalid clock source select\n");
+		assert(0);
 		break;
 	}
 
-	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
-	mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
-	ref_clk *= mdiv;
+	VERBOSE("CLKMGR: %s: clock type %lu and its value %u\n",
+			__func__, GET_CLKMGR_CLKSRC(clk_psrc), clock);
 
-	pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
-	NOTICE("return = %d Hz\n", (ref_clk / pllc_div));
-
-	ref_clk = 200000000;
-	return (uint32_t) ref_clk;
-
+	return clock;
 }
 
-/* Return L3 interconnect clock */
-uint32_t get_l3_clk(void)
+/* Get L3 free clock */
+static uint32_t get_l3_main_free_clk(void)
 {
-	uint32_t l3_clk;
-
-	l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
-				CLKMGR_PERPLL_PLLC1);
-	return l3_clk;
+	return get_clk_freq(CLKMGR_MAINPLL(NOCCLK),
+			    CLKMGR_MAINPLL(PLLC3),
+			    CLKMGR_PERPLL(PLLC1));
 }
 
-/* Calculate clock frequency to be used for watchdog timer */
-uint32_t get_wdt_clk(void)
+/* Get L4 main clock */
+static uint32_t get_l4_main_clk(void)
 {
-	uint32_t l3_clk, l4_sys_clk;
-
-	l3_clk = get_l3_clk();
-	l4_sys_clk = l3_clk / 4;
-
-	return l4_sys_clk;
+	return get_l3_main_free_clk();
 }
 
-/* Calculate clock frequency to be used for UART driver */
-uint32_t get_uart_clk(void)
+/* Get L4 mp clock */
+static uint32_t get_l4_mp_clk(void)
 {
-	uint32_t data32, l3_clk, l4_sp_clk;
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4mp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4MP(
+					mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
 
-	l3_clk = get_l3_clk();
+	uint32_t l4_mp_clk = (l3_main_free_clk / mainpll_nocdiv_l4mp);
 
-	data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
-	data32 = (data32 >> 16) & 0x3;
+	return l4_mp_clk;
+}
 
-	l4_sp_clk = l3_clk >> data32;
+/* Get L4 sp clock */
+static uint32_t get_l4_sp_clk(void)
+{
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4sp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SP(
+					mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+
+	uint32_t l4_sp_clk = (l3_main_free_clk / mainpll_nocdiv_l4sp);
 
 	return l4_sp_clk;
 }
 
 /* Calculate clock frequency to be used for SDMMC driver */
-uint32_t get_mmc_clk(void)
+uint32_t get_sdmmc_clk(void)
 {
-	uint32_t mmc_clk;
+	uint32_t l4_mp_clk = get_l4_mp_clk();
+	uint32_t mainpll_nocdiv = mmio_read_32(CLKMGR_MAINPLL(NOCDIV));
+	uint32_t sdmmc_clk = l4_mp_clk / BIT(GET_CLKMGR_MAINPLL_NOCDIV_SPHY(mainpll_nocdiv));
 
-	//TODO: To update when handoff data is ready
-	//uint32_t data32;
+	return sdmmc_clk;
+}
 
-	//mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
+/* Get clock for ethernet mac0 */
+static uint32_t get_emaca_clk(void)
+{
+	uint32_t emaca_ctr = mmio_read_32(CLKMGR_ALTERA(EMACACTR));
+	uint32_t perpll_emacctl = mmio_read_32(CLKMGR_PERPLL(EMACCTL));
+	uint32_t perpll_emac_src = GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(perpll_emacctl);
+	uint32_t emac_ctr_reg;
+	uint32_t emac_clock;
 
-	//data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
-	//data32 = (data32 & 0x7ff) + 1;
-	//mmc_clk = (mmc_clk / data32) / 4;
+	if (perpll_emac_src != 0) {
+		emac_ctr_reg = CLKMGR_ALTERA(EMACBCTR);
+	} else {
+		emac_ctr_reg = CLKMGR_ALTERA(EMACACTR);
+	}
 
+	/* Get EMACA clock source */
+	uint32_t emacactr_src = GET_CLKMGR_EMACACTR_CLK_SRC(emaca_ctr);
 
-	mmc_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC3,
-				CLKMGR_PERPLL_PLLC3);
+	/* Read the desired EMAC register again */
+	emaca_ctr = mmio_read_32(emac_ctr_reg);
 
-	// TODO: To update when handoff data is ready
-	NOTICE("mmc_clk = %d Hz\n", mmc_clk);
+	/* Get the divider now */
+	uint32_t emaca_ctr_div = emaca_ctr & GENMASK(10, 0);
 
-	return mmc_clk;
+	switch (emacactr_src) {
+	case CLKMGR_CLKSRC_MAIN:
+		emac_clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+		emac_clock /= (mmio_read_32(CLKMGR_MAINPLL(PLLC1)) & GENMASK(10, 0));
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		emac_clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+		emac_clock /= (mmio_read_32(CLKMGR_PERPLL(PLLC3)) & GENMASK(10, 0));
+		break;
+
+	default:
+		ERROR("CLKMGR: %s invalid clock source\n", __func__);
+		emac_clock = 0;
+		return emac_clock;
+	}
+
+	emac_clock /= 1 + emaca_ctr_div;
+
+	return emac_clock;
+}
+
+/* Get MPU clock */
+static uint32_t get_mpu_clk(void)
+{
+	uint32_t cpu_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+	uint32_t ctr_reg = 0U;
+	uint32_t clock;
+
+	if (cpu_id > CLKMGR_ALTERA_CORE1) {
+		clock = get_clk_freq(CLKMGR_ALTERA(CORE23CTR),
+				     CLKMGR_MAINPLL(PLLC0),
+				     CLKMGR_PERPLL(PLLC0));
+	} else {
+		clock = get_clk_freq(CLKMGR_ALTERA(CORE01CTR),
+				     CLKMGR_MAINPLL(PLLC1),
+				     CLKMGR_PERPLL(PLLC0));
+	}
+
+	switch (cpu_id) {
+	case CLKMGR_ALTERA_CORE0:
+	case CLKMGR_ALTERA_CORE1:
+		ctr_reg = CLKMGR_ALTERA(CORE01CTR);
+		break;
+
+	case CLKMGR_ALTERA_CORE2:
+		ctr_reg = CLKMGR_ALTERA(CORE2CTR);
+		break;
+
+	case CLKMGR_ALTERA_CORE3:
+		ctr_reg = CLKMGR_ALTERA(CORE3CTR);
+		break;
+
+	default:
+		break;
+	}
+
+	/* Division setting for ping pong counter in clock slice */
+	clock /= 1 + (mmio_read_32(ctr_reg) & CLKMGR_PLLCX_DIV_MSK);
+
+	return clock;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+static uint32_t get_wdt_clk(void)
+{
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4sysfreeclk = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(
+						mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+	uint32_t l4_sys_free_clk = (l3_main_free_clk / mainpll_nocdiv_l4sysfreeclk);
+
+	return l4_sys_free_clk;
+}
+
+/*
+ * Calculate clock frequency to be used for UART driver.
+ * 'l4_sp_clk' (100MHz) will be used for slow peripherals like UART, I2C
+ * and Timers.
+ */
+static uint32_t get_uart_clk(void)
+{
+	return get_l4_sp_clk();
+}
+
+/* Return the clock value of a given system component */
+uint32_t clkmgr_get_rate(uint32_t clk_id)
+{
+	uint32_t clk_rate;
+
+	switch (clk_id) {
+	case CLKMGR_MPU_CLK_ID:
+		clk_rate = get_mpu_clk();
+		break;
+
+	case CLKMGR_L4_MAIN_CLK_ID:
+		clk_rate = get_l4_main_clk();
+		break;
+
+	case CLKMGR_L4_MP_CLK_ID:
+		clk_rate = get_l4_mp_clk();
+		break;
+
+	case CLKMGR_L4_SP_CLK_ID:
+		clk_rate = get_l4_sp_clk();
+		break;
+
+	case CLKMGR_EMAC0_CLK_ID:
+		clk_rate = get_emaca_clk();
+		break;
+
+	case CLKMGR_SDMMC_CLK_ID:
+		clk_rate = get_sdmmc_clk();
+		break;
+
+	case CLKMGR_UART_CLK_ID:
+		clk_rate = get_uart_clk();
+		break;
+
+	case CLKMGR_WDT_CLK_ID:
+		clk_rate = get_wdt_clk();
+		break;
+
+	default:
+		ERROR("CLKMGR: %s: Invalid clock ID\n", __func__);
+		clk_rate = 0;
+		break;
+	}
+
+	return clk_rate;
 }
 
 /* Return mpu_periph_clk tick */
diff --git a/plat/intel/soc/agilex5/soc/agilex5_ddr.c b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
new file mode 100644
index 0000000..ef2ae57
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include "lib/mmio.h"
+
+#include "agilex5_ddr.h"
+#include "agilex5_iossm_mailbox.h"
+
+/*
+ * TODO: We need to leverage the legacy products DDR drivers and consider
+ * the upcoming products like KM and then come up with common source code/driver
+ * architecture to address all the products in one view.
+ */
+
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK		GENMASK(31, 29)
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT		29
+#define SYSMGR_BS_COLD3_DDR_DBE_MASK			(1 << 1)
+#define SYSMGR_BS_COLD3_OCRAM_DBE_MASK			(1)
+#define SYSMGR_BS_POR0_DDR_PROGRESS_MASK		(1)
+
+/* MPFE NOC registers */
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0			0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0			0x54
+#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0			0x58
+
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS			0x18001000
+#define SOCFPGA_MPFE_SCR_IO96B0				0x18000D00
+#define SOCFPGA_MPFE_SCR_IO96B1				0x18000D04
+#define SOCFPGA_MPFE_NOC_SCHED_CSR			0x18000D08
+
+#define SIDEBANDMGR_FLAGOUTSET0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTSET0)
+#define SIDEBANDMGR_FLAGOUTSTATUS0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+F2SDRAM_SIDEBAND_FLAGOUTSTATUS0)
+#define SIDEBANDMGR_FLAGOUTCLR0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTCLR0)
+#define SZ_8						0x00000008
+
+
+/* Firewall MPU DDR SCR registers */
+#define FW_MPU_DDR_SCR_EN				0x00
+#define FW_MPU_DDR_SCR_EN_SET				0x04
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE		0x10
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT		0x14
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT		0x18
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT		0x1c
+
+#define SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS			0x18000800
+#define SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS			0x18000A00
+#define SOCFPGA_FW_TBU2NOC_ADDRESS			0x18000C00
+
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE		0x90
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT	0x94
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT		0x98
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT	0x9c
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD	0xff
+
+/* Firewall F2SDRAM DDR SCR registers */
+#define FW_F2SDRAM_DDR_SCR_EN				0x00
+#define FW_F2SDRAM_DDR_SCR_EN_SET			0x04
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE		0x10
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT		0x14
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT		0x18
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT		0x1c
+
+#define FW_MPU_DDR_SCR_WRITEL(data, reg)					\
+	do {									\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg), data);	\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg), data);	\
+	} while (0)
+
+#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg)				\
+	mmio_write_32(SOCFPGA_FW_TBU2NOC_ADDRESS + (reg), data)
+
+/* DDR banks info set */
+static struct ddr_info ddr_info_set[CONFIG_NR_DRAM_BANKS];
+
+/* Reset type */
+enum reset_type {
+	POR_RESET,
+	WARM_RESET,
+	COLD_RESET,
+	NCONFIG,
+	JTAG_CONFIG,
+	RSU_RECONFIG
+};
+
+/* Get reset type by reading boot scratch register cold3 */
+static inline enum reset_type get_reset_type(uint32_t sys_reg)
+{
+	return ((sys_reg & SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK) >>
+		 SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT);
+}
+
+/* DDR hang check before the reset */
+static inline bool is_ddr_init_hang(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+	if ((sys_reg & SYSMGR_BS_POR0_DDR_PROGRESS_MASK) != 0) {
+		INFO("DDR: Hang before this reset\n");
+		return true;
+	}
+
+	return false;
+}
+
+/* Set the DDR init progress bit */
+static inline void ddr_init_inprogress(bool start)
+{
+	if (start) {
+		mmio_setbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	} else {
+		mmio_clrbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	}
+}
+
+/* Configure the IO96B CSRs address based on the handoff data */
+static void config_io96b_csr_addr(bool is_dualemif, struct io96b_info *io96b_ctrl)
+{
+	if (is_dualemif)
+		io96b_ctrl->num_instance = 2;
+	else
+		io96b_ctrl->num_instance = 1;
+
+	/* Assign IO96B CSR base address if it is valid */
+	for (int i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			io96b_ctrl->io96b_0.io96b_csr_addr = 0x18400000;
+			INFO("DDR: IO96B0 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_0.io96b_csr_addr);
+			break;
+
+		case 1:
+			io96b_ctrl->io96b_1.io96b_csr_addr = 0x18800000;
+			INFO("DDR: IO96B1 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_1.io96b_csr_addr);
+			break;
+
+		default:
+			ERROR("%s: Invalid IO96B CSR\n", __func__);
+		} /* switch */
+	} /* for */
+}
+
+static inline bool hps_ocram_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_OCRAM_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static inline bool ddr_ecc_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_DDR_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static void sdram_set_firewall_non_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/*
+		 * Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting non-secure MPU region base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU region base and base extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure MPU limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU limit and limit extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		FW_MPU_DDR_SCR_WRITEL(BIT(i) | BIT(i + 8),
+				      FW_MPU_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/* Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		/* Setting limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(BIT(i), FW_F2SDRAM_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall(void)
+{
+	sdram_set_firewall_non_f2sdram();
+	sdram_set_firewall_f2sdram();
+}
+
+/*
+ * Agilex5 DDR/IOSSM controller initialization routine
+ */
+int agilex5_ddr_init(handoff *hoff_ptr)
+{
+	int ret;
+	bool full_mem_init = false;
+	phys_size_t hw_ddr_size;
+	phys_size_t config_ddr_size;
+	struct io96b_info io96b_ctrl;
+	enum reset_type reset_t = get_reset_type(mmio_read_32(SOCFPGA_SYSMGR(
+						BOOT_SCRATCH_COLD_3)));
+	bool is_dualport = hoff_ptr->ddr_config & BIT(0);
+	bool is_dualemif = hoff_ptr->ddr_config & BIT(1);
+
+	NOTICE("DDR: Reset type is '%s'\n",
+	       (reset_t == POR_RESET ? "Power-On" : (reset_t == COLD_RESET ? "Cold" : "Warm")));
+
+	/* DDR initialization progress status tracking */
+	bool is_ddr_hang_bfr_rst = is_ddr_init_hang();
+
+	/* Set the DDR initialization progress */
+	ddr_init_inprogress(true);
+
+	/* Configure the IO96B CSR address based on the handoff data */
+	config_io96b_csr_addr(is_dualemif, &io96b_ctrl);
+
+	/* Configuring MPFE sideband manager registers */
+	/* Dual port setting */
+	if (is_dualport)
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(4));
+
+	/* Dual EMIF setting */
+	if (is_dualemif) {
+		/* Set mpfe_lite_active in the system manager */
+		/* TODO: recheck on the bit value?? */
+		mmio_setbits_32(SOCFPGA_SYSMGR(MPFE_CONFIG), BIT(8));
+
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(5));
+	}
+
+	if (is_dualport || is_dualemif)
+		INFO("DDR: SIDEBANDMGR_FLAGOUTSTATUS0: 0x%x\n",
+		     mmio_read_32(SIDEBANDMGR_FLAGOUTSTATUS0_REG));
+
+	/* Ensure calibration status passing */
+	init_mem_cal(&io96b_ctrl);
+
+	/* Initiate IOSSM mailbox */
+	io96b_mb_init(&io96b_ctrl);
+
+	/* Need to trigger re-calibration for DDR DBE */
+	if (ddr_ecc_dbe_status()) {
+		io96b_ctrl.io96b_0.cal_status = false;
+		io96b_ctrl.io96b_1.cal_status = false;
+		io96b_ctrl.overall_cal_status = io96b_ctrl.io96b_0.cal_status ||
+						io96b_ctrl.io96b_1.cal_status;
+	}
+
+	/* Trigger re-calibration if calibration failed */
+	if (!(io96b_ctrl.overall_cal_status)) {
+		NOTICE("DDR: Re-calibration in progress...\n");
+		trig_mem_cal(&io96b_ctrl);
+	}
+	NOTICE("DDR: Calibration success\n");
+
+	/* DDR type, DDR size and ECC status) */
+	ret = get_mem_technology(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR type\n");
+		return ret;
+	}
+
+	ret = get_mem_width_info(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR size\n");
+		return ret;
+	}
+
+	/* DDR size queried from the IOSSM controller */
+	hw_ddr_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
+
+	/* TODO: Hard code 1GB as of now, and DDR start and end address */
+	config_ddr_size = 0x40000000;
+	ddr_info_set[0].start = 0x80000000;
+	ddr_info_set[0].size = 0x40000000;
+
+	if (config_ddr_size != hw_ddr_size) {
+		WARN("DDR: DDR size configured is (%lld MiB)\n", config_ddr_size >> 20);
+		WARN("DDR: Mismatch with hardware size (%lld MiB).\n", hw_ddr_size >> 20);
+	}
+
+	if (config_ddr_size > hw_ddr_size) {
+		ERROR("DDR: Confgured DDR size is greater than the hardware size - HANG!!!\n");
+		while (1)
+			;
+	}
+
+	ret = ecc_enable_status(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR ECC status\n");
+		return ret;
+	}
+
+	/*
+	 * HPS cold or warm reset? If yes, skip full memory initialization if
+	 * ECC is enabled to preserve memory content.
+	 */
+	if (io96b_ctrl.ecc_status != 0) {
+		full_mem_init = hps_ocram_dbe_status() | ddr_ecc_dbe_status() |
+				is_ddr_hang_bfr_rst;
+		if ((full_mem_init == true) || (reset_t == WARM_RESET ||
+			reset_t == COLD_RESET) == 0) {
+			ret = bist_mem_init_start(&io96b_ctrl);
+			if (ret != 0) {
+				ERROR("DDR: Failed to fully initialize DDR memory\n");
+				return ret;
+			}
+		}
+		INFO("DDR: ECC initialized successfully\n");
+	}
+
+	sdram_set_firewall();
+
+	/*
+	 * Firewall setting for MPFE CSRs, allow both secure and non-secure
+	 * transactions.
+	 */
+	/* IO96B0_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B0, BIT(0));
+	/* IO96B1_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B1, BIT(0));
+	/* noc_scheduler_csr */
+	mmio_setbits_32(SOCFPGA_MPFE_NOC_SCHED_CSR, BIT(0));
+
+	INFO("DDR: firewall init done\n");
+
+	/* Ending DDR driver initialization success tracking */
+	ddr_init_inprogress(false);
+
+	NOTICE("###DDR:init success###\n");
+
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
new file mode 100644
index 0000000..c2ab047
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include "agilex5_iossm_mailbox.h"
+
+/* supported DDR type list */
+static const char *ddr_type_list[7] = {
+	"DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
+};
+
+static inline int wait_for_bit(const void *reg,
+			       const uint32_t mask,
+			       const bool set,
+			       const unsigned int timeout_ms)
+{
+	uint32_t val;
+	uint32_t timeout_sec = (timeout_ms / 1000);
+
+	while (timeout_sec > 0) {
+		val = mmio_read_32((uintptr_t)reg);
+
+		INFO("IOSSM: timeout_sec %d, val %x\n", timeout_sec, val);
+
+		if (!set) {
+			val = ~val;
+		}
+
+		if ((val & mask) == mask) {
+			INFO("IOSSM: %s, success\n", __func__);
+			return 0;
+		}
+
+		/* one second delay */
+		mdelay(1000);
+
+		timeout_sec--;
+	}
+
+	ERROR("IOSSM: %s, failed, time out\n", __func__);
+	return -ETIMEDOUT;
+}
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp)
+{
+	int i;
+	int ret;
+	uint32_t cmd_req, cmd_resp;
+
+	/* Initialized zeros for responses*/
+	resp->cmd_resp_status = 0;
+	resp->cmd_resp_data_0 = 0;
+	resp->cmd_resp_data_1 = 0;
+	resp->cmd_resp_data_2 = 0;
+
+	/* Ensure CMD_REQ is cleared before write any command request */
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET),
+			   GENMASK(31, 0), 0, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_REQ not ready\n", __func__);
+		return -1;
+	}
+
+	/* Write CMD_PARAM_* */
+	for (i = 0; i < 6 ; i++) {
+		switch (i) {
+		case 0:
+			if (cmd_param_0 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET,
+					      cmd_param_0);
+			}
+			break;
+		case 1:
+			if (cmd_param_1 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET,
+					      cmd_param_1);
+			}
+			break;
+		case 2:
+			if (cmd_param_2 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET,
+					      cmd_param_2);
+			}
+			break;
+		case 3:
+			if (cmd_param_3 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET,
+					      cmd_param_3);
+			}
+			break;
+		case 4:
+			if (cmd_param_4 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET,
+					      cmd_param_4);
+			}
+			break;
+		case 5:
+			if (cmd_param_5 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET,
+					      cmd_param_5);
+			}
+			break;
+		case 6:
+			if (cmd_param_6 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET,
+					      cmd_param_6);
+			}
+			break;
+		default:
+			ERROR("IOSSM: %s: Invalid command parameter\n", __func__);
+		}
+	}
+
+	/* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
+	cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
+		  (ip_type << 29);
+	mmio_write_32(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET, cmd_req);
+	INFO("IOSSM: %s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n",
+		__func__, cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+
+	/* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
+			   IOSSM_STATUS_COMMAND_RESPONSE_READY, 1, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_RESPONSE ERROR:\n", __func__);
+		cmd_resp = (io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+		ERROR("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
+		ERROR("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
+	}
+
+	/* read CMD_RESPONSE_STATUS*/
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* read CMD_RESPONSE_DATA_* */
+	for (i = 0; i < resp_data_len; i++) {
+		switch (i) {
+		case 0:
+			resp->cmd_resp_data_0 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
+
+			break;
+		case 1:
+			resp->cmd_resp_data_1 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
+
+			break;
+		case 2:
+			resp->cmd_resp_data_2 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
+			break;
+		default:
+			ERROR("%s: Invalid response data\n", __func__);
+		}
+	}
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* write CMD_RESPONSE_READY = 0 */
+	mmio_clrbits_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET,
+			IOSSM_STATUS_COMMAND_RESPONSE_READY);
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_READY 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	return 0;
+}
+
+/*
+ * Initial function to be called to set memory interface IP type and instance ID
+ * IP type and instance ID need to be determined before sending mailbox command
+ */
+void io96b_mb_init(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	uint8_t ip_type_ret, instance_id_ret;
+	int i, j, k;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			/* Get memory interface IP type & instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+				     CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, 0, 0,
+				     0, 0, 0, 0, 0, 2, &usr_resp);
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_0.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		case 1:
+			/* Get memory interface IP type and instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0, CMD_GET_SYS_INFO,
+				     GET_MEM_INTF_INFO, 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_1.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		}
+
+	}
+}
+
+static inline void hang(void)
+{
+	ERROR("IOSSM: %s: system is going to die :(\n", __func__);
+	while (1)
+		;
+}
+
+int io96b_cal_status(phys_addr_t addr)
+{
+	int cal_busy_status, cal_success_status;
+	phys_addr_t status_addr = addr + IOSSM_STATUS_OFFSET;
+
+	/* Ensure calibration busy status */
+	cal_busy_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_BUSY,
+					false, 15000);
+	if (cal_busy_status != 0) {
+		ERROR("IOSSM: One or more EMIF instances are busy with calibration\n");
+		return -EBUSY;
+	}
+
+	/* Calibration success status check */
+	NOTICE("IOSSM: Calibration success status check...\n");
+	cal_success_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_SUCCESS,
+					  true, 15000);
+	if (cal_success_status != 0) {
+		ERROR("IOSSM: One/more EMIF instances either failed to calibrate/not completed\n");
+		return -EBUSY;
+	}
+
+	NOTICE("IOSSM: All EMIF instances within the IO96 have calibrated successfully!\n");
+	return 0;
+}
+
+void init_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	int count, i, ret;
+
+	/* Initialize overall calibration status */
+	io96b_ctrl->overall_cal_status = false;
+
+	/* Check initial calibration status for the assigned IO96B */
+	count = 0;
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			ret = io96b_cal_status(io96b_ctrl->io96b_0.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_0.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_0 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_0.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_0 succeed\n", __func__);
+			count++;
+			break;
+		case 1:
+			ret = io96b_cal_status(io96b_ctrl->io96b_1.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_1.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_1 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_1.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_1 succeed\n", __func__);
+			count++;
+			break;
+		}
+	}
+
+	if (count == io96b_ctrl->num_instance)
+		io96b_ctrl->overall_cal_status = true;
+}
+
+/*
+ * Trying 3 times re-calibration if initial calibration failed
+ */
+int trig_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	bool recal_success;
+	int i;
+	uint8_t cal_stat;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			if (!(io96b_ctrl->io96b_0.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("%s: Error as SDRAM calibration failed\n", __func__);
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_1 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSMM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_0.cal_status = true;
+			}
+			break;
+		case 1:
+			if (!(io96b_ctrl->io96b_1.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_1.cal_status = true;
+			}
+			break;
+		}
+	}
+
+	if (io96b_ctrl->io96b_0.cal_status && io96b_ctrl->io96b_1.cal_status) {
+		INFO("IOSSM: %s: Overall SDRAM calibration success\n", __func__);
+		io96b_ctrl->overall_cal_status = true;
+	}
+
+	return 0;
+}
+
+int get_mem_technology(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint8_t ddr_type_ret;
+
+	/* Initialize ddr type */
+	io96b_ctrl->ddr_type = ddr_type_list[6];
+
+	/* Get and ensure all memory interface(s) same DDR type */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0, 0,
+					     0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_0\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0,
+					     0, 0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_1\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int get_mem_width_info(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint16_t memory_size = 0U;
+	uint16_t total_memory_size = 0U;
+
+	/* Get all memory interface(s) total memory size on all instance(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_0.size = memory_size;
+
+			break;
+		case 1:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_1.size = memory_size;
+
+			break;
+		}
+
+		total_memory_size = total_memory_size + memory_size;
+	}
+
+	if (total_memory_size == 0U) {
+		ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+		return -ENOEXEC;
+	}
+
+	io96b_ctrl->overall_size = total_memory_size;
+
+	return 0;
+}
+
+int ecc_enable_status(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool ecc_stat_set = false;
+	bool ecc_stat;
+
+	/* Initialize ECC status */
+	io96b_ctrl->ecc_status = false;
+
+	/* Get and ensure all memory interface(s) same ECC status */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("IOSSM: %s: Mismatch DDR ECC status on IO96B_0\n",
+						__func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("%s: Mismatch DDR ECC status on IO96B_1\n"
+						, __func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+	return 0;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool bist_start, bist_success;
+	uint32_t read_count;
+	uint32_t read_interval_ms;
+
+	/* Full memory initialization BIST performed on all memory interface(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_0\n"
+					, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_0\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS Err code%x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_0\n", __func__);
+			break;
+
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_1\n"
+						, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_1\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS ErrCode %x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_1\n", __func__);
+			break;
+		}
+	}
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
index 50d9e36..317b4d8 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -186,40 +187,72 @@
 	0x0000011c, 0x00000000
 };
 
-void config_fpgaintf_mod(void)
+static void config_fpgaintf_mod(void)
 {
-	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+	uint32_t fpgaintf_en_val;
+
+	/*
+	 * System manager FPGA interface enable2 register, disable individual
+	 * interfaces between the FPGA and HPS.
+	 */
+	fpgaintf_en_val = 0U;
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(NAND_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(4);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SDMMC_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(8);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM0_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(16);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM1_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(24);
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), fpgaintf_en_val);
+
+	/*
+	 * System manager FPGA interface enable3 register, disable individual
+	 * interfaces between the FPGA and HPS.
+	 */
+	fpgaintf_en_val = 0U;
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC0_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(0);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC1_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(8);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC2_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(16);
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), fpgaintf_en_val);
 }
 
 void config_pinmux(handoff *hoff_ptr)
 {
-	unsigned int i;
+	uint32_t i;
 
-	mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
-	for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
-		mmio_write_32(AGX5_PINMUX_PIN0SEL +
-			hoff_ptr->pinmux_sel_array[i],
-			hoff_ptr->pinmux_sel_array[i + 1]);
+	/* Configure the pin selection */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_PIN0SEL + hoff_ptr->pinmux_sel_array[i],
+			      hoff_ptr->pinmux_sel_array[i+1]);
 	}
 
+	/* Configure the pin control */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_io_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_IO0CTRL + hoff_ptr->pinmux_io_array[i],
+			      hoff_ptr->pinmux_io_array[i+1]);
+	}
+
+	/*
+	 * Configure the FPGA use.
+	 * The actual generic handoff contains extra 4 elements, and these 4 elements
+	 * are not applicable to the Agilex5 platform. Writing these extra 4 elements
+	 * will cause the system to crash, so let's avoid writing them here.
+	 */
+	for (i = 0; i < (ARRAY_SIZE(hoff_ptr->pinmux_fpga_array) - 4); i += 2) {
+		mmio_write_32(AGX5_PINMUX_EMAC0_USEFPGA + hoff_ptr->pinmux_fpga_array[i],
+			      hoff_ptr->pinmux_fpga_array[i+1]);
+	}
+
+	/* Configure the IO delay */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_iodelay_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_IO0_DELAY + hoff_ptr->pinmux_iodelay_array[i],
+			      hoff_ptr->pinmux_iodelay_array[i+1]);
+	}
+
+	/* Enable/Disable individual interfaces between the FPGA and HPS */
 	config_fpgaintf_mod();
 }
-
-void config_peripheral(handoff *hoff_ptr)
-{
-
-	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
-	// Pending SDM to pass over handoff data
-	// unsigned int i;
-
-	// for (i = 0; i < 4; i += 2) {
-	//	mmio_write_32(AGX_EDGE_PERIPHERAL +
-	//	hoff_ptr->peripheral_pwr_gate_array[i],
-	//	hoff_ptr->peripheral_pwr_gate_array[i+1]);
-	// }
-
-
-	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
-	mmio_write_32(AGX5_PERIPHERAL,
-	hoff_ptr->peripheral_pwr_gate_array);
-}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
index 0d81970..ef3acf9 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +14,7 @@
 #include "agilex5_power_manager.h"
 #include "socfpga_reset_manager.h"
 
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
+static int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
 {
 	uint32_t data = 0;
 	uint32_t count = 0;
@@ -38,7 +39,7 @@
 	return 0;
 }
 
-int pss_sram_power_off(handoff *hoff_ptr)
+static int pss_sram_power_off(handoff *hoff_ptr)
 {
 	int ret = 0;
 	uint32_t peripheral_handoff = 0;
@@ -66,7 +67,7 @@
 {
 	int ret = 0;
 
-	switch (hoff_ptr->header_magic) {
+	switch (hoff_ptr->peripheral_pwr_gate_magic) {
 	case HANDOFF_MAGIC_PERIPHERAL:
 		ret = pss_sram_power_off(hoff_ptr);
 		break;
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index cbd0121..b3d5665 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,18 +98,6 @@
 endfunc plat_my_core_pos
 
 func warm_reset_req
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	bl	plat_is_my_cpu_primary
-	cbnz	x0, warm_reset
-warm_reset:
-	mov_imm x1, PLAT_SEC_ENTRY
-	str	xzr, [x1]
-	mrs	x1, rmr_el3
-	orr	x1, x1, #0x02
-	msr	rmr_el3, x1
-	isb
-	dsb	sy
-#else
 	str	xzr, [x4]
 	bl	plat_is_my_cpu_primary
 	cbz	x0, cpu_in_wfi
@@ -121,22 +111,35 @@
 cpu_in_wfi:
 	wfi
 	b	cpu_in_wfi
-#endif
 endfunc warm_reset_req
 
-/* TODO: Zephyr warm reset test */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
 	ldr	x5, [x4]
-	ldr	x1, =PLAT_L2_RESET_REQ
+
+	/* Check for warm reset request */
+	ldr	x1, =L2_RESET_DONE_STATUS
 	cmp	x1, x5
-	b.eq	zephyr_reset_req
+	b.eq	warm_reset_req
+
+	/* Check for SMP secondary cores boot request */
+	ldr	x1, =SMP_SEC_CORE_BOOT_REQ
+	cmp	x1, x5
+	b.eq	smp_request
+
+	/* Otherwise it is cold reset */
+	mov	x0, #0
+	ret
+smp_request:
+	/*
+	 * Return the address 'bl31_warm_entrypoint', which is passed to
+	 * 'psci_setup' routine as part of BL31 initialization.
+	 */
 	mov_imm	x1, PLAT_SEC_ENTRY
 	ldr	x0, [x1]
-	ret
-zephyr_reset_req:
-	ldr	x0, =0x00
+	/* Clear the mark up before return */
+	str	xzr, [x4]
 	ret
 endfunc plat_get_my_entrypoint
 #else
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index ca76b6a..931ffcf 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -1,10 +1,12 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <assert.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
 #include <errno.h>
 #include <lib/mmio.h>
 #include <platform_def.h>
@@ -16,7 +18,24 @@
 
 uint32_t poll_active_bit(uint32_t dir);
 
-#define SMMU_DMI			1
+#define SMMU_DMI					1
+#define CCU_DMI0_DMIUSMCMCR				SOCFPGA_CCU_NOC_REG_BASE + 0x7340
+#define CCU_DMI0_DMIUSMCMAR				SOCFPGA_CCU_NOC_REG_BASE + 0x7344
+#define CCU_DMI0_DMIUSMCMCR_MNTOP			GENMASK(3, 0)
+#define MAX_DISTRIBUTED_MEM_INTERFACE			2
+#define FLUSH_ALL_ENTRIES				0x4
+#define CCU_DMI0_DMIUSMCMCR_ARRAY_ID			GENMASK(21, 16)
+#define ARRAY_ID_TAG					0x0
+#define ARRAY_ID_DATA					0x1
+#define CACHE_OPERATION_DONE				BIT(0)
+#define TIMEOUT_200MS					200
+
+#define __bf_shf(x)					(__builtin_ffsll(x) - 1)
+
+#define FIELD_PREP(_mask, _val)						\
+	({ \
+		((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);	\
+	})
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 ncore_ccu_reg_t ncore_ccu_modules[] = {
@@ -632,3 +651,61 @@
 	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN1), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN2), ENABLE_STREAMID);
 }
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+/* TODO: Temp added this here*/
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
+{
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int flush_l3_dcache(void)
+{
+	int i;
+	int ret = 0;
+
+	/* Flushing all entries in CCU system memory cache */
+	for (i = 0; i < MAX_DISTRIBUTED_MEM_INTERFACE; i++) {
+		mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+			   FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_TAG),
+			   (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+		/* Wait for cache maintenance operation done */
+		ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+				(i * 0x1000)), CACHE_OPERATION_DONE,
+				CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+		if (ret != 0) {
+			VERBOSE("%s: Timeout while waiting for flushing tag in DMI%d done\n",
+					__func__, i);
+			return ret;
+		}
+
+		mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+			   FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_DATA),
+			   (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+		/* Wait for cache maintenance operation done */
+		ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+				(i * 0x1000)), CACHE_OPERATION_DONE,
+				CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+		if (ret != 0) {
+			VERBOSE("%s: Timeout while waiting for flushing data in DMI%d done\n",
+					__func__, i);
+		}
+	}
+
+	return ret;
+}
+#endif
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index e00c4b7..a89c098 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -452,5 +453,6 @@
 uint32_t init_ncore_ccu(void);
 void ncore_enable_ocram_firewall(void);
 void setup_smmu_stream_id(void);
+int flush_l3_dcache(void);
 
 #endif
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
index 48f91eb..62698a9 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -18,53 +18,26 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-#include "agilex5_pinmux.h"
 #include "sdmmc.h"
 #include "socfpga_mailbox.h"
+#include "wdt/watchdog.h"
 
 static const struct mmc_ops *ops;
 static unsigned int mmc_ocr_value;
-static struct mmc_csd_emmc mmc_csd;
-static struct sd_switch_status sd_switch_func_status;
-static unsigned char mmc_ext_csd[512] __aligned(16);
 static unsigned int mmc_flags;
-static struct mmc_device_info *mmc_dev_info;
 static unsigned int rca;
-static unsigned int scr[2]__aligned(16) = { 0 };
 
 extern const struct mmc_ops cdns_sdmmc_ops;
 extern struct cdns_sdmmc_params cdns_params;
 extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
 extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
 
-static bool is_cmd23_enabled(void)
+bool is_cmd23_enabled(void)
 {
 	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
 }
 
-static bool is_sd_cmd6_enabled(void)
-{
-	return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
-}
-
-/* TODO: Will romove once ATF driver is developed */
-void sdmmc_pin_config(void)
-{
-	/* temp use base + addr. Official must change to common method */
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
-}
-
-static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
 			unsigned int r_type, unsigned int *r_data)
 {
 	struct mmc_cmd cmd;
@@ -94,7 +67,7 @@
 	return ret;
 }
 
-static int sdmmc_device_state(void)
+int sdmmc_device_state(void)
 {
 	int retries = DEFAULT_SDMMC_MAX_RETRIES;
 	unsigned int resp_data[4];
@@ -125,521 +98,12 @@
 	return MMC_GET_STATE(resp_data[0]);
 }
 
-static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
-{
-	int ret;
-
-	ret = sdmmc_send_cmd(MMC_CMD(6),
-			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
-			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
-			   MMC_RESPONSE_R1B, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret == MMC_STATE_PRG);
-
-	return 0;
-}
-
-static int sdmmc_mmc_sd_switch(unsigned int bus_width)
-{
-	int ret;
-	int retries = DEFAULT_SDMMC_MAX_RETRIES;
-	unsigned int bus_width_arg = 0;
-
-	/* CMD55: Application Specific Command */
-	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R5, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* ACMD51: SEND_SCR */
-	do {
-		ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
-		if ((ret != 0) && (retries == 0)) {
-			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
-			      DEFAULT_SDMMC_MAX_RETRIES, ret);
-			return ret;
-		}
-
-		retries--;
-	} while (ret != 0);
-
-	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
-	    (bus_width == MMC_BUS_WIDTH_4)) {
-		bus_width_arg = 2;
-	}
-
-	/* CMD55: Application Specific Command */
-	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R5, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* ACMD6: SET_BUS_WIDTH */
-	ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret == MMC_STATE_PRG);
-
-	return 0;
-}
-
-static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
-{
-	int ret;
-	unsigned int width = bus_width;
-
-	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
-		if (width == MMC_BUS_WIDTH_8) {
-			WARN("Wrong bus config for SD-card, force to 4\n");
-			width = MMC_BUS_WIDTH_4;
-		}
-		ret = sdmmc_mmc_sd_switch(width);
-		if (ret != 0) {
-			return ret;
-		}
-	} else if (mmc_csd.spec_vers == 4U) {
-		ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
-				      (unsigned int)width);
-		if (ret != 0) {
-			return ret;
-		}
-	} else {
-		VERBOSE("Wrong MMC type or spec version\n");
-	}
-
-	return ops->set_ios(clk, width);
-}
-
-static int sdmmc_fill_device_info(void)
-{
-	unsigned long long c_size;
-	unsigned int speed_idx;
-	unsigned int nb_blocks;
-	unsigned int freq_unit;
-	int ret = 0;
-	struct mmc_csd_sd_v2 *csd_sd_v2;
-
-	switch (mmc_dev_info->mmc_dev_type) {
-	case MMC_IS_EMMC:
-		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
-		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
-				   sizeof(mmc_ext_csd));
-		if (ret != 0) {
-			return ret;
-		}
-
-		/* MMC CMD8: SEND_EXT_CSD */
-		ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-
-		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
-				sizeof(mmc_ext_csd));
-		if (ret != 0) {
-			return ret;
-		}
-
-		do {
-			ret = sdmmc_device_state();
-			if (ret < 0) {
-				return ret;
-			}
-		} while (ret != MMC_STATE_TRAN);
-
-		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
-
-		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
-			mmc_dev_info->block_size;
-
-		break;
-
-	case MMC_IS_SD:
-		/*
-		 * Use the same mmc_csd struct, as required fields here
-		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
-		 */
-		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
-
-		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
-			 (unsigned long long)mmc_csd.c_size_low;
-		assert(c_size != 0xFFFU);
-
-		mmc_dev_info->device_size = (c_size + 1U) *
-					    BIT_64(mmc_csd.c_size_mult + 2U) *
-					    mmc_dev_info->block_size;
-
-		break;
-
-	case MMC_IS_SD_HC:
-		assert(mmc_csd.csd_structure == 1U);
-
-		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
-		/* Need to use mmc_csd_sd_v2 struct */
-		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
-		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
-			 (unsigned long long)csd_sd_v2->c_size_low;
-
-		mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
-
-		break;
-
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	if (ret < 0) {
-		return ret;
-	}
-
-	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
-			 CSD_TRAN_SPEED_MULT_SHIFT;
-
-	assert(speed_idx > 0U);
-
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
-	} else {
-		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
-	}
-
-	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
-	while (freq_unit != 0U) {
-		mmc_dev_info->max_bus_freq *= 10U;
-		--freq_unit;
-	}
-
-	mmc_dev_info->max_bus_freq *= 10000U;
-
-	return 0;
-}
-
-static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
-		     unsigned char func)
-{
-	unsigned int group_shift = (group - 1U) * 4U;
-	unsigned int group_mask = GENMASK(group_shift + 3U,  group_shift);
-	unsigned int arg;
-	int ret;
-
-	ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
-			   sizeof(sd_switch_func_status));
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* MMC CMD6: SWITCH_FUNC */
-	arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
-	arg &= ~group_mask;
-	arg |= func << group_shift;
-	ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	return ops->read(0, (uintptr_t)&sd_switch_func_status,
-			 sizeof(sd_switch_func_status));
-}
-
-static int sdmmc_sd_send_op_cond(void)
-{
-	int n;
-	unsigned int resp_data[4];
-
-	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
-		int ret;
-
-		/* CMD55: Application Specific Command */
-		ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-
-		/* ACMD41: SD_SEND_OP_COND */
-		ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
-			mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
-			&resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((resp_data[0] & OCR_POWERUP) != 0U) {
-			mmc_ocr_value = resp_data[0];
-
-			if ((mmc_ocr_value & OCR_HCS) != 0U) {
-				mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
-			} else {
-				mmc_dev_info->mmc_dev_type = MMC_IS_SD;
-			}
-
-			return 0;
-		}
-
-		mdelay(10);
-	}
-
-	ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
-	return -EIO;
-}
-
-static int sdmmc_reset_to_idle(void)
-{
-	int ret;
-
-	/* CMD0: reset to IDLE */
-	ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	mdelay(2);
-
-	return 0;
-}
-
-static int sdmmc_send_op_cond(void)
-{
-	int ret, n;
-	unsigned int resp_data[4];
-
-	ret = sdmmc_reset_to_idle();
-	if (ret != 0) {
-		return ret;
-	}
-
-	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
-		ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
-				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
-				   MMC_RESPONSE_R3, &resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((resp_data[0] & OCR_POWERUP) != 0U) {
-			mmc_ocr_value = resp_data[0];
-			return 0;
-		}
-
-		mdelay(10);
-	}
-
-	ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
-	return -EIO;
-}
-
-static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
-{
-	int ret;
-	unsigned int resp_data[4];
-
-	ops->init();
-
-	ret = sdmmc_reset_to_idle();
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		ret = sdmmc_send_op_cond();
-	} else {
-		/* CMD8: Send Interface Condition Command */
-		ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
-				   MMC_RESPONSE_R5, &resp_data[0]);
-
-		if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
-			ret = sdmmc_sd_send_op_cond();
-		}
-	}
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* CMD2: Card Identification */
-	ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* CMD3: Set Relative Address */
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		rca = MMC_FIX_RCA;
-		ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
-				   MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-	} else {
-		ret = sdmmc_send_cmd(MMC_CMD(3), 0,
-				   MMC_RESPONSE_R6, &resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
-	}
-
-	/* CMD9: CSD Register */
-	ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R2, &resp_data[0]);
-	if (ret != 0) {
-		return ret;
-	}
-
-	memcpy_s(&mmc_csd, sizeof(mmc_csd) / MBOX_WORD_BYTE,
-		&resp_data, sizeof(resp_data) / MBOX_WORD_BYTE);
-
-	/* CMD7: Select Card */
-	ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret != MMC_STATE_TRAN);
-
-	ret = sdmmc_set_ios(clk, bus_width);
-	if (ret != 0) {
-		return ret;
-	}
-
-	ret = sdmmc_fill_device_info();
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (is_sd_cmd6_enabled() &&
-	    (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
-		/* Try to switch to High Speed Mode */
-		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
-			/* High speed not supported, keep default speed */
-			return 0;
-		}
-
-		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
-			/* Cannot switch to high speed, keep default speed */
-			return 0;
-		}
-
-		mmc_dev_info->max_bus_freq = 50000000U;
-		ret = ops->set_ios(clk, bus_width);
-	}
-
-	return ret;
-}
-
 size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
 {
-	int ret;
-	unsigned int cmd_idx, cmd_arg;
+	mmc_read_blocks(lba, buf, size);
 
-	assert((ops != NULL) &&
-	       (ops->read != NULL) &&
-	       (size != 0U) &&
-	       ((size & MMC_BLOCK_MASK) == 0U));
-
-	ret = ops->prepare(lba, buf, size);
-	if (ret != 0) {
-		return 0;
-	}
-
-	if (is_cmd23_enabled()) {
-		/* Set block count */
-		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
-				   MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return 0;
-		}
-
-		cmd_idx = MMC_CMD(18);
-	} else {
-		if (size > MMC_BLOCK_SIZE) {
-			cmd_idx = MMC_CMD(18);
-		} else {
-			cmd_idx = MMC_CMD(17);
-		}
-	}
-
-	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
-	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
-		cmd_arg = lba * MMC_BLOCK_SIZE;
-	} else {
-		cmd_arg = lba;
-	}
-
-	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return 0;
-	}
-
-	ret = ops->read(lba, buf, size);
-	if (ret != 0) {
-		return 0;
-	}
-
-	/* Wait buffer empty */
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return 0;
-		}
-	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
-
-	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
-		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
-		if (ret != 0) {
-			return 0;
-		}
-	}
+	/* Restart watchdog for reading each chunk byte */
+	watchdog_sw_rst();
 
 	return size;
 }
@@ -710,64 +174,3 @@
 
 	return size;
 }
-
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
-	     unsigned int width, unsigned int flags,
-	     struct mmc_device_info *device_info)
-{
-	assert((ops_ptr != NULL) &&
-	       (ops_ptr->init != NULL) &&
-	       (ops_ptr->send_cmd != NULL) &&
-	       (ops_ptr->set_ios != NULL) &&
-	       (ops_ptr->prepare != NULL) &&
-	       (ops_ptr->read != NULL) &&
-	       (ops_ptr->write != NULL) &&
-	       (device_info != NULL) &&
-	       (clk != 0) &&
-	       ((width == MMC_BUS_WIDTH_1) ||
-		(width == MMC_BUS_WIDTH_4) ||
-		(width == MMC_BUS_WIDTH_8) ||
-		(width == MMC_BUS_WIDTH_DDR_4) ||
-		(width == MMC_BUS_WIDTH_DDR_8)));
-
-	ops = ops_ptr;
-	mmc_flags = flags;
-	mmc_dev_info = device_info;
-
-	return sdmmc_enumerate(clk, width);
-}
-
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
-{
-	int result = 0;
-
-	/* SDMMC pin mux configuration */
-	sdmmc_pin_config();
-	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (result < 0) {
-		return result;
-	}
-
-	assert((params != NULL) &&
-	       ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
-	       ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
-	       ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
-		   ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
-		   ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
-	       (params->desc_size > 0) &&
-	       (params->clk_rate > 0) &&
-	       ((params->bus_width == MMC_BUS_WIDTH_1) ||
-		(params->bus_width == MMC_BUS_WIDTH_4) ||
-		(params->bus_width == MMC_BUS_WIDTH_8)));
-
-	memcpy_s(&cdns_params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE,
-		params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE);
-	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
-	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
-
-	result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
-		params->flags, info);
-
-	return result;
-}
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
index 16c6b04..3f6119c 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,10 +34,12 @@
  * @hoff_ptr: Pointer to the hand-off data
  * Return: 0 on success, a negative errno on failure
  */
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params,
-	     struct mmc_device_info *info);
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
-	     unsigned int width, unsigned int flags,
-	     struct mmc_device_info *device_info);
 void sdmmc_pin_config(void);
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+int sdmmc_device_state(void);
+bool is_cmd23_enabled(void);
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+			unsigned int r_type, unsigned int *r_data);
+
 #endif
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 1946898..a820e41 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +22,18 @@
 #define PLAT_SOCFPGA_AGILEX5			4
 #define SIMICS_RUN				1
 #define MAX_IO_MTD_DEVICES			U(1)
+/* Boot Source configuration
+ * TODO: Shall consider "assert_numeric" in the future
+ */
+#if SOCFPGA_BOOT_SOURCE_NAND
+#define BOOT_SOURCE						BOOT_SOURCE_NAND
+#elif SOCFPGA_BOOT_SOURCE_SDMMC
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#elif SOCFPGA_BOOT_SOURCE_QSPI
+#define BOOT_SOURCE						BOOT_SOURCE_QSPI
+#else
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#endif
 
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
@@ -28,26 +41,26 @@
 /* Magic word to indicate L2 reset is completed */
 #define L2_RESET_DONE_STATUS			0x1228E5E7
 
+/* Magic word to differentiate for SMP secondary core boot request */
+#define SMP_SEC_CORE_BOOT_REQ			0x1228E5E8
+
 /* Define next boot image name and offset */
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
-#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-
-#ifndef PRELOADED_BL33_BASE
+#ifdef PRELOADED_BL33_BASE
+#define PLAT_NS_IMAGE_OFFSET			PRELOADED_BL33_BASE
+#else
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 #define PLAT_NS_IMAGE_OFFSET			0x80200000
 #else
-#define PLAT_NS_IMAGE_OFFSET			PRELOADED_BL33_BASE
-#endif
-#define PLAT_HANDOFF_OFFSET 0x0003F000
-
-#else
 #define PLAT_NS_IMAGE_OFFSET			0x10000000
-#define PLAT_HANDOFF_OFFSET			0xFFE3F000
 #endif
+#endif /* #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 */
 
 #define PLAT_QSPI_DATA_BASE			(0x3C00000)
 #define PLAT_NAND_DATA_BASE			(0x0200000)
 #define PLAT_SDMMC_DATA_BASE			(0x0)
 
+
 /*******************************************************************************
  * Platform binary types for linking
  ******************************************************************************/
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index b2913c7..7e1d0c0 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +11,12 @@
 #define HANDOFF_MAGIC_HEADER			0x424f4f54	/* BOOT */
 #define HANDOFF_MAGIC_PINMUX_SEL		0x504d5558	/* PMUX */
 #define HANDOFF_MAGIC_IOCTLR			0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA				0x46504741	/* FPGA */
+#define HANDOFF_MAGIC_FPGA			0x46504741	/* FPGA */
 #define HANDOFF_MAGIC_IODELAY			0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK				0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC				0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_CLOCK			0x434c4b53	/* CLKS */
+#define HANDOFF_MAGIC_MISC			0x4d495343	/* MISC */
 #define HANDOFF_MAGIC_PERIPHERAL		0x50455249	/* PERIPHERAL */
-#define HANDOFF_MAGIC_DDR				0x5344524d	/* DDR */
+#define HANDOFF_MAGIC_DDR			0x5344524d	/* DDR */
 
 #include <socfpga_plat_def.h>
 
@@ -126,6 +127,8 @@
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
 	uint32_t	_pad_0x588_0x590[2];
+
+	/* main group PLL */
 	uint32_t	main_pll_nocclk;
 	uint32_t	main_pll_nocdiv;
 	uint32_t	main_pll_pllglob;
@@ -135,6 +138,8 @@
 	uint32_t	main_pll_pllc2;
 	uint32_t	main_pll_pllc3;
 	uint32_t	main_pll_pllm;
+
+	/* peripheral group PLL */
 	uint32_t	per_pll_emacctl;
 	uint32_t	per_pll_gpiodiv;
 	uint32_t	per_pll_pllglob;
@@ -144,29 +149,25 @@
 	uint32_t	per_pll_pllc2;
 	uint32_t	per_pll_pllc3;
 	uint32_t	per_pll_pllm;
+
+	/* control group */
 	uint32_t	alt_emacactr;
 	uint32_t	alt_emacbctr;
 	uint32_t	alt_emacptpctr;
 	uint32_t	alt_gpiodbctr;
-	uint32_t	alt_sdmmcctr;
 	uint32_t	alt_s2fuser0ctr;
 	uint32_t	alt_s2fuser1ctr;
 	uint32_t	alt_psirefctr;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	qspi_clk_khz;
+	uint32_t	alt_usb31ctr;
+	uint32_t	alt_dsuctr;
+	uint32_t	alt_core01ctr;
+	uint32_t	alt_core23ctr;
+	uint32_t	alt_core2ctr;
+	uint32_t	alt_core3ctr;
 	uint32_t	hps_osc_clk_hz;
 	uint32_t	fpga_clk_hz;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	ddr_reset_type;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	hps_status_coldreset;
-	/* TODO: Temp remove due to add in extra handoff data */
-	//uint32_t	_pad_0x604_0x610[3];
+	uint32_t	_pad_0x604_0x610[3];
 #endif
-	/* misc configuration */
-	uint32_t	misc_magic;
-	uint32_t	misc_length;
-	uint32_t	_pad_0x618_0x620[2];
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	/* peripheral configuration - select */
@@ -179,7 +180,7 @@
 	uint32_t	ddr_magic;
 	uint32_t	ddr_length;
 	uint32_t	_pad_0x1C_0x20[2];
-	uint32_t	ddr_array[4];	/* offset, value */
+	uint32_t	ddr_config;	/* BIT[0]-Dual Port. BIT[1]-Dual EMIF */
 #endif
 } handoff;
 
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index fcee101..e27af21 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -48,6 +48,7 @@
 #define MBOX_CMD_GET_IDCODE				0x10
 #define MBOX_CMD_GET_USERCODE				0x13
 #define MBOX_CMD_GET_CHIPID				0x12
+#define MBOX_CMD_FPGA_CONFIG_COMP			0x45
 #define MBOX_CMD_REBOOT_HPS				0x47
 
 /* Reconfiguration Commands */
@@ -242,11 +243,13 @@
 void mailbox_reset_warm(uint32_t reset_type);
 void mailbox_clear_response(void);
 
-int intel_mailbox_get_config_status(uint32_t cmd, bool init_done);
+int intel_mailbox_get_config_status(uint32_t cmd, bool init_done,
+				    uint32_t *err_states);
 int intel_mailbox_is_fpga_not_ready(void);
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 void intel_smmu_hps_remapper_init(uint64_t *mem);
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass);
 #endif
 
 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
@@ -259,4 +262,6 @@
 int mailbox_seu_err_status(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len);
 
+int mailbox_send_fpga_config_comp(void);
+
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 041c282..fbe18c3 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +24,8 @@
 	BOOT_SOURCE_FPGA = 0,
 	BOOT_SOURCE_SDMMC,
 	BOOT_SOURCE_NAND,
-	BOOT_SOURCE_RSVD,
-	BOOT_SOURCE_QSPI
+	BOOT_SOURCE_QSPI,
+	BOOT_SOURCE_RSVD
 } boot_source_type;
 
 /*******************************************************************************
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index d2eceb9..31474c4 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -140,6 +140,7 @@
 #define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE			0xC200008B
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT				0xC200008C
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE				0xC200008E
+#define INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG				0xC2000201
 
 /* SEU ERR */
 #define INTEL_SIP_SMC_SEU_ERR_STATUS					0xC2000099
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 1327b81..346cfe1 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,4 +33,8 @@
 #define SOCFPGA_SYSMGR(_reg)		(SOCFPGA_SYSMGR_REG_BASE \
 						+ (SOCFPGA_SYSMGR_##_reg))
 
+/* Function Prototype */
+uint32_t intel_hps_get_jtag_id(void);
+bool is_agilex5_A5F0(void);
+
 #endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 74ecc95..69f0008 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -168,7 +168,7 @@
 		}
 
 		if (MBOX_RESP_ERR(resp_data) > 0U) {
-			INFO("Error in response: %x\n", resp_data);
+			INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 			return -MBOX_RESP_ERR(resp_data);
 		}
 
@@ -337,7 +337,7 @@
 			}
 
 			if (MBOX_RESP_ERR(resp_data) > 0U) {
-				INFO("Error in response: %x\n", resp_data);
+				INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 				return -MBOX_RESP_ERR(resp_data);
 			}
 
@@ -622,7 +622,24 @@
 	return MBOX_RET_OK;
 }
 
-int intel_mailbox_get_config_status(uint32_t cmd, bool init_done)
+int mailbox_send_fpga_config_comp(void)
+{
+	int ret;
+
+	ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_FPGA_CONFIG_COMP, NULL, 0U,
+				 CMD_CASUAL, NULL, NULL);
+
+	if (ret != 0) {
+		INFO("SOCFPGA: FPGA configuration complete response, Return Code: 0x%x\n",
+			MBOX_RESP_ERR(-ret));
+		return MBOX_RET_ERROR;
+	}
+
+	return MBOX_RET_OK;
+}
+
+int intel_mailbox_get_config_status(uint32_t cmd, bool init_done,
+				    uint32_t *err_states)
 {
 	int status;
 	uint32_t res, response[6];
@@ -637,6 +654,9 @@
 
 	res = response[RECONFIG_STATUS_STATE];
 
+	if (err_states != NULL)
+		*err_states = res;
+
 	if (res == MBOX_CFGSTAT_VAB_BS_PREAUTH) {
 		return MBOX_CFGSTAT_STATE_CONFIG;
 	}
@@ -652,7 +672,7 @@
 
 	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
 	if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
-		ERROR("SoftFunction Status SEU ERROR\n");
+		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
 	}
 
 	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
@@ -668,11 +688,11 @@
 
 int intel_mailbox_is_fpga_not_ready(void)
 {
-	int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+	int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true, NULL);
 
 	if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
 		ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
-							false);
+							false, NULL);
 	}
 
 	return ret;
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index cb4a210..f653318 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -76,7 +76,7 @@
 			RSTMGR_FIELD(PER0, DMAIF6) |
 			RSTMGR_FIELD(PER0, DMAIF7));
 
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#if (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5)
 	mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_FIELD(BRG, MPFE));
 #endif
@@ -404,10 +404,11 @@
 	uint32_t brg_lst = 0;
 #endif
 
+/**************** SOC2FPGA ****************/
+
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-/**************** SOC2FPGA ****************/
 	brg_lst = mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST));
 	if ((brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA)
 		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_SOC2FPGA) != 0)) {
@@ -484,6 +485,11 @@
 				(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
 				| RSTMGR_BRGMODRST_LWHPS2FPGA))
 				| RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* Set System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
 	}
 
 /**************** LWSOCFPGA ****************/
@@ -567,6 +573,11 @@
 				((~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
 				| RSTMGR_BRGMODRST_LWHPS2FPGA)))
 				| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* Set System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
 	}
 #else
 	if (brg_mask != 0U) {
@@ -580,12 +591,11 @@
 		/* Wait until idle ack becomes 0 */
 		ret_hps = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
 				       noc_mask, 0, 1000);
-		if (ret_hps < 0) {
-			ERROR("S2F bridge enable: Timeout idle ack\n");
-		}
 	}
 #endif
 
+/**************** FPGA2SOC ****************/
+
 	/* Enable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
 				&f2s_force_drain, &f2s_en,
@@ -596,89 +606,28 @@
 	if ((brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC)
 		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_FPGA2SOC) != 0)) {
 		/*
-		 * To request handshake
-		 * Write Reset Manager hdsken[fpgahsen] = 1
+		 * To deassert reset
+		 * Write Reset Manager brgmodrst[fpga2soc] = 0
 		 */
-		VERBOSE("Set FPGA hdsken(fpgahsen) ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+		VERBOSE("Deassert F2S ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				RSTMGR_BRGMODRST_FPGA2SOC);
 
 		/*
-		 * To request handshake
-		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 * To clear handshake fpgahsack
+		 * Write Reset Manager hdskreq[fpgahsack] = 1
 		 */
-		VERBOSE("Set FPGA hdskreq(fpgahsreq) ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
-
-		/*
-		 * To poll idle status
-		 * Read Reset Manager hdskack[fpgahsack] = 1
-		 */
-		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
-		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
-				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
-			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
-				300);
-		}
-
-		if (ret < 0) {
-			ERROR("FPGA bridge fpga handshake fpgahsreq: Timeout\n");
-		}
-
-		/*
-		 * To fence and drain traffic
-		 * Write Reset Manager hdskreq[f2s_flush_req] = 1
-		 */
-		VERBOSE("Set F2S hdskreq(f2s_flush_req) ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_FPGA2SOCREQ);
-
-		/*
-		 * To poll idle status
-		 * Read Reset Manager hdskack[f2s_flush_ack] = 1
-		 */
-		VERBOSE("Get F2S hdskack(f2s_flush_ack) ...\n");
-		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
-				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
-			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
-				300);
-		}
-
-		if (ret < 0) {
-			ERROR("F2S bridge fpga handshake f2sdram_flush_req: Timeout\n");
-		}
+		VERBOSE("Clear FPGA hdskack(fpgahsack) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK);
 
 		/*
 		 * To clear idle request
-		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 * Write Reset Manager hdskreq[fpgahsreq] = 0
 		 */
 		VERBOSE("Clear FPGA hdskreq(fpgahsreq) ...\n");
-		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
-
-		/*
-		 * To clear idle request
-		 * Write Reset Manager hdskreq[f2s_flush_req] = 1
-		 */
-		VERBOSE("Clear F2S hdskreq(f2s_flush_req) ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_FPGA2SOCREQ);
-
-		/*
-		 * To poll idle status
-		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
-		 */
-		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
-		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
-				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
-			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
-				300);
-		}
-
-		if (ret < 0) {
-			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
-		}
+				RSTMGR_HDSKACK_FPGAHSREQ);
 
 		/*
 		 * To poll idle status
@@ -688,8 +637,9 @@
 		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
 				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
 			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-				300);
+						RSTMGR_HDSKACK_FPGAHSACK,
+						RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+						1000);
 				}
 
 		if (ret < 0) {
@@ -697,27 +647,46 @@
 		}
 
 		/*
-		 * To assert reset
-		 * Write Reset Manager brgmodrst[fpga2soc] = 1
+		 * To clear handshake f2s_flush_ack
+		 * Write Reset Manager hdskreq[f2s_flush_ack] = 1
 		 */
-		VERBOSE("Assert F2S ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
-
-		udelay(1000);
+		VERBOSE("Clear F2S hdskack(f2s_flush_ack) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2S_FLUSH);
 
 		/*
-		 * To deassert reset
-		 * Write Reset Manager brgmodrst[fpga2soc] = 0
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[f2s_flush_req] = 0
 		 */
-		VERBOSE("Deassert F2S ...\n");
-		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+		VERBOSE("Clear F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_F2S_FLUSH);
 
-		/* Write System Manager f2s bridge control register[f2soc_enable] = 1 */
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+						RSTMGR_HDSKACK_FPGA2SOCACK,
+						RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+						1000);
+		}
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+		}
+
+		/* Write System Manager f2s_bridge_ctrl [f2soc_enable] = 1 */
 		VERBOSE("Deassert F2S f2soc_enable ...\n");
 		mmio_setbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
-			SYSMGR_F2S_BRIDGE_CTRL_EN);
+				SYSMGR_F2S_BRIDGE_CTRL_EN);
 	}
 
+/**************** FPGA2SDRAM ****************/
+
 	/* Enable FPGA2SDRAM bridge */
 	if ((brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0)
 		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_F2SDRAM0) != 0)) {
@@ -925,6 +894,8 @@
 	uint32_t f2s_respempty = 0;
 	uint32_t f2s_cmdidle = 0;
 
+/**************** SOC2FPGA ****************/
+
 	/* Disable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
@@ -958,9 +929,16 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_SOC2FPGA);
 
+		/* Clear System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
+
 		udelay(1000);
 	}
 
+/**************** LWSOCFPGA ****************/
+
 	/* Disable LWSOC2FPGA bridge */
 	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
 		/*
@@ -991,6 +969,11 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_LWHPS2FPGA);
 
+		/* Clear System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
+
 		udelay(1000);
 	}
 #else
@@ -1018,6 +1001,8 @@
 	}
 #endif
 
+/**************** FPGA2SOC ****************/
+
 	/* Disable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
 				&f2s_force_drain, &f2s_en,
@@ -1027,67 +1012,90 @@
 	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
 		/*
 		 * To request handshake
+		 * Write Reset Manager hdsken[f2soc_flush] = 1
+		 */
+		VERBOSE("Enable FPGA hdsken(f2soc_flush) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
+				RSTMGR_HDSKEN_F2S_FLUSH);
+
+		/*
+		 * To request handshake
 		 * Write Reset Manager hdsken[fpgahsen] = 1
 		 */
-		VERBOSE("Set FPGA hdsken(fpgahsen) ...\n");
+		VERBOSE("Enable FPGA hdsken(fpgahsen) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
 
 		/*
-		 * To clear handshake request
-		 * Write Reset Manager hdskreq[fpgahsreq] = 0
+		 * To clear handshake fpgahsack
+		 * Write Reset Manager hdskack[fpgahsack] = 1
 		 */
-		VERBOSE("Clear FPGA hdskreq(fpgahsreq) ...\n");
-		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+		VERBOSE("Clear FPGA hdskack(fpgahsack) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK);
 
 		/*
-		 * To clear handshake request
-		 * Write Reset Manager hdskreq[f2s_flush_req] = 0
+		 * To set handshake request
+		 * Write Reset Manager hdskreq[fpgahsreq] = 1
 		 */
-		VERBOSE("Clear F2S hdskreq(f2s_flush_req) ...\n");
-		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+		VERBOSE("Set FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_FPGAHSREQ);
 
 		/*
 		 * To poll idle status
-		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
-		 */
-		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
-			300);
-
-		if (ret < 0) {
-			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
-		}
-
-		/*
-		 * To poll idle status
-		 * Read Reset Manager hdskack[fpgahsack] = 0
+		 * Read Reset Manager hdskack[fpgahsack] = 1
 		 */
 		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
 		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-			300);
+					RSTMGR_HDSKACK_FPGAHSACK,
+					RSTMGR_HDSKACK_FPGAHSACK,
+					1000);
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
 		}
 
 		/*
+		 * To clear handshake f2s_flush_ack
+		 * Write Reset Manager hdskack[f2s_flush_ack] = 1
+		 */
+		VERBOSE("Clear F2S hdskack(f2s_flush_ack) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2S_FLUSH);
+
+		/*
+		 * To set handshake request
+		 * Write Reset Manager hdskreq[f2s_flush_req] = 1
+		 */
+		VERBOSE("Set FPGA hdskreq(f2s_flush_req) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_F2S_FLUSH);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2s_flush_ack] = 1
+		 */
+		VERBOSE("Get FPGA hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+					RSTMGR_HDSKACK_FPGA2SOCACK,
+					RSTMGR_HDSKACK_F2S_FLUSH,
+					1000);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+		}
+
+		/*
 		 * To assert reset
 		 * Write Reset Manager brgmodrst[fpga2soc] = 1
 		 */
 		VERBOSE("Assert F2S ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
-
-		udelay(1000);
-
-		/* Write System Manager f2s bridge control register[f2soc_enable] = 0 */
-		VERBOSE("Assert F2S f2soc_enable ...\n");
-		mmio_clrbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
-			SYSMGR_F2S_BRIDGE_CTRL_EN);
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				RSTMGR_BRGMODRST_FPGA2SOC);
 	}
 
+/**************** FPGA2SDRAM ****************/
+
 	/* Disable FPGA2SDRAM bridge */
 	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
 		/*
@@ -1266,4 +1274,4 @@
 	} while (timeout-- > 0);
 
 	return RSTMGR_RET_ERROR;
-}
+}
\ No newline at end of file
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_system_manager.c
new file mode 100644
index 0000000..4223b2b
--- /dev/null
+++ b/plat/intel/soc/common/soc/socfpga_system_manager.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "socfpga_system_manager.h"
+
+uint32_t intel_hps_get_jtag_id(void)
+{
+	uint32_t jtag_id = 0x00;
+
+	jtag_id = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_4)));
+
+	INFO("%s: JTAG ID: 0x%x\n", __func__, jtag_id);
+
+	return jtag_id;
+}
+
+/* Check for Agilex5 SM4 */
+bool is_agilex5_A5F0(void)
+{
+	return ((intel_hps_get_jtag_id() & JTAG_ID_MASK) == A5F0_JTAG_ID);
+}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index db173a4..3759009 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +11,6 @@
 #include <lib/mmio.h>
 #include "socfpga_plat_def.h"
 
-
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
 #include "agilex_clock_manager.h"
 #elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
@@ -19,7 +19,7 @@
 #include "s10_clock_manager.h"
 #endif
 
-#define SOCFPGA_GLOBAL_TIMER		0xffd01000
+#define SOCFPGA_GLOBAL_TIMER		PLAT_TIMER_BASE_ADDR
 #define SOCFPGA_GLOBAL_TIMER_EN		0x3
 
 static timer_ops_t plat_timer_ops;
@@ -44,7 +44,6 @@
 	plat_timer_ops.clk_div		= PLAT_SYS_COUNTER_FREQ_IN_MHZ;
 
 	timer_init(&plat_timer_ops);
-
 }
 
 void socfpga_delay_timer_init(void)
@@ -54,5 +53,4 @@
 
 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
 	asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
-
 }
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index a5c3279..ee79158 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +13,13 @@
  ******************************************************************************/
 void plat_flush_next_bl_params(void)
 {
+	/*
+	 * We cannot flush these descriptors on the Agilex5 platform,
+	 * since the BL2 runs on the OCRAM and this OCRAM is not cache coherent.
+	 */
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	flush_bl_params_desc();
+#endif
 }
 
 /*******************************************************************************
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 623843e..50d4820 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -17,8 +17,13 @@
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#include "agilex5_cache.h"
+#endif
+#include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
+#include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
@@ -190,6 +195,14 @@
 	if (intel_rsu_update_address) {
 		mailbox_rsu_update(addr_buf);
 	} else {
+#if CACHE_FLUSH
+		/* ATF Flush and Invalidate Cache */
+		dcsw_op_all(DCCISW);
+		invalidate_cache_low_el();
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+		flush_l3_dcache();
+#endif
+#endif
 		mailbox_reset_cold();
 	}
 
@@ -200,6 +213,16 @@
 static int socfpga_system_reset2(int is_vendor, int reset_type,
 					u_register_t cookie)
 {
+
+#if CACHE_FLUSH
+	/*
+	 * ATF Flush and Invalidate Cache due to hardware limitation
+	 * of auto Flush and Invalidate Cache.
+	 */
+	dcsw_op_all(DCCISW);
+	invalidate_cache_low_el();
+#endif
+
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	mailbox_reset_warm(reset_type);
 #else
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 5dfbc14..71a626d 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -28,6 +28,9 @@
 static uint32_t send_id, rcv_id;
 static uint32_t bytes_per_block, blocks_submitted;
 static bool bridge_disable;
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static uint32_t g_remapper_bypass;
+#endif
 
 /* RSU static variables */
 static uint32_t rsu_dcmf_ver[4] = {0};
@@ -91,22 +94,25 @@
 	return 0;
 }
 
-static uint32_t intel_mailbox_fpga_config_isdone(void)
+static uint32_t intel_mailbox_fpga_config_isdone(uint32_t *err_states)
 {
 	uint32_t ret;
 
+	if (err_states == NULL)
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+
 	switch (request_type) {
 	case RECONFIGURATION:
 		ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
-							true);
+							true, err_states);
 		break;
 	case BITSTREAM_AUTH:
 		ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
-							false);
+							false, err_states);
 		break;
 	default:
 		ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
-							false);
+							false, err_states);
 		break;
 	}
 
@@ -219,6 +225,19 @@
 	unsigned int size = 0;
 	unsigned int resp_len = ARRAY_SIZE(response);
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/*
+	 * To trigger isolation
+	 * FPGA configuration complete signal should be de-asserted
+	 */
+	INFO("SOCFPGA: Request SDM to trigger isolation\n");
+	status = mailbox_send_fpga_config_comp();
+
+	if (status < 0) {
+		INFO("SOCFPGA: Isolation for FPGA configuration complete is not executed\n");
+	}
+#endif
+
 	request_type = RECONFIGURATION;
 
 	if (!CONFIG_TEST_FLAG(flag, PARTIAL_CONFIG)) {
@@ -758,7 +777,7 @@
 	/* Read out Bit 1 value */
 	uint32_t remap = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_1)) & 0x02);
 
-	if (remap == 0x00) {
+	if ((remap == 0x00) && (g_remapper_bypass == 0x00)) {
 		/* Update DRAM Base address for SDM SMMU */
 		mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), DRAM_BASE);
 		mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), DRAM_BASE);
@@ -767,6 +786,19 @@
 		*mem = *mem - DRAM_BASE;
 	}
 }
+
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass)
+{
+	/* Read out the JTAG-ID from boot scratch register */
+	if (is_agilex5_A5F0() != 0) {
+		if (remapper_bypass == 0x01) {
+			g_remapper_bypass = remapper_bypass;
+			mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), 0);
+			mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), 0);
+		}
+	}
+	return INTEL_SIP_SMC_STATUS_OK;
+}
 #endif
 
 /*
@@ -785,6 +817,7 @@
 	uint32_t retval = 0, completed_addr[3];
 	uint32_t retval2 = 0;
 	uint32_t mbox_error = 0;
+	uint32_t err_states = 0;
 	uint64_t retval64, rsu_respbuf[9];
 	uint32_t seu_respbuf[3];
 	int status = INTEL_SIP_SMC_STATUS_OK;
@@ -798,8 +831,8 @@
 		SMC_UUID_RET(handle, intl_svc_uid);
 
 	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
-		status = intel_mailbox_fpga_config_isdone();
-		SMC_RET4(handle, status, 0, 0, 0);
+		status = intel_mailbox_fpga_config_isdone(&err_states);
+		SMC_RET4(handle, status, err_states, 0, 0);
 
 	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
 		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
@@ -1292,6 +1325,12 @@
 					x5, x6, true, &send_id);
 		SMC_RET1(handle, status);
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	case INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG:
+		status = intel_smmu_hps_remapper_config(x1);
+		SMC_RET1(handle, status);
+#endif
+
 	case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
 		status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
 							&mbox_error);
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index d250d9e..66b5216 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,11 +28,6 @@
 #include "socfpga_ros.h"
 
 
-#define PLAT_FIP_BASE		(0)
-#define PLAT_FIP_MAX_SIZE	(0x1000000)
-#define PLAT_MMC_DATA_BASE	(0xffe3c000)
-#define PLAT_MMC_DATA_SIZE	(0x2000)
-
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;
 
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
index 54477da..95a3d5c 100644
--- a/plat/intel/soc/n5x/include/n5x_clock_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_clock_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +10,6 @@
 
 
 /* MACRO DEFINITION */
-#define SOCFPGA_GLOBAL_TIMER				0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN				0x3
 
 #define CLKMGR_PLLGLOB_VCO_PSRC_MASK			GENMASK(17, 16)
diff --git a/plat/intel/soc/n5x/include/n5x_system_manager.h b/plat/intel/soc/n5x/include/n5x_system_manager.h
index 3610a6e..fd789a2 100644
--- a/plat/intel/soc/n5x/include/n5x_system_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,7 +122,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 1eafeef..6f0a40b 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,10 +15,11 @@
 
 /* Platform Setting */
 #define PLATFORM_MODEL				PLAT_SOCFPGA_N5X
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -27,6 +29,15 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		U(0xf7000000)
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 29fd0eb..4770f8d 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -1,5 +1,6 @@
 #
-# Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -46,8 +47,30 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h
index 155b279..056f6cf 100644
--- a/plat/intel/soc/stratix10/include/s10_memory_controller.h
+++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,7 +27,7 @@
 #define S10_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define S10_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index e7bf730..dcc1517 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,7 +121,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 7f452bd..90345c3 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,10 +14,11 @@
 
 /* Platform Setting */
 #define PLATFORM_MODEL				PLAT_SOCFPGA_STRATIX10
-#define BOOT_SOURCE				BOOT_SOURCE_SDMMC
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -26,6 +28,15 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index afcf514..4cd7032 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,6 +27,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	\
 			plat/intel/soc/common/soc/socfpga_firewall.c
 
@@ -76,8 +78,30 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index 0cb2014..a095ba9 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -71,8 +71,9 @@
         $(eval SOURCES    := $(2))
         $(eval OBJS_TEMP  := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MODULE_OBJS += $(OBJS_TEMP))
+        $(eval BL         := $(call uppercase,$(3)))
 
-$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
+$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3},$(BL)))
 
 libraries: $(OBJS_TEMP)
 endef
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c
index dfe1dcf..87e8960 100644
--- a/plat/mediatek/drivers/apusys/apusys.c
+++ b/plat/mediatek/drivers/apusys/apusys.c
@@ -30,10 +30,10 @@
 
 	switch (request_ops) {
 	case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON:
-		ret = apusys_kernel_apusys_pwr_top_on();
+		ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_ON);
 		break;
 	case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF:
-		ret = apusys_kernel_apusys_pwr_top_off();
+		ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_OFF);
 		break;
 	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER:
 		ret = apusys_kernel_apusys_rv_setup_reviser();
@@ -68,6 +68,27 @@
 	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING:
 		ret = apusys_kernel_apusys_rv_cg_ungating();
 		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU:
+		ret = apusys_kernel_apusys_rv_setup_apummu();
+		break;
+#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
+	case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP:
+		ret = apusys_kernel_apusys_logtop_reg_dump((uint32_t)x2, smccc_ret);
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE:
+		ret = apusys_kernel_apusys_logtop_reg_write((uint32_t)x2, (uint32_t)x3,
+							    smccc_ret);
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C:
+		ret = apusys_kernel_apusys_logtop_reg_w1c((uint32_t)x2, smccc_ret);
+		break;
+#endif
+	case MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY:
+		ret = apusys_rv_cold_boot_clr_mbox_dummy();
+		break;
+	case MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN:
+		ret = apusys_rv_setup_ce_bin();
+		break;
 	default:
 		ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
 		break;
diff --git a/plat/mediatek/drivers/apusys/apusys.h b/plat/mediatek/drivers/apusys/apusys.h
index ed4e195..709379e 100644
--- a/plat/mediatek/drivers/apusys/apusys.h
+++ b/plat/mediatek/drivers/apusys/apusys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,19 +10,25 @@
 #define MODULE_TAG "[APUSYS]"
 
 enum MTK_APUSYS_KERNEL_OP {
-	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,		/*  0 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,	/*  1 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER,	/*  2 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP,	/*  3 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT,	/*  4 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP,	/*  5 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP,		/*  6 */
-	MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX,		/*  7 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM,	/*  8 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR,	/*  9 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR,	/* 10 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING,	/* 11 */
-	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING,	/* 12 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,			/*  0 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,		/*  1 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER,		/*  2 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP,		/*  3 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT,		/*  4 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP,		/*  5 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP,			/*  6 */
+	MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX,			/*  7 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM,		/*  8 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR,		/*  9 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR,		/* 10 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING,		/* 11 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING,		/* 12 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU,		/* 13 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP,		/* 14 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE,		/* 15 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C,		/* 16 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY,	/* 17 */
+	MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN,		/* 18 */
 	MTK_APUSYS_KERNEL_OP_NUM,
 };
 
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index cb57668..a9eebb5 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -1,9 +1,11 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
+
 /* TF-A system header */
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -14,7 +16,19 @@
 #include "apusys.h"
 #include "apusys_rv.h"
 #include "apusys_rv_mbox_mpu.h"
-#include "emi_mpu.h"
+#include "apusys_rv_pwr_ctrl.h"
+#include "apusys_rv_sec_info.h"
+#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
+#include "apusys_security_ctrl_perm.h"
+#endif
+#include "apusys_security_ctrl_plat.h"
+#include <drivers/apusys_rv_public.h>
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+#include "apusys_ammu.h"
+#endif
 
 static spinlock_t apusys_rv_lock;
 
@@ -94,6 +108,8 @@
 		      (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
 		      (PREDEFINE_CACHE << PREDEF_4G_OFS));
 
+	apusys_infra_dcm_setup();
+
 	spin_unlock(&apusys_rv_lock);
 	return 0;
 }
@@ -107,25 +123,64 @@
 	return 0;
 }
 
+static int hw_sema2_release(uint32_t timeout)
+{
+#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
+	int ret;
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0);
+	if (ret) {
+		ERROR("%s: HW semaphore release timeout\n", __func__);
+	}
+
+	return ret;
+#else
+	return 0;
+#endif
+}
+
+static int hw_sema2_acquire(uint32_t timeout)
+{
+#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
+	int ret;
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0);
+	if (ret) {
+		ERROR("%s: HW semaphore acquire timeout\n", __func__);
+	}
+
+	return ret;
+#else
+	return 0;
+#endif
+}
+
 int apusys_kernel_apusys_rv_stop_mp(void)
 {
+	int ret;
+
+	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+	if (ret)
+		return ret;
+
 	spin_lock(&apusys_rv_lock);
 	mmio_write_32(MD32_RUNSTALL, MD32_STALL);
 	spin_unlock(&apusys_rv_lock);
 
-	return 0;
+	ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+	return ret;
 }
 
 int apusys_kernel_apusys_rv_setup_sec_mem(void)
 {
-	int ret;
+	int ret = 0;
 
 	spin_lock(&apusys_rv_lock);
 
-	ret = set_apu_emi_mpu_region();
-	if (ret != 0) {
+	ret = apusys_plat_setup_sec_mem();
+	if (ret != 0)
 		ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
-	}
 
 	spin_unlock(&apusys_rv_lock);
 	return ret;
@@ -133,37 +188,312 @@
 
 int apusys_kernel_apusys_rv_disable_wdt_isr(void)
 {
+	int ret;
+
+	ret = hw_sema2_acquire(0);
+	if (ret)
+		return ret;
+
 	spin_lock(&apusys_rv_lock);
 	mmio_clrbits_32(WDT_CTRL0, WDT_EN);
 	spin_unlock(&apusys_rv_lock);
 
-	return 0;
+	ret = hw_sema2_release(0);
+
+	return ret;
 }
 
 int apusys_kernel_apusys_rv_clear_wdt_isr(void)
 {
+	int ret;
+
+	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+	if (ret)
+		return ret;
+
 	spin_lock(&apusys_rv_lock);
 	mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
 	mmio_write_32(WDT_INT, WDT_INT_W1C);
 	spin_unlock(&apusys_rv_lock);
 
-	return 0;
+	ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+	return ret;
 }
 
 int apusys_kernel_apusys_rv_cg_gating(void)
 {
+	int ret;
+
+	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+	if (ret)
+		return ret;
+
 	spin_lock(&apusys_rv_lock);
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
 	spin_unlock(&apusys_rv_lock);
 
-	return 0;
+	ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+	return ret;
 }
 
 int apusys_kernel_apusys_rv_cg_ungating(void)
 {
+	int ret;
+
+	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+	if (ret)
+		return ret;
+
 	spin_lock(&apusys_rv_lock);
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
 	spin_unlock(&apusys_rv_lock);
 
+	ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+	return ret;
+}
+
+int apusys_kernel_apusys_rv_setup_apummu(void)
+{
+	spin_lock(&apusys_rv_lock);
+
+#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
+	sec_set_rv_dns();
+#endif
+
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+	uint32_t apummu_tcm_sz_select = 0;
+
+	if (APU_MD32_TCM_SZ <= 0x20000)
+		apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
+	else if (APU_MD32_TCM_SZ <= 0x40000)
+		apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
+	else if (APU_MD32_TCM_SZ <= 0x80000)
+		apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
+	else if (APU_MD32_TCM_SZ <= 0x100000)
+		apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
+	else {
+		ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
+		spin_unlock(&apusys_rv_lock);
+		return -EINVAL;
+	}
+
+	INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
+	rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
+		APU_MD32_TCM, apummu_tcm_sz_select);
+#endif
+
+	spin_unlock(&apusys_rv_lock);
+	return 0;
+}
+
+int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+	return apusys_rv_pwr_ctrl(op);
+}
+
+#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
+int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret)
+{
+	int ret = 0;
+	uint8_t smc_op;
+	uint32_t reg_addr[MAX_SMC_OP_NUM];
+	uint32_t i;
+
+	if (op == 0) {
+		ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < MAX_SMC_OP_NUM; i++) {
+		smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK;
+		switch (smc_op) {
+		case SMC_OP_APU_LOG_BUF_NULL:
+			reg_addr[i] = 0x0;
+			break;
+		case SMC_OP_APU_LOG_BUF_T_SIZE:
+			reg_addr[i] = APU_LOG_BUF_T_SIZE;
+			break;
+		case SMC_OP_APU_LOG_BUF_W_PTR:
+			reg_addr[i] = APU_LOG_BUF_W_PTR;
+			break;
+		case SMC_OP_APU_LOG_BUF_R_PTR:
+			reg_addr[i] = APU_LOG_BUF_R_PTR;
+			break;
+		case SMC_OP_APU_LOG_BUF_CON:
+			reg_addr[i] = APU_LOGTOP_CON;
+			break;
+		default:
+			ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op);
+			return -EINVAL;
+		}
+	}
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < MAX_SMC_OP_NUM; i++) {
+		if (reg_addr[i] == 0)
+			continue;
+
+		switch (i) {
+		case 0:
+			smccc_ret->a1 = mmio_read_32(reg_addr[i]);
+			break;
+		case 1:
+			smccc_ret->a2 = mmio_read_32(reg_addr[i]);
+			break;
+		case 2:
+			smccc_ret->a3 = mmio_read_32(reg_addr[i]);
+			break;
+		}
+	}
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
+	if (ret)
+		ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+	return ret;
+}
+
+static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val,
+					      bool w1c, struct smccc_res *smccc_ret)
+{
+	int ret = 0;
+	uint32_t reg_addr = 0, reg_val = 0;
+
+	switch (op) {
+	case SMC_OP_APU_LOG_BUF_R_PTR:
+		reg_addr = APU_LOG_BUF_R_PTR;
+		break;
+	case SMC_OP_APU_LOG_BUF_CON:
+		reg_addr = APU_LOGTOP_CON;
+		break;
+	default:
+		ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op);
+		return -EINVAL;
+	}
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
+	if (ret)
+		return ret;
+
+	if (w1c) {
+		reg_val = mmio_read_32(reg_addr);
+		mmio_write_32(reg_addr, reg_val);
+		smccc_ret->a1 = reg_val;
+	} else {
+		mmio_write_32(reg_addr, write_val);
+	}
+
+	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
+	if (ret)
+		ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+	return ret;
+}
+
+int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
+					  struct smccc_res *smccc_ret)
+{
+	return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret);
+}
+
+int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret)
+{
+	return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret);
+}
+
+#endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */
+
+int apusys_rv_cold_boot_clr_mbox_dummy(void)
+{
+#ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY
+	mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0);
+#else
+	WARN("Not support clear mbox dummy on this platform\n");
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
+int apusys_rv_iommu_hw_sem_trylock(void)
+{
+	return rv_iommu_hw_sem_trylock();
+}
+
+int apusys_rv_iommu_hw_sem_unlock(void)
+{
+	return rv_iommu_hw_sem_unlock();
+}
+#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
+
+int apusys_rv_setup_ce_bin(void)
+{
+#ifdef CONFIG_MTK_APUSYS_CE_SUPPORT
+	uintptr_t apusys_rv_sec_buf_pa;
+	struct apusys_secure_info_t *apusys_secure_info;
+	struct ce_main_hdr_t *ce_main_hdr;
+	struct ce_sub_hdr_t *ce_sub_hdr;
+	unsigned int cnt, i, reg_val;
+	uint64_t ce_sub_hdr_bin;
+	int ret;
+
+	apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY;
+	/* create mapping */
+	ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa,
+				      round_up(APU_RESERVE_SIZE, PAGE_SIZE),
+				      MT_MEMORY | MT_RW | MT_NS);
+	if (ret) {
+		ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret);
+		return ret;
+	}
+
+	apusys_secure_info = (struct apusys_secure_info_t *)
+				(apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET);
+
+	ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa +
+		apusys_secure_info->ce_bin_ofs);
+	ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size);
+
+	if (ce_main_hdr->magic != CE_MAIN_MAGIC) {
+		ERROR("%s: invalid header\n", __func__);
+		return -EINVAL;
+	}
+
+	cnt = 0;
+
+	while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) {
+		VERBOSE("%s: job (%d), magic (0x%x)\n", __func__,
+			ce_sub_hdr->ce_enum, ce_sub_hdr->magic);
+
+		ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset;
+
+		for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) {
+			reg_val = *(uint32_t *)(ce_sub_hdr_bin + i);
+			mmio_write_32(ce_sub_hdr->mem_st + i, reg_val);
+		}
+
+		if (ce_sub_hdr->hw_entry) {
+			mmio_clrsetbits_32(ce_sub_hdr->hw_entry,
+					   ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit,
+					   (ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask)
+					   << ce_sub_hdr->hw_entry_bit);
+		}
+
+		ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size);
+		cnt++;
+	}
+
+	mmap_remove_dynamic_region(apusys_rv_sec_buf_pa,
+				   round_up(APU_RESERVE_SIZE, PAGE_SIZE));
+
+	INFO("%s: setup CE binary done\n", __func__);
+#else
+	WARN("Not support CE on this platform\n");
+#endif
 	return 0;
 }
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
index 8a43890..506fcee 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -88,24 +88,35 @@
 #define WDT_INT_W1C			(1)
 #define WDT_EN				BIT(31)
 
-/* APU MBOX */
-#define MBOX_FUNC_CFG			(0xb0)
-#define MBOX_DOMAIN_CFG			(0xe0)
-#define MBOX_CTRL_LOCK			BIT(0)
-#define MBOX_NO_MPU_SHIFT		(16)
-#define MBOX_RX_NS_SHIFT		(16)
-#define MBOX_RX_DOMAIN_SHIFT		(17)
-#define MBOX_TX_NS_SHIFT		(24)
-#define MBOX_TX_DOMAIN_SHIFT		(25)
-#define MBOX_SIZE			(0x100)
-#define MBOX_NUM			(8)
+enum APU_PWR_OP {
+	APU_PWR_OFF = 0,
+	APU_PWR_ON  = 1,
+};
 
-#define APU_MBOX(i)		(((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
-						  (APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
-#define APU_MBOX_FUNC_CFG(i)	(APU_MBOX(i) + MBOX_FUNC_CFG)
-#define APU_MBOX_DOMAIN_CFG(i)	(APU_MBOX(i) + MBOX_DOMAIN_CFG)
+/* APU_LOGTOP */
+#define APU_LOGTOP_CON			(APU_LOGTOP + 0x0)
+#define APU_LOG_BUF_T_SIZE		(APU_LOGTOP + 0x78)
+#define APU_LOG_BUF_W_PTR		(APU_LOGTOP + 0x80)
+#define APU_LOG_BUF_R_PTR		(APU_LOGTOP + 0x84)
+#define HW_SEMA2			(APU_ARE_REG_BASE + 0x0E08)
+#define HW_SEMA_USER			(0x2)
+#define HW_SEMA_LOGGER_USER		(0x3)
+#define MAX_SMC_OP_NUM			(0x3)
+#define LOGTOP_OP_MASK			(0xFF)
+#define LOGTOP_OP_SHIFT			(8)
+enum {
+	SMC_OP_APU_LOG_BUF_NULL = 0,
+	SMC_OP_APU_LOG_BUF_T_SIZE,
+	SMC_OP_APU_LOG_BUF_W_PTR,
+	SMC_OP_APU_LOG_BUF_R_PTR,
+	SMC_OP_APU_LOG_BUF_CON,
+	SMC_OP_APU_LOG_BUF_NUM
+};
+
+struct smccc_res;
 
 void apusys_rv_mbox_mpu_init(void);
+int apusys_infra_dcm_setup(void);
 int apusys_kernel_apusys_rv_setup_reviser(void);
 int apusys_kernel_apusys_rv_reset_mp(void);
 int apusys_kernel_apusys_rv_setup_boot(void);
@@ -116,5 +127,13 @@
 int apusys_kernel_apusys_rv_clear_wdt_isr(void);
 int apusys_kernel_apusys_rv_cg_gating(void);
 int apusys_kernel_apusys_rv_cg_ungating(void);
+int apusys_kernel_apusys_rv_setup_apummu(void);
+int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret);
+int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
+					  struct smccc_res *smccc_ret);
+int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret);
+int apusys_rv_cold_boot_clr_mbox_dummy(void);
+int apusys_rv_setup_ce_bin(void);
 
 #endif /* APUSYS_RV_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h
new file mode 100644
index 0000000..581ed0a
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_SECURE_INFO_H
+#define APUSYS_RV_SECURE_INFO_H
+
+#define CE_MAIN_MAGIC		(0xCEC0DE88)
+#define CE_SUB_MAGIC		(0xCEC0DE00)
+
+struct apusys_secure_info_t {
+	unsigned int total_sz;
+	unsigned int up_code_buf_ofs;
+	unsigned int up_code_buf_sz;
+
+	unsigned int up_fw_ofs;
+	unsigned int up_fw_sz;
+	unsigned int up_xfile_ofs;
+	unsigned int up_xfile_sz;
+	unsigned int mdla_fw_boot_ofs;
+	unsigned int mdla_fw_boot_sz;
+	unsigned int mdla_fw_main_ofs;
+	unsigned int mdla_fw_main_sz;
+	unsigned int mdla_xfile_ofs;
+	unsigned int mdla_xfile_sz;
+	unsigned int mvpu_fw_ofs;
+	unsigned int mvpu_fw_sz;
+	unsigned int mvpu_xfile_ofs;
+	unsigned int mvpu_xfile_sz;
+	unsigned int mvpu_sec_fw_ofs;
+	unsigned int mvpu_sec_fw_sz;
+	unsigned int mvpu_sec_xfile_ofs;
+	unsigned int mvpu_sec_xfile_sz;
+
+	unsigned int up_coredump_ofs;
+	unsigned int up_coredump_sz;
+	unsigned int mdla_coredump_ofs;
+	unsigned int mdla_coredump_sz;
+	unsigned int mvpu_coredump_ofs;
+	unsigned int mvpu_coredump_sz;
+	unsigned int mvpu_sec_coredump_ofs;
+	unsigned int mvpu_sec_coredump_sz;
+
+	unsigned int ce_bin_ofs;
+	unsigned int ce_bin_sz;
+};
+
+struct ce_main_hdr_t {
+	unsigned int magic;         /* magic number*/
+	unsigned int hdr_size;      /* header size */
+	unsigned int img_size;      /* img size */
+	unsigned int bin_count;     /* bin count */
+};
+
+struct ce_sub_hdr_t {
+	unsigned int magic;         /* magic number */
+	unsigned int bin_offset;    /* binary offset */
+	unsigned int bin_size;      /* binary size */
+	unsigned int ce_enum;       /* ce enum */
+	char job_name[8];           /* job name */
+	unsigned int mem_st;        /* ce enum */
+	unsigned int hw_entry;      /* hw entry */
+	unsigned int hw_entry_bit;  /* hw entry bit */
+	unsigned int hw_entry_mask; /* hw entry mask */
+	unsigned int hw_entry_val;  /* hw entry val*/
+	unsigned int user_info;     /* user_info */
+};
+
+#endif /* APUSYS_RV_SECURE_INFO_H */
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
index 1b77942..a15daa2 100644
--- a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,8 +13,15 @@
  * STRUCTURE DEFINITION
  ******************************************************************************/
 enum apusys_apc_err_status {
-	APUSYS_APC_OK		= 0x0,
-	APUSYS_APC_ERR_GENERIC	= 0x1,
+	APUSYS_APC_OK				= 0x0,
+	APUSYS_APC_ERR_GENERIC			= 0x1000,
+	APUSYS_APC_ERR_INVALID_CMD		= 0x1001,
+	APUSYS_APC_ERR_SLAVE_TYPE_NOT_SUPPORTED	= 0x1002,
+	APUSYS_APC_ERR_SLAVE_IDX_NOT_SUPPORTED	= 0x1003,
+	APUSYS_APC_ERR_DOMAIN_NOT_SUPPORTED	= 0x1004,
+	APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED	= 0x1005,
+	APUSYS_APC_ERR_OUT_OF_BOUNDARY		= 0x1006,
+	APUSYS_APC_ERR_REQ_TYPE_NOT_SUPPORTED	= 0x1007,
 };
 
 enum apusys_apc_perm_type {
@@ -155,4 +162,110 @@
 			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
 			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
 			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   SEC_RW_ONLY,   FORBIDDEN,   FORBIDDEN, NO_PROTECTION, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   SEC_RW_NS_R, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   FORBIDDEN, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN, FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   SEC_RW_NS_R, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   NO_PROTECTION, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, NO_PROTECTION, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   SEC_RW_ONLY, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, NO_PROTECTION, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   SEC_RW_ONLY,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   SEC_RW_ONLY, FORBIDDEN,   FORBIDDEN, SEC_RW_ONLY, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   SEC_RW_NS_R, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   SEC_RW_ONLY, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+			   SEC_RW_ONLY, FORBIDDEN,   FORBIDDEN, FORBIDDEN, \
+			   FORBIDDEN,   FORBIDDEN,   FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT(domain) \
+	APUSYS_APC_AO_ATTR(domain, \
+			   NO_PROTECTION, FORBIDDEN,     FORBIDDEN,     FORBIDDEN, \
+			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN,     NO_PROTECTION, \
+			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN,     FORBIDDEN, \
+			   FORBIDDEN,     FORBIDDEN,     NO_PROTECTION, FORBIDDEN)
+
 #endif /* APUSYS_DAPC_V1_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
index 0a2781b..746c81f 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <inttypes.h>
 
 /* TF-A system header */
@@ -18,6 +19,7 @@
 #include "apusys.h"
 #include "apusys_power.h"
 #include "apusys_rv.h"
+#include "apusys_rv_pwr_ctrl.h"
 #include <mtk_mmap_pool.h>
 
 static spinlock_t apu_lock;
@@ -118,7 +120,7 @@
 	mmio_write_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG, (cfg & 0x1));
 }
 
-int apusys_kernel_apusys_pwr_top_on(void)
+static int apusys_kernel_apusys_pwr_top_on(void)
 {
 	int ret;
 
@@ -184,7 +186,7 @@
 	udelay(100);
 }
 
-int apusys_kernel_apusys_pwr_top_off(void)
+static int apusys_kernel_apusys_pwr_top_off(void)
 {
 	int ret;
 
@@ -221,6 +223,19 @@
 	return ret;
 }
 
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+	if (op != APU_PWR_OFF && op != APU_PWR_ON) {
+		ERROR(MODULE_TAG "%s unknown request_ops = %d\n", __func__, op);
+		return -EINVAL;
+	}
+
+	if (op == APU_PWR_ON)
+		return apusys_kernel_apusys_pwr_top_on();
+
+	return apusys_kernel_apusys_pwr_top_off();
+}
+
 static void get_pll_pcw(const uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
 {
 	unsigned int fvco = clk_rate;
@@ -481,3 +496,10 @@
 
 	return ret;
 }
+
+int apusys_infra_dcm_setup(void)
+{
+	WARN(MODULE_TAG "%s not support\n", __func__);
+
+	return -EOPNOTSUPP;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
index 460cc50..e1ce4a4 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -242,7 +242,5 @@
 #define CG_CLR					(0xffffffff)
 
 int apusys_power_init(void);
-int apusys_kernel_apusys_pwr_top_on(void);
-int apusys_kernel_apusys_pwr_top_off(void);
 
 #endif /* APUSYS_POWER_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
similarity index 95%
rename from plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
rename to plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
index 0ee4878..dbdf274 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h
new file mode 100644
index 0000000..329eadf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PWR_CTL_H
+#define APUSYS_RV_PWR_CTL_H
+
+#include "apusys_rv.h"
+
+/* APU MBOX */
+#define MBOX_FUNC_CFG			(0xb0)
+#define MBOX_DOMAIN_CFG			(0xe0)
+#define MBOX_CTRL_LOCK			BIT(0)
+#define MBOX_NO_MPU_SHIFT		(16)
+#define MBOX_RX_NS_SHIFT		(16)
+#define MBOX_RX_DOMAIN_SHIFT		(17)
+#define MBOX_TX_NS_SHIFT		(24)
+#define MBOX_TX_DOMAIN_SHIFT		(25)
+#define MBOX_SIZE			(0x100)
+#define MBOX_NUM			(8)
+
+#define APU_MBOX(i)		(((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
+						  (APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
+#define APU_MBOX_FUNC_CFG(i)	(APU_MBOX(i) + MBOX_FUNC_CFG)
+#define APU_MBOX_DOMAIN_CFG(i)	(APU_MBOX(i) + MBOX_DOMAIN_CFG)
+
+#define HW_SEM_TIMEOUT		(0)
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+
+#endif /* APUSYS_RV_PWR_CTL_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
index 86bebe5..8517db0 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 #include <common/debug.h>
 #include <lib/mmio.h>
 
+#include "emi_mpu.h"
+
 /* Vendor header */
 #include "apusys_security_ctrl_plat.h"
 
@@ -41,3 +43,8 @@
 {
 	apusys_domain_remap_init();
 }
+
+int apusys_plat_setup_sec_mem(void)
+{
+	return set_apu_emi_mpu_region();
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
index f9181ae..f1b0a41 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,5 +34,6 @@
 #define D15_REMAP_DOMAIN	(15)
 
 void apusys_security_ctrl_init(void);
+int apusys_plat_setup_sec_mem(void);
 
 #endif /* APUSYS_SECURITY_CTRL_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
new file mode 100644
index 0000000..fa1cd2c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include "apusys_ammu.h"
+#include <apusys_security_ctrl_perm.h>
+#include <mtk_mmap_pool.h>
+
+static void apummu_set_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr,
+				       uint8_t res_bits, uint8_t page_sel, uint8_t page_len)
+{
+	mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_0),
+		      APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, res_bits, page_sel, page_len));
+}
+
+static void apummu_set_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, uint32_t output_adr,
+				       uint8_t res0, uint8_t iommu_en, uint8_t res1)
+{
+	mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_1),
+		      APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, res0, iommu_en, res1));
+}
+
+static void apummu_set_segment_offset2(uint32_t vsid_idx, uint8_t seg_idx, uint8_t resv,
+				       uint8_t domain, uint8_t acp_en, uint8_t aw_clr,
+				       uint8_t aw_invalid, uint8_t ar_exclu, uint8_t ar_sepcu,
+				       uint8_t aw_cache_allocate, uint8_t aw_slc_en,
+				       uint8_t aw_slb_en, uint8_t ar_cache_allocate,
+				       uint8_t ar_slc_en, uint8_t ar_slb_en, uint8_t ro,
+				       uint8_t ns)
+{
+	mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_2),
+		      APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, aw_invalid,
+						   ar_exclu, ar_sepcu, aw_cache_allocate,
+						   aw_slc_en, aw_slb_en, ar_cache_allocate,
+						   ar_slc_en, ar_slb_en, ro, ns));
+}
+
+static void apummu_vsid_segment_enable_init(uint8_t vsid_idx)
+{
+	mmio_write_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), 0);
+}
+
+static void apummu_set_single_segment(uint8_t vsid_idx, uint8_t seg_idx)
+{
+	mmio_setbits_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), BIT(seg_idx));
+}
+
+static int apummu_enable_vsid(uint32_t vsid_idx)
+{
+	if (vsid_idx > (APUMMU_VSID_ACTIVE - 1) &&
+	    vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)) {
+		ERROR("invalid vsid index %d\n", vsid_idx);
+		return -1;
+	}
+
+	mmio_write_32(APUMMU_VSID_ENABLE_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+	mmio_write_32(APUMMU_VSID_VALID_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+
+	return 0;
+}
+
+static void apummu_enable(void)
+{
+	mmio_setbits_32(APUMMU_CMU_TOP_BASE, 0x1);
+}
+
+static void apummu_vsid_sram_config(void)
+{
+	uint32_t idx;
+	uint32_t base = (APUMMU_VSID_SRAM_TOTAL - APUMMU_VSID_RSV);
+
+	for (idx = 0; idx < APUMMU_VSID_RSV; idx++) {
+		mmio_write_32(APUMMU_VSID(APUMMU_RSV_VSID_IDX_START + idx),
+			      APUMMU_VSID_DESC(base + idx));
+		apummu_vsid_segment_enable_init(base + idx);
+	}
+}
+
+static void apummu_bind_vsid(uint32_t tcu_base, uint32_t vsid_idx, uint8_t cor_id,
+			     uint8_t hw_thread, uint8_t cor_valid, uint8_t vsid_valid)
+{
+	mmio_write_32((tcu_base + hw_thread * VSID_THREAD_SZ),
+		      (((cor_id & VSID_CORID_MASK) << VSID_CORID_OFF) |
+		       ((vsid_idx & VSID_IDX_MASK) << VSID_IDX_OFF) |
+		       ((cor_valid & VSID_VALID_MASK) << VSID_COR_VALID_OFF) |
+		       ((vsid_valid & VSID_VALID_MASK) << VSID_VALID_OFF)));
+}
+
+static int apummu_rv_bind_vsid(uint8_t hw_thread)
+{
+	uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+	if (hw_thread > APUMMU_HW_THREAD_MAX) {
+		ERROR("%s: the hw thread id (%d) is not valid for rv/logger\n", __func__,
+		       hw_thread);
+		return -EINVAL;
+	}
+
+	apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, cor_id, hw_thread,
+			 cor_valid, vsid_valid);
+
+	return 0;
+}
+
+static int apummu_apmcu_bind_vsid(uint8_t hw_thread)
+{
+	uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+	if (hw_thread > APUMMU_HW_THREAD_MAX) {
+		ERROR("%s: the hw thread id (%d) is not valid for apmcu\n", __func__, hw_thread);
+		return -EINVAL;
+	}
+
+	apummu_bind_vsid(APUMMU_RCX_EXTM_TCU_BASE, APUMMU_APMCU_RSV_VSID, cor_id, hw_thread,
+			 cor_valid, vsid_valid);
+
+	return 0;
+}
+
+static int apummu_add_map(uint32_t vsid_idx, uint8_t seg_idx, uint64_t input_adr,
+			  uint64_t output_adr, uint8_t page_sel, uint8_t page_len,
+			  uint8_t domain, uint8_t ns)
+{
+	uint8_t smmu_sid;
+	bool smmu_sec_id;
+
+	if (seg_idx > APUMMU_SEG_MAX) {
+		ERROR("seg_idx is illegal (0x%x)\n", seg_idx);
+		return -EINVAL;
+	}
+
+	smmu_sec_id = false;
+	if (ns == 0)
+		smmu_sid = SMMU_NORMAL_1_4G_SID;
+	else
+		smmu_sid = (output_adr > 0xFFFFFFFF) ? SMMU_NORMAL_4_16G_SID
+						     : SMMU_NORMAL_1_4G_SID;
+
+	/* fill segment */
+	apummu_set_segment_offset0(vsid_idx, seg_idx, (input_adr >> APUMMU_ADDR_SHIFT), 0,
+				   page_sel, page_len);
+	apummu_set_segment_offset1(vsid_idx, seg_idx, (output_adr >> APUMMU_ADDR_SHIFT),
+				   smmu_sid, 0, smmu_sec_id);
+	apummu_set_segment_offset2(vsid_idx, seg_idx, 0, domain,
+				   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ns);
+	apummu_set_single_segment(vsid_idx, seg_idx);
+
+	return 0;
+}
+
+static int apummu_get_dns(enum apusys_dev_type engine_type, enum apusys_sec_level sec_level,
+			  uint8_t *domain, uint8_t *ns)
+{
+	int ret = 0;
+
+	if (engine_type != APUSYS_DEVICE_NUM) {
+		ret = sec_get_dns(engine_type, sec_level, domain, ns);
+		if (ret)
+			ERROR("engine:%d, sec: %d\n", engine_type, sec_level);
+	} else {
+		*domain = 7;
+		*ns = 1;
+	}
+
+	return ret;
+}
+
+static void apummu_init(void)
+{
+	apummu_vsid_sram_config();
+	mmio_write_32((APU_VCORE_CONFIG_BASE + APUMMU_SSID_SID_WIDTH_CTRL),
+		      CSR_SMMU_AXMMUSID_WIDTH);
+	apummu_enable();
+}
+
+static void virtual_engine_thread(void)
+{
+	mmio_write_32((APUMMU_RCX_EXTM_TCU_BASE + APUMMU_INT_D2T_TBL0_OFS), APUMMU_THD_ID_TEE);
+}
+
+static int apummu_add_apmcu_map(uint32_t seg0_input, uint32_t seg0_output,
+				enum apummu_page_size page_size)
+{
+	int i, ret;
+	uint8_t domain, ns, seg;
+
+	ret = apummu_get_dns(APUSYS_DEVICE_NUM, SEC_LEVEL_SECURE, &domain, &ns);
+	if (ret) {
+		return ret;
+	}
+
+	seg = 0;
+	ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg, seg0_input, seg0_output, 0,
+			     page_size, domain, ns);
+	seg += 1;
+	if (ret)
+		return ret;
+
+	for (i = 0; i < 4; i++) {
+		ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg,
+				     APUSYS_TCM + (i * APUMMU_1M_SIZE),
+				     APUSYS_TCM + (i * APUMMU_1M_SIZE),
+				     0, APUMMU_PAGE_LEN_1MB, domain, ns);
+		seg += 1;
+		if (ret)
+			return ret;
+	}
+
+	ret = apummu_enable_vsid(APUMMU_APMCU_RSV_VSID);
+
+	return ret;
+}
+
+static int apummu_add_rv_boot_map(uint32_t seg0_output, uint32_t seg1_output, uint32_t seg2_output)
+{
+	int ret;
+	uint8_t domain, ns;
+
+	ret = apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &domain, &ns);
+	if (ret) {
+		ERROR("sec get dns fail %d\n", ret);
+		return ret;
+	}
+
+	/* must be in order */
+	ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 0, 0, seg0_output, 0,
+			      APUMMU_PAGE_LEN_1MB, domain, ns);
+	ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 1, 0, seg1_output, 0,
+			      APUMMU_PAGE_LEN_512MB, domain, ns);
+
+	ret |= apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &domain, &ns);
+	if (ret) {
+		return ret;
+	}
+
+	ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 2,
+			      0, seg2_output, 0, APUMMU_PAGE_LEN_4GB,
+			      domain, ns);
+	if (ret) {
+		ERROR("sec add map fail %d\n", ret);
+		return ret;
+	}
+
+	ret = apummu_enable_vsid(APUMMU_UPRV_RSV_VSID);
+
+	return ret;
+}
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+	    enum apummu_page_size logger_page_size,
+	    uint32_t XPU_seg_output, enum apummu_page_size XPU_page_size)
+{
+	int ret = 0;
+
+	apummu_init();
+
+	ret = apummu_add_rv_boot_map(uP_seg_output, 0, 0);
+	if (ret) {
+		return ret;
+	}
+
+	ret = apummu_rv_bind_vsid(uP_hw_thread);
+	if (ret)
+		return ret;
+
+	ret = apummu_rv_bind_vsid(uP_hw_thread + 1);
+	if (ret)
+		return ret;
+
+	virtual_engine_thread();
+
+	ret = apummu_add_apmcu_map(XPU_seg_output, XPU_seg_output,
+				   XPU_page_size);
+	if (ret)
+		return ret;
+
+	ret = apummu_apmcu_bind_vsid(APUMMU_THD_ID_TEE);
+
+	return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
new file mode 100644
index 0000000..61defc9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_AMMU_H
+#define APUSYS_AMMU_H
+
+#include <platform_def.h>
+
+/* CMU */
+#define APUMMU_CMU_TOP_BASE		(APU_CMU_TOP)
+#define APUMMU_CMU_TOP_TOPOLOGY		(APUMMU_CMU_TOP_BASE + 0x04)
+#define APUMMU_VSID_ENABLE_OFFSET	(0x50)
+#define APUMMU_VSID_VALID_OFFSET	(0xb0)
+
+#define VSID_OFFSET(vsid_idx)		(((vsid_idx) >> 5) * 0x4)
+
+#define APUMMU_VSID_ENABLE_BASE(vsid_idx) \
+	(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_ENABLE_OFFSET)
+#define APUMMU_VSID_VALID_BASE(vsid_idx) \
+	(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_VALID_OFFSET)
+
+/* VSID SRAM */
+#define APUMMU_VSID_BASE		(APUMMU_CMU_TOP_BASE + 0x1000)
+#define APUMMU_VSID_DESC_BASE		(APUMMU_VSID_BASE + 0x400)
+#define APUMMU_VSID_SRAM_SZIE		(0x5C00)
+#define APUMMU_VSID_TBL_SZIE		(0xF4)
+
+#define APUMMU_VSID(vsid_idx)		(APUMMU_VSID_BASE + (vsid_idx) * 4)
+#define APUMMU_VSID_DESC(vsid_idx) \
+	(APUMMU_VSID_DESC_BASE + (vsid_idx) * APUMMU_VSID_TBL_SZIE)
+
+/* TCU RCX */
+#define APU_VCORE_CONFIG_BASE		(APU_RCX_VCORE_CONFIG)
+#define APUMMU_RCX_EXTM_TCU_BASE	(APU_RCX_EXTM_TCU)
+#define APUMMU_RCX_UPRV_TCU_BASE	(APU_RCX_UPRV_TCU)
+
+#define APUMMU_SSID_SID_WIDTH_CTRL	(0xCC0)
+#define CSR_SMMU_AXMMUSID_WIDTH		BIT(7)
+#define APUMMU_1M_SIZE			(0x100000)
+
+#define SMMU_NORMAL_0_1G_SID		(0x8)
+#define SMMU_NORMAL_1_4G_SID		(0x9)
+#define SMMU_NORMAL_4_16G_SID		(0xA)
+
+enum apummu_page_size {
+	APUMMU_PAGE_LEN_128KB = 0,
+	APUMMU_PAGE_LEN_256KB,
+	APUMMU_PAGE_LEN_512KB,
+	APUMMU_PAGE_LEN_1MB,
+	APUMMU_PAGE_LEN_128MB,
+	APUMMU_PAGE_LEN_256MB,
+	APUMMU_PAGE_LEN_512MB,
+	APUMMU_PAGE_LEN_4GB,
+};
+
+#define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \
+	(APUMMU_VSID_DESC(vsid_idx) + (seg_idx) * 0xC + (seg_offset) * 0x04 + 0x4)
+
+#define APUMMU_VSID_SEGMENT_ENABLE(vsid_idx)	(APUMMU_VSID_DESC(vsid_idx))
+
+#define APUMMU_VSID_SRAM_TOTAL		(APUMMU_VSID_SRAM_SZIE / APUMMU_VSID_TBL_SZIE)
+#define APUMMU_RSV_VSID_DESC_IDX_END	(APUMMU_VSID_SRAM_TOTAL - 1)
+#define APUMMU_UPRV_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END)		/* 53 */
+#define APUMMU_LOGGER_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END - 1)
+#define APUMMU_APMCU_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END - 2)
+#define APUMMU_GPU_RSV_DESC_IDX		(APUMMU_RSV_VSID_DESC_IDX_END - 3)
+
+#define APUMMU_SEG_OFFSET_0		(0)
+#define APUMMU_SEG_OFFSET_1		(1)
+#define APUMMU_SEG_OFFSET_2		(2)
+#define APUMMU_VSID_EN_MASK		(0x1f)
+
+#define APUMMU_HW_THREAD_MAX		(7)
+#define APUMMU_SEG_MAX			(9)
+#define APUMMU_ADDR_SHIFT		(12)
+
+#define VSID_THREAD_SZ			(0x4)
+#define VSID_CORID_MASK			(0x7f)
+#define VSID_CORID_OFF			(11)
+#define VSID_IDX_MASK			(0xff)
+#define VSID_IDX_OFF			(3)
+#define VSID_VALID_MASK			(0x1)
+#define VSID_COR_VALID_OFF		(1)
+#define VSID_VALID_OFF			(0)
+
+#define APUMMU_VSID_ACTIVE		(32)
+#define APUMMU_VSID_RSV			(4)
+#define APUMMU_VSID_UNUSED		(12)
+#define APUMMU_VSID_USE_MAX		(APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV)
+
+#if ((APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) > APUMMU_VSID_SRAM_TOTAL)
+#error APUMMU VSID Overflow
+#endif
+
+#define APUMMU_RSV_VSID_IDX_END		(254)
+#define APUMMU_RSV_VSID_IDX_START	(APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)
+
+#if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV)
+#error APUMMU VSID RSV Overflow
+#endif
+
+/* Reserve */
+#define APUMMU_UPRV_RSV_VSID		(APUMMU_RSV_VSID_IDX_END)
+#define APUMMU_LOGGER_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 1)
+#define APUMMU_APMCU_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 2)
+#define APUMMU_GPU_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 3)
+
+/* VSID bit mask */
+#define APUMMU_VSID_MAX_MASK_WORD	((APUMMU_VSID_USE_MAX + 32 - 1) / 32)
+
+/* VSID fields */
+#define READ_VSID_FIELD(vids, sg, offset, shift, mask) \
+	((mmio_read_32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, offset)) >> sift) & mask)
+#define READ_VSID_FIELD_OFFESET0(vids, sg, shift, mask) \
+	READ_VSID_FIELD(vids, sg, 0, shift, mask)
+#define READ_VSID_FIELD_OFFESET1(vids, sg, shift, mask) \
+	READ_VSID_FIELD(vids, sg, 1, shift, mask)
+#define READ_VSID_FIELD_OFFESET2(vids, sg, shift, mask) \
+	READ_VSID_FIELD(vids, sg, 2, shift, mask)
+
+/* Get segment offset 0 data - 0x00 */
+#define APUMMU_SEGMENT_GET_INPUT(vsid, seg) \
+	READ_VSID_FIELD_OFFESET0(vsid, seg, 10, 0x3FFFFF)
+#define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid, seg) \
+	READ_VSID_FIELD_OFFESET0(vsid, seg, 6, 0xF)
+#define APUMMU_SEGMENT_GET_PAGELEN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET0(vsid, seg, 0, 0x7)
+#define APUMMU_SEGMENT_GET_PAGESEL(vsid, seg) \
+	READ_VSID_FIELD_OFFESET0(vsid, seg, 3, 0x7)
+
+/* Get segment offset 1 data - 0x04 */
+#define APUMMU_SEGMENT_GET_IOMMU_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET1(vsid, seg, 1, 0x1)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid, seg) \
+	READ_VSID_FIELD_OFFESET1(vsid, seg, 2, 0xFF)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid, seg) \
+	READ_VSID_FIELD_OFFESET1(vsid, seg, 0, 0x1)
+#define APUMMU_SEGMENT_GET_OUTPUT(vsid, seg) \
+	READ_VSID_FIELD_OFFESET1(vsid, seg, 10, 0x3FFFFF)
+
+/* Get segment offset 2 data - 0x08 */
+#define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 12, 0x1)
+#define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 4, 0x1)
+#define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 9, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 8, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 2, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 3, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 7, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 11, 0x1)
+#define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 10, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 5, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 6, 0x1)
+#define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 13, 0xF)
+#define APUMMU_SEGMENT_GET_NS(vsid, seg) \
+	READ_VSID_FIELD_OFFESET2(vsid, seg, 0, 0x1)
+
+/* Build segment data */
+/* Build segment offset 0 (0x00) data */
+#define APUMMU_VSID_SEGMENT_00_INPUT(input_adr)		(((input_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel)	(((page_sel) & 0x7) << 3)
+#define APUMMU_VSID_SEGMENT_00_PAGELEN(page_len)	(((page_len) & 0x7) << 0)
+#define APUMMU_VSID_SEGMENT_00_RESV(resv)		(((resv) & 0xf) << 6)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \
+				(APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \
+				 APUMMU_VSID_SEGMENT_00_RESV(resv) | \
+				 APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \
+				 APUMMU_VSID_SEGMENT_00_PAGELEN(page_len))
+
+/* Build segment offset 1 (0x04) data */
+#define APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en)	(((iommu_en) & 0x1) << 1)
+#define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr)	(((output_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_04_RESV0(resv0)		(((resv0) & 0xff) << 2)
+#define APUMMU_VSID_SEGMENT_04_RESV1(resv1)		(((resv1) & 0x1) << 0)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \
+				(APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \
+				 APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \
+				 APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) | \
+				 APUMMU_VSID_SEGMENT_04_RESV1(resv1))
+
+/* Build segment offset 2 (0x08) data */
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK	(0xf)
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT	(13)
+#define APUMMU_VSID_SEGMENT_08_RESV_MASK	(0x7fff)
+#define APUMMU_VSID_SEGMENT_08_RESV_SHIFT	(17)
+
+#define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \
+	(((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT)
+#define APUMMU_VSID_SEGMENT_08_RESV(resv) \
+	(((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << APUMMU_VSID_SEGMENT_08_RESV_SHIFT)
+
+#define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)		(((acp_en) & 0x1) << 12)
+#define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)	(((ar_exclu) & 0x1) << 9)
+#define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)	(((ar_sepcu) & 0x1) << 8)
+#define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)	(((ar_slb_en) & 0x1) << 2)
+#define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)	(((ar_slc_en) & 0x1) << 3)
+#define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)		(((aw_clr) & 0x1) << 11)
+#define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)	(((aw_invalid) & 0x1) << 10)
+#define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)	(((aw_slb_en) & 0x1) << 5)
+#define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)	(((aw_slc_en) & 0x1) << 6)
+#define APUMMU_VSID_SEGMENT_08_NS(ns)			(((ns) & 0x1) << 0)
+#define APUMMU_VSID_SEGMENT_08_RO(ro)			(((ro) & 0x1) << 1)
+
+#define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \
+	(((ar_cache_allocate) & 0x1) << 4)
+#define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \
+	(((aw_cache_allocate) & 0x1) << 7)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \
+		aw_invalid, ar_exclu, ar_sepcu, \
+		aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \
+		ar_slc_en, ar_slb_en, ro, ns) \
+		((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\
+		 (APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\
+		 (APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\
+		 (APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\
+		 (APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\
+		 (APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\
+		 (APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\
+		 (APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\
+		 (APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\
+		 (APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\
+		 (APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\
+		 (APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\
+		 (APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\
+		 (APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns)))
+
+/* Build segment offset 3 (0x0c) data */
+#define APUMMU_VSID_SEGMENT_0C_RESV(rsv)		(((rsv) & 0x7fffffff) << 0)
+#define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid)	(((seg_valid) & 0x1U) << 31)
+#define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \
+	((uint32_t)APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \
+	 APUMMU_VSID_SEGMENT_0C_RESV(rsv))
+
+#define APUMMU_INT_D2T_TBL0_OFS	(0x40)
+
+#define APUSYS_TCM		(0x4d100000)
+
+enum {
+	APUMMU_THD_ID_APMCU_NORMAL = 0,
+	APUMMU_THD_ID_TEE,
+};
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+	    enum apummu_page_size logger_page_size, uint32_t XPU_seg_output,
+	    enum apummu_page_size XPU_page_size);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c
new file mode 100644
index 0000000..09e35f1
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#include <apusys_devapc.h>
+#include <apusys_devapc_def.h>
+#include <mtk_mmap_pool.h>
+
+/* AO CONTROL DEVAPC - apu_rcx_ao_infra_dapc_con */
+static const struct apc_dom_16 APUSYS_CTRL_DAPC_AO[] = {
+	/* ctrl index = 0 */
+	SLAVE_RCX_BULK0("apu_ao_ctl_o-0"),
+	SLAVE_MD32_APB("apu_ao_ctl_o-1"),
+	SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-2"),
+	SLAVE_PTP_THM("apu_ao_ctl_o-3"),
+	SLAVE_VCORE("apu_ao_ctl_o-4"),
+	SLAVE_IOMMU0_BANK0("apu_ao_ctl_o-5"),
+	SLAVE_IOMMU0_BANK1("apu_ao_ctl_o-6"),
+	SLAVE_IOMMU0_BANK2("apu_ao_ctl_o-7"),
+	SLAVE_IOMMU0_BANK3("apu_ao_ctl_o-8"),
+	SLAVE_IOMMU0_BANK4("apu_ao_ctl_o-9"),
+
+	/* ctrl index = 10 */
+	SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-10"),
+	SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-11"),
+	SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-12"),
+	SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-13"),
+	SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-14"),
+	SLAVE_S0_SSC("apu_ao_ctl_o-15"),
+	SLAVE_N0_SSC("apu_ao_ctl_o-16"),
+	SLAVE_S1_SSC("apu_ao_ctl_o-17"),
+	SLAVE_N1_SSC("apu_ao_ctl_o-18"),
+	SLAVE_ACP_SSC("apu_ao_ctl_o-19"),
+
+	/* ctrl index = 20 */
+	SLAVE_WDEC("apu_ao_ctl_o-20"),
+	SLAVE_SMMU_IP_REG("apu_ao_ctl_o-21"),
+	SLAVE_SMMU_NSEC("apu_ao_ctl_o-22"),
+	SLAVE_SMMU_SEC("apu_ao_ctl_o-23"),
+	SLAVE_ARE0("apu_ao_ctl_o-24"),
+	SLAVE_ARE1("apu_ao_ctl_o-25"),
+	SLAVE_SONC("apu_ao_ctl_o-26"),
+	SLAVE_RPC("apu_ao_ctl_o-28"),
+	SLAVE_PCU("apu_ao_ctl_o-29"),
+	SLAVE_AO_CTRL("apu_ao_ctl_o-30"),
+
+	/* ctrl index = 30 */
+	SLAVE_AO_CTRL("apu_ao_ctl_o-31"),
+	SLAVE_ACC("apu_ao_ctl_o-32"),
+	SLAVE_SEC("apu_ao_ctl_o-33"),
+	SLAVE_PLL("apu_ao_ctl_o-34"),
+	SLAVE_RPC_MDLA("apu_ao_ctl_o-35"),
+	SLAVE_TOP_PMU("apu_ao_ctl_o-36"),
+	SLAVE_AO_BCRM("apu_ao_ctl_o-37"),
+	SLAVE_AO_DAPC_WRAP("apu_ao_ctl_o-38"),
+	SLAVE_AO_DAPC_CON("apu_ao_ctl_o-39"),
+	SLAVE_UNDEFINE0("apu_ao_ctl_o-40"),
+
+	/* ctrl index = 40 */
+	SLAVE_UNDEFINE1("apu_ao_ctl_o-41"),
+	SLAVE_RCX_BULK0("apu_ao_ctl_o-42"),
+	SLAVE_UNDEFINE2("apu_ao_ctl_o-43"),
+	SLAVE_UNDEFINE3("apu_ao_ctl_o-44"),
+	SLAVE_UNDEFINE4("apu_ao_ctl_o-45"),
+	SLAVE_UNDEFINE5("apu_ao_ctl_o-46"),
+	SLAVE_UNDEFINE6("apu_ao_ctl_o-47"),
+	SLAVE_UNDEFINE7("apu_ao_ctl_o-48"),
+	SLAVE_DATA_BULK("apu_ao_ctl_o-49"),
+	SLAVE_ACX0_BULK("apu_ao_ctl_o-50"),
+
+	/* ctrl index = 50 */
+	SLAVE_ACX0_AO("apu_ao_ctl_o-51"),
+	SLAVE_ACX1_BULK("apu_ao_ctl_o-52"),
+	SLAVE_ACX1_AO("apu_ao_ctl_o-53"),
+	SLAVE_NCX_BULK("apu_ao_ctl_o-54"),
+	SLAVE_NCX_AO("apu_ao_ctl_o-55"),
+	SLAVE_ACX0_BULK("apu_rcx2acx0_o-0"),
+	SLAVE_ACX0_AO("apu_rcx2acx0_o-1"),
+	SLAVE_ACX0_BULK("apu_sae2acx0_o-0"),
+	SLAVE_ACX0_AO("apu_sae2acx0_o-1"),
+	SLAVE_ACX1_BULK("apu_rcx2acx1_o-0"),
+
+	/* ctrl index = 60 */
+	SLAVE_ACX1_AO("apu_rcx2acx1_o-1"),
+	SLAVE_ACX1_BULK("apu_sae2acx1_o-0"),
+	SLAVE_ACX1_AO("apu_sae2acx1_o-1"),
+	SLAVE_NCX_BULK("apu_rcx2ncx_o-0"),
+	SLAVE_NCX_AO("apu_rcx2ncx_o-1"),
+	SLAVE_NCX_BULK("apu_sae2ncx_o-0"),
+	SLAVE_NCX_AO("apu_sae2ncx_o-1"),
+};
+
+
+/* RCX CONTROL DEVAPC - apu_rcx_infra_dapc_con */
+static const struct apc_dom_16 APUSYS_CTRL_DAPC_RCX[] = {
+	/* ctrl index = 0 */
+	SLAVE_ACX0_BULK("acx0_apbs-0"),
+	SLAVE_ACX0_RPC("acx0_apbs-1"),
+	SLAVE_ACX0_AO_CTRL("acx0_apbs-2"),
+	SLAVE_UNDEFINE8("acx0_apbs-3"),
+	SLAVE_ACX1_BULK("acx1_apbs-0"),
+	SLAVE_ACX1_RPC("acx1_apbs-1"),
+	SLAVE_ACX1_AO_CTRL("acx1_apbs-2"),
+	SLAVE_UNDEFINE9("acx1_apbs-3"),
+	SLAVE_NCX_BULK("ncx_apbs-0"),
+	SLAVE_NCX_RPC("ncx_apbs-1"),
+
+	/* ctrl index = 10 */
+	SLAVE_NCX_AO_CTRL("ncx_apbs-2"),
+	SLAVE_UNDEFINE10("ncx_apbs-3"),
+	SLAVE_MD32_SYSCTRL("md32_apb_s-0"),
+	SLAVE_MD32_PMU("md32_apb_s-1"),
+	SLAVE_MD32_WDT("md32_apb_s-2"),
+	SLAVE_MD32_CACHE("md32_apb_s-3"),
+	SLAVE_ARE0("apusys_ao-0"),
+	SLAVE_ARE1("apusys_ao-1"),
+	SLAVE_SONC("apusys_ao-2"),
+	SLAVE_RPC("apusys_ao-3"),
+
+	/* ctrl index = 20 */
+	SLAVE_PCU("apusys_ao-4"),
+	SLAVE_AO_CTRL("apusys_ao-5"),
+	SLAVE_AO_CTRL("apusys_ao-6"),
+	SLAVE_SEC("apusys_ao-7"),
+	SLAVE_PLL("apusys_ao-8"),
+	SLAVE_RPC_MDLA("apusys_ao-9"),
+	SLAVE_TOP_PMU("apusys_ao-10"),
+	SLAVE_AO_BCRM("apusys_ao-11"),
+	SLAVE_AO_DAPC_WRAP("apusys_ao-12"),
+	SLAVE_AO_DAPC_CON("apusys_ao-13"),
+
+	/* ctrl index = 30 */
+	SLAVE_VCORE("apusys_ao-14"),
+	SLAVE_IOMMU0_BANK0("apusys_ao-15"),
+	SLAVE_IOMMU0_BANK1("apusys_ao-16"),
+	SLAVE_IOMMU0_BANK2("apusys_ao-17"),
+	SLAVE_IOMMU0_BANK3("apusys_ao-18"),
+	SLAVE_IOMMU0_BANK4("apusys_ao-19"),
+	SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-20"),
+	SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-21"),
+	SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-22"),
+	SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-23"),
+
+	/* ctrl index = 40 */
+	SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-24"),
+	SLAVE_S0_SSC("apu_ao_ctl_o-25"),
+	SLAVE_N0_SSC("apu_ao_ctl_o-26"),
+	SLAVE_S1_SSC("apu_ao_ctl_o-27"),
+	SLAVE_N1_SSC("apu_ao_ctl_o-28"),
+	SLAVE_ACP_SSC("apu_ao_ctl_o-29"),
+	SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-30"),
+	SLAVE_PTP_THM("apu_ao_ctl_o-31"),
+	SLAVE_WDEC("apu_ao_ctl_o-32"),
+	SLAVE_SMMU_IP_REG("apu_ao_ctl_o-33"),
+
+	/* ctrl index = 50 */
+	SLAVE_SMMU_NSEC("apu_ao_ctl_o-34"),
+	SLAVE_SMMU_SEC("apu_ao_ctl_o-35"),
+	SLAVE_DATA_BULK("noc_axi"),
+	SLAVE_MD32_DBG("md32_dbg"),
+	SLAVE_MDLA_DBG("mdla_dbg"),
+	SLAVE_INFRA_DBG("apb_infra_dbg"),
+	SLAVE_LOG_TOP0("apu_logtop-0"),
+	SLAVE_LOG_TOP1("apu_logtop-1"),
+	SLAVE_RCX_CFG("apu_rcx_cfg"),
+	SLAVE_ACX_IPS("apu_acx_ips"),
+
+	/* ctrl index = 60 */
+	SLAVE_SEMA_STIMER("apu_sema_stimer"),
+	SLAVE_EMI_CFG("apu_emi_cfg"),
+	SLAVE_CPE_SENSOR("apu_cpe_sensor"),
+	SLAVE_CPE_COEF("apu_cpe_coef"),
+	SLAVE_CPE_CTRL("apu_cpe_ctrl"),
+	SLAVE_TPPA("apu_dfd"),
+	SLAVE_SENSOR_ACX0_DLA0("apu_sen_acx0_dla0"),
+	SLAVE_SENSOR_ACX0_VPU("apu_sen_acx0_vpu"),
+	SLAVE_SENSOR_ACX1_DLA0("apu_sen_acx1_dla0"),
+	SLAVE_SENSOR_ACX1_VPU("apu_sen_acx1_vpu"),
+
+	/* ctrl index = 70 */
+	SLAVE_SENSOR_NCX_DLA0("apu_sen_ncx_dla0"),
+	SLAVE_SENSOR_NCX_NVE("apu_sen_ncx_nve"),
+	SLAVE_RCX_TCU0("noc_cfg-0"),
+	SLAVE_RCX_TCU1("noc_cfg-1"),
+	SLAVE_RCX_TCU2("noc_cfg-2"),
+	SLAVE_RCX_TCU3("noc_cfg-3"),
+	SLAVE_RCX_TCU4("noc_cfg-4"),
+	SLAVE_RCX_TCU5("noc_cfg-5"),
+	SLAVE_RCX_TCU6("noc_cfg-6"),
+	SLAVE_RCX_NOC_CFG("noc_cfg-7"),
+
+	/* ctrl index = 80 */
+	SLAVE_SCMDQ("apu_hse-0"),
+	SLAVE_HSE("apu_hse-1"),
+	SLAVE_MDLA_CORE_CTRL("mdla_cfg-0"),
+	SLAVE_MDLA_BIU("mdla_cfg-1"),
+	SLAVE_MDLA_PMU("mdla_cfg-2"),
+	SLAVE_MDLA_CMDE("mdla_cfg-3"),
+	SLAVE_EDPA0("apu_edpa-0"),
+	SLAVE_EDPA1("apu_edpa-1"),
+	SLAVE_RCX_BCRM("infra_bcrm"),
+	SLAVE_RCX_DAPC_WRAP("infra_dpac_wrap"),
+
+	/* ctrl index = 90 */
+	SLAVE_RCX_DAPC_CON("infra_dapc_con"),
+	SLAVE_RCX_CMU("rcx_cmu"),
+	SLAVE_RCX_ACS("apu_rcx_acs"),
+	SLAVE_RCX_CBFC("rcx_cbfc"),
+	SLAVE_ACC("acc"),
+};
+
+static enum apusys_apc_err_status set_slave_ctrl_apc(uint32_t slave,
+						     enum apusys_apc_type type,
+						     enum apusys_apc_domain_id domain_id,
+						     enum apusys_apc_perm_type perm)
+{
+	uint32_t apc_register_index;
+	uint32_t apc_set_index;
+	uint32_t base = 0;
+	uint32_t clr_bit;
+	uint32_t set_bit;
+	uint32_t slave_num_in_1_dom;
+	uint32_t slave_num, dom_num;
+	uint32_t dapc_base;
+
+	if (perm >= PERM_NUM) {
+		ERROR("%s: permission type:0x%x is not supported!\n", __func__, perm);
+		return APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED;
+	}
+
+	switch (type) {
+	case DAPC_AO:
+		slave_num_in_1_dom = APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM;
+		slave_num = APUSYS_CTRL_DAPC_AO_SLAVE_NUM;
+		dom_num = APUSYS_CTRL_DAPC_AO_DOM_NUM;
+		dapc_base = APUSYS_CTRL_DAPC_AO_BASE;
+		break;
+	case DAPC_RCX:
+		slave_num_in_1_dom = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+		slave_num = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM;
+		dom_num = APUSYS_CTRL_DAPC_RCX_DOM_NUM;
+		dapc_base = APUSYS_CTRL_DAPC_RCX_BASE;
+		break;
+	default:
+		ERROR("%s: unsupported devapc type: %u\n", __func__, type);
+		return APUSYS_APC_ERR_GENERIC;
+	}
+
+	apc_register_index = slave / slave_num_in_1_dom;
+	apc_set_index = slave % slave_num_in_1_dom;
+
+	clr_bit = DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT);
+	set_bit = (uint32_t)perm << (apc_set_index * DEVAPC_DOM_SHIFT);
+
+	if (slave < slave_num && domain_id < dom_num) {
+		base = dapc_base + domain_id * DEVAPC_DOM_SIZE
+		       + apc_register_index * DEVAPC_REG_SIZE;
+	} else {
+		ERROR("%s: out of boundary, devapc type: %d, slave: 0x%x, domain_id: 0x%x\n",
+			__func__, type, slave, domain_id);
+		return APUSYS_APC_ERR_OUT_OF_BOUNDARY;
+	}
+
+	if (!base)
+		return APUSYS_APC_ERR_GENERIC;
+
+	mmio_clrsetbits_32(base, clr_bit, set_bit);
+	return APUSYS_APC_OK;
+}
+
+static enum apusys_apc_err_status set_slave_ao_ctrl_apc(uint32_t slave,
+							enum apusys_apc_domain_id domain_id,
+							enum apusys_apc_perm_type perm)
+{
+	return set_slave_ctrl_apc(slave, DAPC_AO, domain_id, perm);
+}
+
+static enum apusys_apc_err_status set_slave_rcx_ctrl_apc(uint32_t slave,
+							 enum apusys_apc_domain_id domain_id,
+							 enum apusys_apc_perm_type perm)
+{
+	return set_slave_ctrl_apc(slave, DAPC_RCX, domain_id, perm);
+}
+
+static void apusys_devapc_init(uint32_t base)
+{
+	mmio_write_32(APUSYS_DAPC_CON(base), APUSYS_DAPC_CON_VIO_MASK);
+}
+
+int apusys_devapc_ao_init(void)
+{
+	int32_t ret = APUSYS_APC_OK;
+
+	apusys_devapc_init(APUSYS_CTRL_DAPC_AO_BASE);
+
+	ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO, set_slave_ao_ctrl_apc);
+
+	if (ret) {
+		ERROR("[APUAPC_AO] %s: set_apusys_ao_ctrl_dapc failed\n", __func__);
+		return ret;
+	}
+
+#ifdef DUMP_CFG
+	DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO);
+#endif
+
+	INFO("[APUAPC_AO] %s done\n", __func__);
+
+	return ret;
+}
+
+int apusys_devapc_rcx_init(void)
+{
+	int32_t ret = APUSYS_APC_OK;
+
+	apusys_devapc_init(APUSYS_CTRL_DAPC_RCX_BASE);
+
+	ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX, set_slave_rcx_ctrl_apc);
+	if (ret) {
+		ERROR("[APUAPC_RCX] %s: set_slave_rcx_ctrl_apc failed\n", __func__);
+		return ret;
+	}
+
+#ifdef DUMP_CFG
+	DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX);
+#endif
+
+	INFO("[APUAPC_RCX] %s done\n", __func__);
+
+	return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h
new file mode 100644
index 0000000..8d6204e
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_H
+#define APUSYS_DEVAPC_H
+
+enum apusys_apc_type {
+	DAPC_AO = 0,
+	DAPC_RCX
+};
+
+int apusys_devapc_ao_init(void);
+int apusys_devapc_rcx_init(void);
+
+#endif /* APUSYS_DEVAPC_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h
new file mode 100644
index 0000000..af63c0c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_DEF_H
+#define APUSYS_DEVAPC_DEF_H
+
+#include <lib/mmio.h>
+
+#include <devapc/apusys_dapc_v1.h>
+
+/* Control */
+#define SLAVE_RCX_BULK0		SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
+#define SLAVE_RCX_BULK1		SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW
+#define SLAVE_MD32_APB		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_ACP_TCU_SSC	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_VCORE		SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
+#define SLAVE_WDEC		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_SMMU_IP_REG	SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT
+#define SLAVE_SMMU_NSEC		SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT
+#define SLAVE_SMMU_SEC		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RPC		SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT
+#define SLAVE_PCU		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_AO_CTRL		SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_ACC		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_PLL		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW
+#define SLAVE_SEC		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_ARE0		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ARE1		SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
+#define SLAVE_RPC_MDLA		SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_MDLA_DBG		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_TOP_PMU		SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_UNDEFINE0		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE1		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE2		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE3		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE4		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE5		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE6		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE7		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE8		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE9		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE10	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_DATA_BULK		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_AO_BCRM		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_AO_DAPC_WRAP	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_AO_DAPC_CON	SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_ACX0_AO		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_BULK		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_RPC		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_AO_CTRL	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_ACX1_AO		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_BULK		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_RPC		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_AO_CTRL	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_NCX_AO		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_NCX_BULK		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_NCX_RPC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_NCX_AO_CTRL	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MD32_SYSCTRL	SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_MD32_PMU		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_LOG_TOP0		SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT
+#define SLAVE_LOG_TOP1		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CFG		SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
+#define SLAVE_ACX_IPS		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU0		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_TCU1		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_TCU2		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU3		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU4		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU5		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU6		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_NOC_CFG	SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MDLA_CORE_CTRL	SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MDLA_BIU		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MDLA_PMU		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MDLA_CMDE		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_EDPA0		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_EDPA1		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CMU		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_ACS		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MD32_WDT		SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_MD32_CACHE	SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MD32_DBG		SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
+#define SLAVE_INFRA_DBG		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK0	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK1	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK2	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK3	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK4	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK0	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK1	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK2	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK3	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK4	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_S0_SSC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_N0_SSC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_ACP_SSC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_S1_SSC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_N1_SSC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SEMA_STIMER	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_EMI_CFG		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_SENSOR	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_COEF		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_CTRL		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_TPPA		SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_SENSOR_ACX0_DLA0	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX0_VPU	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX1_DLA0	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX1_VPU	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_NCX_DLA0	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_NCX_NVE	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_BCRM		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_DAPC_WRAP	SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_DAPC_CON	SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_HSE		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CBFC		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SONC		SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_SCMDQ		SLAVE_FORBID_EXCEPT_D5_SEC_RW
+
+#if DEBUG
+#define SLAVE_PTP_THM		SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
+#else
+#define SLAVE_PTP_THM		SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#endif
+
+/* Power Domain: AO */
+#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM	(16)
+#define APUSYS_CTRL_DAPC_AO_DOM_NUM		(16)
+#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM		(67)	/* 0~66 */
+#define DEVAPC_MASK				(0x3U)
+#define DEVAPC_DOM_SHIFT			(2)
+
+/* Power Domain: RCX */
+#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM	(16)
+#define APUSYS_CTRL_DAPC_RCX_DOM_NUM		(16)
+#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM		(95)	/* 0~94 */
+
+/* Dump Config */
+#define DUMP_CFG
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_power.c b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
new file mode 100644
index 0000000..4262d63
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+#define SPMI_ENABLE	(0)
+
+#if SPMI_ENABLE
+#include <include/drivers/spmi_api.h>
+#endif
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "apusys_power.h"
+
+static void apu_w_are(int entry, uint32_t reg, uint32_t data)
+{
+	uint32_t are_entry_addr;
+
+	are_entry_addr = APUSYS_BASE + APU_ARE + ARE_REG_SIZE * ARE_ENTRY(entry);
+	mmio_write_32(are_entry_addr, reg);
+	mmio_write_32((are_entry_addr + ARE_REG_SIZE), data);
+}
+
+static void get_pll_pcw(uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
+{
+	unsigned int fvco = clk_rate;
+	unsigned int pcw_val;
+	unsigned int postdiv_val = 1;
+	unsigned int postdiv_reg = 0;
+
+	while (fvco <= OUT_CLK_FREQ_MIN) {
+		postdiv_val = postdiv_val << 1;
+		postdiv_reg = postdiv_reg + 1;
+		fvco = fvco << 1;
+	}
+
+	pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ;
+
+	if (postdiv_reg == 0) {
+		pcw_val = pcw_val * 2;
+		postdiv_val = postdiv_val << 1;
+		postdiv_reg = postdiv_reg + 1;
+	}
+
+	*r1 = postdiv_reg;
+	*r2 = pcw_val;
+}
+
+static void buck_off_by_pcu(uint32_t ofs, uint32_t shift, uint32_t slv_id)
+{
+	uint32_t pmif_id = 0x0;
+	int retry = 10;
+
+	mmio_setbits_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, PMIC_IRQ_EN);
+	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF1,
+		      (ofs << PMIC_OFF_ADDR_OFF) | BIT(shift));
+	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF2,
+		      (slv_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_BUCK_OFF_CMD);
+	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_CMD, PMIC_CMD_EN);
+
+	while ((mmio_read_32(APUSYS_PCU + APU_PCU_PMIC_IRQ) & PMIC_CMD_IRQ) == 0) {
+		udelay(10);
+		if (--retry < 0)
+			ERROR("%s wait APU_PCU_PMIC_IRQ timeout !\n", __func__);
+	}
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_IRQ, PMIC_CMD_IRQ);
+}
+
+static void apu_buck_off_cfg(void)
+{
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
+
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_LHENB_SET);
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_ISO_SET);
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, PLL_AOC_ISO_EN_SET);
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
+	udelay(1);
+
+	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
+	udelay(1);
+
+	buck_off_by_pcu(BUCK_VAPU_PMIC_REG_EN_CLR_ADDR, BUCK_VAPU_PMIC_REG_EN_SHIFT,
+			BUCK_VAPU_PMIC_ID);
+
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
+	udelay(1);
+	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
+	udelay(1);
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
+	udelay(1);
+	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
+	udelay(1);
+}
+
+static void apu_acc_init(void)
+{
+	uint32_t top_acc_base_arr[] = {MNOC_ACC_BASE, UP_ACC_BASE};
+	uint32_t eng_acc_base_arr[] = {MVPU_ACC_BASE, MDLA_ACC_BASE};
+	int acc_idx;
+	int are_idx = ACC_ENTRY_BEGIN;
+	uint32_t base_reg;
+
+	for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(top_acc_base_arr) ; acc_idx++) {
+		base_reg = APUSYS_ACC + top_acc_base_arr[acc_idx];
+#if CFG_APU_ARDCM_ENABLE
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
+#endif
+		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
+		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
+	}
+
+	for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(eng_acc_base_arr) ; acc_idx++) {
+		base_reg = APUSYS_ACC + eng_acc_base_arr[acc_idx];
+#if CFG_APU_ARDCM_ENABLE
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
+		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
+#endif
+		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
+		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
+		apu_w_are(are_idx++, base_reg + APU_ACC_AUTO_CTRL_SET0, CLK_REQ_SW_EN);
+	}
+}
+
+static void apu_pll_init(void)
+{
+	uint32_t pll_base_arr[] = {MNOC_PLL_BASE, UP_PLL_BASE, MVPU_PLL_BASE, MDLA_PLL_BASE};
+	int32_t pll_freq_out[] = {
+		APUPLL0_DEFAULT_FREQ,
+		APUPLL1_DEFAULT_FREQ,
+		APUPLL2_DEFAULT_FREQ,
+		APUPLL3_DEFAULT_FREQ
+	};
+	uint32_t pcw_val, posdiv_val;
+	int pll_idx, are_idx;
+	uint32_t base_reg;
+
+	mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_RCX_AO_EN);
+	mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_RCX_AO_EN);
+
+	mmio_write_32(APUSYS_BASE + APU_ARE + ARE_RCX_AO_CONFIG, ARE_ENTRY(RCX_AO_BEGIN) |
+		      (ARE_ENTRIES(RCX_AO_BEGIN, RCX_AO_END) << ARE_RCX_AO_CONFIG_HIGH_OFF));
+
+	are_idx = PLL_ENTRY_BEGIN;
+	for (pll_idx = 0 ; pll_idx < ARRAY_SIZE(pll_base_arr) ; pll_idx++) {
+		base_reg = APUSYS_PLL + pll_base_arr[pll_idx];
+
+		apu_w_are(are_idx++, base_reg + RG_PLLGP_LVR_REFSEL, RG_PLLGP_LVR_REFSEL_VAL);
+		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_HP_EN, FHCTL_CTRL);
+		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_RST_CON, FHCTL_NO_RESET);
+		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_CLK_CON, FHCTL_CLKEN);
+		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_CFG,
+			  FHCTL_HOPPING_EN | FHCTL_SFSTR0_EN);
+
+		posdiv_val = 0;
+		pcw_val = 0;
+		get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val);
+
+		apu_w_are(are_idx++, base_reg + PLL1C_PLL1_CON1,
+			  ((0x1U << RG_PLL_SDM_PCW_CHG_OFF) |
+			   (posdiv_val << RG_PLL_POSDIV_OFF) | pcw_val));
+
+		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_DDS,
+			  ((0x1U << FHCTL0_PLL_TGL_ORG) | pcw_val));
+	}
+}
+
+static void apu_are_init(void)
+{
+	int entry = 0;
+
+	mmio_clrbits_32(APUSYS_BASE + APU_ARE, 0xFFFU << ARE_VCORE_OFF);
+
+	mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_VCORE_EN);
+	mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_VCORE_EN);
+
+	for (entry = ARE_CONF_START; entry < ARE_CONF_END; entry += 4)
+		mmio_write_32(APUSYS_BASE + APU_ARE + entry, 0);
+}
+
+static void apu_rpclite_init(void)
+{
+	uint32_t sleep_type_offset[] = {
+		APU_RPC_SW_TYPE1_OFF,
+		APU_RPC_SW_TYPE2_OFF,
+		APU_RPC_SW_TYPE3_OFF,
+		APU_RPC_SW_TYPE4_OFF
+	};
+	uint32_t rpc_lite_base[] = {
+		APU_ACX0_RPC_LITE,
+		APU_ACX1_RPC_LITE,
+		APU_ACX2_RPC_LITE,
+	};
+	int ofs_idx, rpc_lite_idx;
+	uint32_t base;
+
+	for (rpc_lite_idx = 0; rpc_lite_idx < ARRAY_SIZE(rpc_lite_base); rpc_lite_idx++) {
+		base = APUSYS_BASE + rpc_lite_base[rpc_lite_idx];
+		for (ofs_idx = 0; ofs_idx < ARRAY_SIZE(sleep_type_offset); ofs_idx++)
+			mmio_clrbits_32(base + sleep_type_offset[ofs_idx],
+					SW_TYPE_MVPU_MDLA_RV);
+		mmio_setbits_32(base + APU_RPC_TOP_SEL, TOP_SEL_VAL);
+	}
+}
+
+static void apu_rpc_mdla_init(void)
+{
+	mmio_clrbits_32(APUSYS_BASE + APU_RPCTOP_MDLA + APU_RPC_SW_TYPE0_OFF, SW_TYPE_MVPU_MDLA_RV);
+}
+
+static void apu_rpc_init(void)
+{
+	mmio_write_32(APUSYS_RPC + APU_RPC_SW_TYPE0_OFF, RPC_TYPE_INIT_VAL);
+	mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, RPC_TOP_SEL_VAL);
+
+#if !CFG_CTL_RPC_BY_CE
+	mmio_clrbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, CE_ENABLE);
+#endif
+
+	mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL_1, BUCK_PROT_SEL);
+}
+
+static int apu_pcu_init(void)
+{
+	uint32_t pmif_id = 0x0;
+	uint32_t slave_id = BUCK_VAPU_PMIC_ID;
+	uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR;
+	uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR;
+	uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT;
+#if SPMI_ENABLE
+	struct spmi_device *vsram_sdev;
+#endif
+	unsigned char vsram = 0;
+
+	mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN);
+
+	mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL);
+
+#if SPMI_ENABLE
+	vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
+	if (!vsram_sdev) {
+		ERROR("[APUPW] VSRAM BUCK4 get device fail\n");
+		return -1;
+	}
+
+	if (spmi_ext_register_readl(vsram_sdev, MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR, &vsram, 1)) {
+		ERROR("[APUPW] VSRAM BUCK4 read fail\n");
+		return -1;
+	}
+#endif
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L,
+		      (BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram);
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_H,
+		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_L,
+		      (en_set_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_H,
+		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_L,
+		      (en_clr_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_H,
+		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE0, 0);
+	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE1, VAPU_BUCK_ON_SETTLE_TIME);
+
+	return 0;
+}
+
+static void apu_aoc_init(void)
+{
+	uint32_t reg;
+
+	mmio_setbits_32(SPM_BASE + 0xF6C, BIT(4));
+	mmio_clrbits_32(SPM_BASE + 0x414, BIT(1));
+
+	mmio_write_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CONFIG, APUSYS_AO_SRAM_EN);
+	udelay(1);
+
+	reg = APUSYS_AO_CTL + APUSYS_AO_SRAM_SET;
+
+#if !CFG_CTL_RPC_BY_CE
+	mmio_setbits_32(reg, BIT(8));
+	udelay(1);
+	mmio_setbits_32(reg, BIT(11));
+	udelay(1);
+	mmio_setbits_32(reg, BIT(13));
+	udelay(1);
+
+	mmio_clrbits_32(reg, BIT(8));
+	udelay(1);
+	mmio_clrbits_32(reg, BIT(11));
+	udelay(1);
+	mmio_clrbits_32(reg, BIT(13));
+#else
+	mmio_setbits_32(reg, BIT(9));
+	mmio_setbits_32(reg, BIT(12));
+	mmio_setbits_32(reg, BIT(14));
+
+	mmio_clrbits_32(reg, BIT(9));
+	mmio_clrbits_32(reg, BIT(12));
+	mmio_clrbits_32(reg, BIT(14));
+	udelay(1);
+#endif
+
+	reg = APUSYS_RPC + APU_RPC_HW_CON;
+
+	mmio_write_32(reg, BUCK_ELS_EN_CLR);
+	udelay(1);
+
+	mmio_write_32(reg, BUCK_AO_RST_B_SET);
+	udelay(1);
+
+	mmio_write_32(reg, BUCK_PROT_REQ_CLR);
+	udelay(1);
+
+	mmio_write_32(reg, SRAM_AOC_ISO_CLR);
+	udelay(1);
+
+	mmio_write_32(reg, PLL_AOC_ISO_EN_CLR);
+	udelay(1);
+}
+
+static int init_hw_setting(void)
+{
+	int ret;
+
+	apu_aoc_init();
+	ret = apu_pcu_init();
+	apu_rpc_init();
+	apu_rpc_mdla_init();
+	apu_rpclite_init();
+	apu_are_init();
+	apu_pll_init();
+	apu_acc_init();
+	apu_buck_off_cfg();
+
+	return ret;
+}
+
+int apusys_power_init(void)
+{
+	int ret;
+
+	ret = init_hw_setting();
+	if (ret != 0)
+		ERROR("%s init HW failed\n", __func__);
+	else
+		INFO("%s init HW done\n", __func__);
+
+	mmio_write_32(APU_ACE_HW_FLAG_DIS, APU_ACE_DIS_FLAG_VAL);
+
+	return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_power.h b/plat/mediatek/drivers/apusys/mt8196/apusys_power.h
new file mode 100644
index 0000000..ddf35c5
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_power.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_POWER_H
+#define APUSYS_POWER_H
+
+#include <platform_def.h>
+
+#define CFG_APU_ARDCM_ENABLE	(0)
+#define CFG_CTL_RPC_BY_CE	(1)
+
+#define APUPLL0_DEFAULT_FREQ	(800)
+#define APUPLL1_DEFAULT_FREQ	(960)
+#define APUPLL2_DEFAULT_FREQ	(1200)
+#define APUPLL3_DEFAULT_FREQ	(1230)
+
+enum t_acx_id {
+	D_ACX0 = 0,
+	ACX0,
+	ACX1,
+	ACX2,
+	CLUSTER_NUM,
+	RCX,
+};
+
+enum rcx_ao_range {
+	RCX_AO_BEGIN = 0,
+	PLL_ENTRY_BEGIN = 0,
+	PLL_ENTRY_END = 27,
+	ACC_ENTRY_BEGIN = 28,
+	ACC_ENTRY_END = 37,
+	RCX_AO_END = 37,
+};
+
+#define SYS_VLP			(0x000000)
+#define SYS_SPM			(0x000000)
+#define APU_RCX			(0x020000)
+#define APU_RCX_DLA		(0x040000)
+#define APU_ARE			(0x0a0000)
+#define APU_ARE_REG		(0x0b0000)
+#define APU_VCORE		(0x0e0000)
+#define APU_MD32_MBOX		(0x0e1000)
+#define APU_RPC			(0x0f0000)
+#define APU_PCU			(0x0f1000)
+#define APU_AO_CTL		(0x0f2000)
+#define APU_ACC			(0x0f3000)
+#define APU_PLL			(0x0f6000)
+#define APU_RPCTOP_MDLA		(0x0F7400)
+#define APU_ACX0		(0x100000)
+#define APU_ACX0_RPC_LITE	(0x140000)
+#define APU_ACX1		(0x200000)
+#define APU_ACX1_RPC_LITE	(0x240000)
+#define APU_ACX2		(0x300000)
+#define APU_ACX2_RPC_LITE	(0x340000)
+
+/* APU GRP offset define */
+#define APU_GRP_0_BASE		(0x0000)
+#define APU_GRP_1_BASE		(0x0400)
+#define APU_GRP_2_BASE		(0x0800)
+#define APU_GRP_3_BASE		(0x0C00)
+
+#define MDLA_PLL_BASE		APU_GRP_0_BASE
+#define MVPU_PLL_BASE		APU_GRP_1_BASE
+#define MNOC_PLL_BASE		APU_GRP_2_BASE
+#define UP_PLL_BASE		APU_GRP_3_BASE
+
+#define MDLA_ACC_BASE		APU_GRP_0_BASE
+#define MVPU_ACC_BASE		APU_GRP_1_BASE
+#define MNOC_ACC_BASE		APU_GRP_2_BASE
+#define UP_ACC_BASE		APU_GRP_3_BASE
+
+/* RPC / RPC_LITE control */
+#define APU_RPC_SW_TYPE0_OFF	(0x200)
+#define APU_RPC_SW_TYPE1_OFF	(0x204)
+#define APU_RPC_SW_TYPE2_OFF	(0x208)
+#define APU_RPC_SW_TYPE3_OFF	(0x20C)
+#define APU_RPC_SW_TYPE4_OFF	(0x210)
+#define SW_TYPE_MVPU_MDLA_RV	BIT(0)
+#define CE_ENABLE		BIT(10)
+#define BUCK_PROT_SEL		BIT(20)
+#define RPC_TYPE_INIT_VAL	(0x18)
+#define TOP_SEL_VAL		(0xB2)
+#define RPC_TOP_SEL_VAL		(0xB800D50F)
+
+#define APUSYS_AO_CTL		(APUSYS_BASE + APU_AO_CTL)
+#define APUSYS_RPC		(APUSYS_BASE + APU_RPC)
+#define APUSYS_ACC		(APUSYS_BASE + APU_ACC)
+#define APUSYS_PLL		(APUSYS_BASE + APU_PLL)
+#define APUSYS_PCU		(APUSYS_BASE + APU_PCU)
+
+/* ARE control */
+#define ARE_VCORE_EN		BIT(20)
+#define ARE_RCX_AO_EN		BIT(21)
+#define ARE_VCORE_OFF		(20)
+#define ARE_CONF_START		(0x04)
+#define ARE_CONF_END		(0x6C)
+#define ARE_REG_SIZE		(4)
+
+/* ACC offset */
+#define APU_ACC_CONFG_SET0	(0x000)
+#define APU_ACC_CONFG_CLR0	(0x010)
+#define APU_ACC_AUTO_CTRL_SET0	(0x084)
+#define APU_ARDCM_CTRL0		(0x100)
+#define APU_ARDCM_CTRL1		(0x104)
+
+/* ACC control */
+#define APU_ARDCM_CTRL0_VAL_0	(0x00000016)
+#define APU_ARDCM_CTRL0_VAL_1	(0x00000036)
+#define APU_ARDCM_CTRL1_VAL_0	(0x00001006)
+#define APU_ARDCM_CTRL1_VAL_1	(0x07F0F006)
+#define CGEN_SOC		BIT(2)
+#define CLK_REQ_SW_EN		BIT(8)
+#define HW_CTRL_EN		BIT(15)
+
+/* APU PLL1C offset */
+#define RG_PLLGP_LVR_REFSEL	(0x204)
+#define PLL1C_PLL1_CON1		(0x20C)
+#define PLL1CPLL_FHCTL_HP_EN	(0x300)
+#define PLL1CPLL_FHCTL_CLK_CON	(0x308)
+#define PLL1CPLL_FHCTL_RST_CON	(0x30C)
+#define PLL1CPLL_FHCTL0_CFG	(0x314)
+#define PLL1CPLL_FHCTL0_DDS	(0x31C)
+
+/* PLL control */
+#define RG_PLLGP_LVR_REFSEL_VAL	(0x3)
+#define FHCTL_CTRL		(0x1)
+#define FHCTL_NO_RESET		(0x1)
+#define FHCTL_CLKEN		(0x1)
+#define FHCTL_HOPPING_EN	BIT(0)
+#define FHCTL_SFSTR0_EN		BIT(2)
+#define RG_PLL_SDM_PCW_CHG_OFF	(31)
+#define RG_PLL_POSDIV_OFF	(24)
+#define FHCTL0_PLL_TGL_ORG	(31)
+
+/* RPC offset define */
+#define APU_RPC_TOP_SEL		(0x0004)
+#define APU_RPC_TOP_SEL_1	(0x0018)
+#define APU_RPC_HW_CON		(0x001C)
+#define APU_RPC_STATUS_1	(0x0034)
+#define APU_RPC_INTF_PWR_RDY	(0x0044)
+
+/* RPC control */
+#define SRAM_AOC_LHENB_SET	BIT(4)
+#define	SRAM_AOC_ISO_SET	BIT(6)
+#define SRAM_AOC_ISO_CLR	BIT(7)
+#define PLL_AOC_ISO_EN_SET	BIT(8)
+#define PLL_AOC_ISO_EN_CLR	BIT(9)
+#define BUCK_ELS_EN_SET		BIT(10)
+#define BUCK_ELS_EN_CLR		BIT(11)
+#define BUCK_AO_RST_B_SET	BIT(12)
+#define BUCK_AO_RST_B_CLR	BIT(13)
+#define BUCK_PROT_REQ_SET	BIT(14)
+#define BUCK_PROT_REQ_CLR	BIT(15)
+
+/* mt6373_vbuck2 */
+#define MT6373_SLAVE_ID				(0x5)
+#define MT6373_RG_BUCK_VBUCK2_SET		(0x241)
+#define MT6373_RG_BUCK_VBUCK2_CLR		(0x242)
+#define MT6373_RG_BUCK_VBUCK2_EN_SHIFT		(2)
+#define MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR	(0x24e)
+
+/* PCU initial data */
+#define APU_PCUTOP_CTRL_SET		(0x0)
+#define APU_PCU_BUCK_STEP_SEL		(0x0030)
+#define APU_PCU_BUCK_ON_DAT0_L		(0x0080)
+#define APU_PCU_BUCK_ON_DAT0_H		(0x0084)
+#define APU_PCU_BUCK_ON_DAT1_L		(0x0088)
+#define APU_PCU_BUCK_ON_DAT1_H		(0x008C)
+#define APU_PCU_BUCK_OFF_DAT0_L		(0x00A0)
+#define APU_PCU_BUCK_OFF_DAT0_H		(0x00A4)
+#define APU_PCU_BUCK_ON_SLE0		(0x00C0)
+#define APU_PCU_BUCK_ON_SLE1		(0x00C4)
+#define VAPU_BUCK_ON_SETTLE_TIME	(0x00C8)
+#define APU_PCU_PMIC_TAR_BUF1		(0x0190)
+#define APU_PCU_PMIC_TAR_BUF2		(0x0194)
+#define APU_PCU_PMIC_CMD		(0x0184)
+#define APU_PCU_PMIC_IRQ		(0x0180)
+
+/* PCU control */
+#define PMIC_CMD_IRQ			BIT(0)
+#define PMIC_IRQ_EN			BIT(2)
+#define AUTO_BUCK_EN			BIT(3)
+#define PMIC_PMIFID_OFF			(3)
+#define PMIC_SLVID_OFF			(4)
+#define PCU_CMD_OP_W			(0x7)
+#define PMIC_OFF_ADDR_OFF		(16)
+#define PMIC_CMD_EN			(0x1)
+#define BUCK_STEP_SEL_VAL		(0x13)
+#define PCU_BUCK_OFF_CMD		(0x7)
+
+/* sram_core: mt6363_vbuck4 */
+#define MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR	(0x250)
+
+/* sub_pmic */
+#define BUCK_VAPU_PMIC_ID		MT6373_SLAVE_ID
+#define BUCK_VAPU_PMIC_REG_VOSEL_ADDR	MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR
+#define BUCK_VAPU_PMIC_REG_EN_SET_ADDR	MT6373_RG_BUCK_VBUCK2_SET
+#define BUCK_VAPU_PMIC_REG_EN_CLR_ADDR	MT6373_RG_BUCK_VBUCK2_CLR
+#define BUCK_VAPU_PMIC_REG_EN_SHIFT	MT6373_RG_BUCK_VBUCK2_EN_SHIFT
+
+/* vlp offset define */
+#define APUSYS_AO_SRAM_CONFIG		(0x70)
+#define APUSYS_AO_SRAM_SET		(0x74)
+#define APUSYS_AO_SRAM_CLR		(0x78)
+
+#define APUSYS_AO_SRAM_EN		(0x1)
+
+#define ARE_ENTRIES(x, y)		((((y) - (x)) + 1) * 2)
+#define ARE_ENTRY(x)			(((x) * 2) + 36)
+#define ARE_RCX_AO_CONFIG		(0x0014)
+#define ARE_RCX_AO_CONFIG_HIGH_OFF	(16)
+
+#define APU_ACE_HW_FLAG_DIS		(APUSYS_CE_BASE + 0x05D4)
+#define APU_ACE_DIS_FLAG_VAL		(0xffff7ff8)
+
+#define OUT_CLK_FREQ_MIN		(1500)
+#define DDS_SHIFT			(14)
+#define BASIC_CLK_FREQ			(26)
+
+int apusys_power_init(void);
+
+#endif /* APUSYS_POWER_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h
new file mode 100644
index 0000000..7a5b212
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_MBOX_MPU_H
+#define APUSYS_RV_MBOX_MPU_H
+
+#define MPU_EN		(0)
+#define MPU_DIS		(1)
+#define MBOX0_TX_DOMAIN	(0)
+#define MBOX0_TX_NS	(1)
+#define MBOX1_TX_DOMAIN	(11)
+#define MBOX1_TX_NS	(1)
+#define MBOX3_TX_DOMAIN	(3)
+#define MBOX3_TX_NS	(0)
+#define MBOX4_RX_DOMAIN	(0)
+#define MBOX4_RX_NS	(0)
+#define MBOX5_TX_DOMAIN	(8)
+#define MBOX5_TX_NS	(0)
+#define MBOX6_TX_DOMAIN	(4)
+#define MBOX6_TX_NS	(1)
+#define MBOX7_RX_DOMAIN	(0)
+#define MBOX7_RX_NS	(0)
+#define MBOXN_RX_DOMAIN	(5)
+#define MBOXN_RX_NS	(0)
+#define MBOXN_TX_DOMAIN	(0)
+#define MBOXN_TX_NS	(0)
+
+struct mbox_mpu_setting {
+	uint32_t no_mpu;
+	uint32_t rx_ns;
+	uint32_t rx_domain;
+	uint32_t tx_ns;
+	uint32_t tx_domain;
+};
+
+static const struct mbox_mpu_setting mbox_mpu_setting_tab[] = {
+	/* no_mpu,	rx_ns,		rx_domain,		tx_ns,		tx_domain */
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOX0_TX_NS,	MBOX0_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOX1_TX_NS,	MBOX1_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOXN_TX_NS,	MBOXN_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOX3_TX_NS,	MBOX3_TX_DOMAIN},
+	{MPU_DIS,	MBOX4_RX_NS,	MBOX4_RX_DOMAIN,	MBOXN_TX_NS,	MBOXN_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOX5_TX_NS,	MBOX5_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOX6_TX_NS,	MBOX6_TX_DOMAIN},
+	{MPU_DIS,	MBOX7_RX_NS,	MBOX7_RX_DOMAIN,	MBOXN_TX_NS,	MBOXN_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOXN_TX_NS,	MBOXN_TX_DOMAIN},
+	{MPU_EN,	MBOXN_RX_NS,	MBOXN_RX_DOMAIN,	MBOXN_TX_NS,	MBOXN_TX_DOMAIN},
+};
+
+#define APU_MBOX_NUM ARRAY_SIZE(mbox_mpu_setting_tab)
+
+#endif /* APUSYS_RV_MBOX_MPU_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
new file mode 100644
index 0000000..632af52
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "apusys_power.h"
+#include "apusys_rv.h"
+#include "apusys_rv_pwr_ctrl.h"
+
+#define RPC_POWER_OFF_TIMEOUT_CNT	(100000) /* 100ms */
+
+static int wait_for_state_ready(uint32_t reg, uint32_t mask, uint32_t expect,
+				uint32_t retry_times, uint32_t set_reg, uint32_t set_val)
+{
+	uint32_t count = 0;
+
+	while ((mmio_read_32(reg) & mask) != expect) {
+		if (count > retry_times) {
+			ERROR("%s: timed out, reg = %x, mask = %x, expect = %x\n",
+			       __func__, reg, mask, expect);
+			return -EBUSY;
+		}
+		count += 1;
+
+		if (set_reg)
+			mmio_write_32(set_reg, set_val);
+		udelay(1);
+	}
+
+	return 0;
+}
+
+int apu_hw_sema_ctl_per_mbox(uint32_t sem_ctrl_addr, uint32_t sem_sta_addr,
+			     uint8_t usr_bit, enum apu_hw_sem_op ctl, uint32_t timeout,
+			     uint8_t bypass)
+{
+	int ret;
+	uint8_t ctl_bit = 0;
+
+	if (ctl == HW_SEM_GET)
+		ctl_bit = 0x1;
+	else if (ctl == HW_SEM_PUT)
+		ctl_bit = 0x2;
+	else
+		return -EINVAL;
+
+	/* return fail if semaphore is currently not held by this user */
+	if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_sta_addr) & BIT(usr_bit)) == 0)
+	    && !bypass) {
+		ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
+		       __func__, usr_bit, ctl, sem_sta_addr, mmio_read_32(sem_sta_addr));
+		return -EINVAL;
+	}
+
+	mmio_write_32(sem_ctrl_addr, ctl_bit);
+
+	if (ctl == HW_SEM_PUT)
+		return 0;
+
+	ret = wait_for_state_ready(sem_sta_addr, BIT(usr_bit), BIT(usr_bit), timeout,
+				   sem_ctrl_addr, ctl_bit);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+	int ret;
+	uint32_t global_ref_cnt;
+
+	ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
+				       APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
+				       APU_HW_SEM_SYS_APMCU, HW_SEM_GET, HW_SEM_TIMEOUT, 0);
+
+	if (ret) {
+		ERROR("%s(%d): sem acquire timeout\n", __func__, op);
+		return ret;
+	}
+
+	global_ref_cnt = mmio_read_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY);
+
+	if (global_ref_cnt > 2) {
+		ERROR("%s: global_ref_cnt(%d) > 2\n", __func__, global_ref_cnt);
+	} else if (op == APU_PWR_OFF) {
+		global_ref_cnt--;
+		mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
+		if (global_ref_cnt == 0)
+			mmio_write_32(APU_MBOX_WKUP_CFG(11), 0);
+	} else if (op == APU_PWR_ON) {
+		global_ref_cnt++;
+		mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
+		if (global_ref_cnt == 1)
+			mmio_write_32(APU_MBOX_WKUP_CFG(11), 1);
+	}
+
+	ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
+				       APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
+				       APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, HW_SEM_TIMEOUT, 0);
+
+	if (ret)
+		ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+	return ret;
+}
+
+int rv_iommu_hw_sem_trylock(void)
+{
+	return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
+					APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
+					APU_HW_SEM_SYS_APMCU, HW_SEM_GET, 0, 0);
+}
+
+int rv_iommu_hw_sem_unlock(void)
+{
+	return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
+					APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
+					APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, 0, 0);
+}
+
+int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
+		    uint8_t bypass)
+{
+	int ret;
+	uint8_t ctl_bit = 0;
+
+	if (ctl == HW_SEM_GET)
+		ctl_bit = usr_bit;
+	else if (ctl == HW_SEM_PUT)
+		ctl_bit = usr_bit + HW_SEM_PUT_BIT_SHIFT;
+	else
+		return -EINVAL;
+
+	if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_addr) & BIT(ctl_bit)) == 0) && !bypass) {
+		ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
+		       __func__, usr_bit, ctl, sem_addr, mmio_read_32(sem_addr));
+		return -EINVAL;
+	}
+
+	mmio_write_32(sem_addr, BIT(ctl_bit));
+
+	if (ctl == HW_SEM_PUT)
+		goto end;
+
+	ret = wait_for_state_ready(sem_addr, BIT(ctl_bit), BIT(ctl_bit), timeout,
+				   sem_addr, BIT(ctl_bit));
+	if (ret)
+		return ret;
+
+end:
+	VERBOSE("%s: sem_addr = 0x%x, usr_bit: %d, ctl: %d, sem_addr = 0x%08x\n",
+		 __func__, sem_addr, usr_bit, ctl, mmio_read_32(sem_addr));
+
+	return 0;
+}
+
+int apusys_infra_dcm_setup(void)
+{
+	mmio_write_32(APU_REG_AO_GLUE_CONFG,
+		      mmio_read_32(APU_REG_AO_GLUE_CONFG) | BIT(24) | BIT(26));
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
new file mode 100644
index 0000000..b5a48e2
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PWR_CTL_H
+#define APUSYS_RV_PWR_CTL_H
+
+#include <platform_def.h>
+
+#include "apusys_rv.h"
+
+#define SUPPORT_APU_CLEAR_MBOX_DUMMY	(1)
+
+enum apu_hw_sem_sys_id {
+	APU_HW_SEM_SYS_APU   = 0UL,	/* mbox0 */
+	APU_HW_SEM_SYS_GZ    = 1UL,	/* mbox1 */
+	APU_HW_SEM_SYS_SCP   = 3UL,	/* mbox3 */
+	APU_HW_SEM_SYS_APMCU = 11UL,	/* mbox11 */
+};
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+int rv_iommu_hw_sem_unlock(void);
+int rv_iommu_hw_sem_trylock(void);
+int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
+		    uint8_t bypass);
+
+#define HW_SEM_TIMEOUT	(300) /* 300 us */
+
+/* APU MBOX */
+#define MBOX_WKUP_CFG		(0x80)
+#define MBOX_WKUP_MASK		(0x84)
+#define MBOX_FUNC_CFG		(0xb0)
+#define MBOX_DOMAIN_CFG		(0xe0)
+
+#define MBOX_CTRL_LOCK		BIT(0)
+#define MBOX_NO_MPU_SHIFT	(16)
+#define MBOX_RC_SHIFT		(24)
+
+#define MBOX_RX_NS_SHIFT	(16)
+#define MBOX_RX_DOMAIN_SHIFT	(17)
+#define MBOX_TX_NS_SHIFT	(24)
+#define MBOX_TX_DOMAIN_SHIFT	(25)
+
+#define APU_REG_AO_GLUE_CONFG	(APU_AO_CTRL + 0x20)
+
+#define ENABLE_INFRA_WA
+
+enum apu_infra_bit_id {
+	APU_INFRA_SYS_APMCU = 1UL,
+	APU_INFRA_SYS_GZ    = 2UL,
+	APU_INFRA_SYS_SCP   = 3UL,
+};
+
+#define APU_MBOX(i)		(APU_MBOX0 + 0x10000 * i)
+
+#define APU_MBOX_FUNC_CFG(i)	(APU_MBOX(i) + MBOX_FUNC_CFG)
+#define APU_MBOX_DOMAIN_CFG(i)	(APU_MBOX(i) + MBOX_DOMAIN_CFG)
+#define APU_MBOX_WKUP_CFG(i)	(APU_MBOX(i) + MBOX_WKUP_CFG)
+
+enum apu_hw_sem_op {
+	HW_SEM_PUT = 0,
+	HW_SEM_GET = 1,
+};
+
+#define HW_SEM_PUT_BIT_SHIFT	(16)
+
+/* bypass mbox register Dump for secure master */
+#define APU_MBOX_DBG_EN		(0x190f2380)
+
+/* apu_mbox register definition for mbox addr change*/
+#define APU_MBOX_SEMA0_CTRL	(0x090)
+#define APU_MBOX_SEMA0_RST	(0x094)
+#define APU_MBOX_SEMA0_STA	(0x098)
+#define APU_MBOX_SEMA1_CTRL	(0x0A0)
+#define APU_MBOX_SEMA1_RST	(0x0A4)
+#define APU_MBOX_SEMA1_STA	(0x0A8)
+#define APU_MBOX_DUMMY		(0x040)
+#define APU_MBOX_OFFSET(i)	(0x10000 * i)
+
+/* apu infra workaround */
+#define APU_INFRA_DISABLE	(APU_INFRA_BASE + 0xC18)
+#define APU_INFRA_ENABLE	(APU_INFRA_BASE + 0xC14)
+#define APU_INFRA_STATUS	(APU_INFRA_BASE + 0xC10)
+#define APU_INFRA_STATUS_MASK	(0x1fffe)
+#define APU_INFRA_HW_SEM	(APUSYS_CE_BASE + 0xE00)
+#define APU_RPC_STATUS		(0x190f0044)
+
+#define APU_INFRA_BIT_OFF	(16)
+#define APU_RPC_STATUS_BIT	BIT(0)
+
+#endif /* APUSYS_RV_PWR_CTL_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
new file mode 100644
index 0000000..f6c8f58
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "apusys_security_ctrl_perm.h"
+#include "apusys_security_ctrl_perm_plat.h"
+
+#define SEC_CTRL_APU_SEC_CON_BASE	(0x190F5000)
+#define SEC_CTRL_RV_DOMAIN_OFS		(0x60)
+#define SEC_CTRL_RV_NS_OFS		(0x64)
+#define SEC_CTRL_RV_DOMAIN_SHF		(4)
+#define SEC_CTRL_RV_NS_SHF		(1)
+
+#define SEC_LEVEL_NORMAL_DOMAIN		(7)
+#define SEC_LEVEL_NORMAL_NS		(1)
+#define SEC_LEVEL_SAPU_DOMAIN		(5)
+#define SEC_LEVEL_SAPU_NS		(1)
+#define SEC_LEVEL_AOV_DOMAIN		(14)
+#define SEC_LEVEL_AOV_NS		(1)
+#define SEC_LEVEL_UP_SECURE_DOMAIN	(5)
+#define SEC_LEVEL_UP_SECURE_NS		(0)
+#define SEC_LEVEL_MVPU_SECURE_DOMAIN	(7)
+#define SEC_LEVEL_MVPU_SECURE_NS	(0)
+#define SEC_LEVEL_MDLA_SECURE_DOMAIN	(14)
+#define SEC_LEVEL_MDLA_SECURE_NS	(0)
+#define DOMAIN(SEC_LVL)	SEC_LEVEL_##SEC_LVL##_DOMAIN
+#define NS(SEC_LVL)	SEC_LEVEL_##SEC_LVL##_NS
+
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+		uint8_t *domain, uint8_t *ns)
+{
+	if ((dev_type < 0) || (dev_type >= APUSYS_DEVICE_NUM)) {
+		ERROR("invalid dev type %d\n", dev_type);
+		return -EINVAL;
+	}
+
+	if ((sec_level < 0) || (sec_level >= SEC_LEVEL_NUM)) {
+		ERROR("invalid sec_level %d\n", sec_level);
+		return -EINVAL;
+	}
+
+	switch (sec_level) {
+	case SEC_LEVEL_NORMAL:
+		*domain = DOMAIN(NORMAL);
+		*ns = NS(NORMAL);
+		break;
+	case SEC_LEVEL_SECURE:
+		switch (dev_type) {
+		case APUSYS_DEVICE_MVPU:
+			*domain = DOMAIN(MVPU_SECURE);
+			*ns = NS(MVPU_SECURE);
+			break;
+		case APUSYS_DEVICE_MDLA:
+			*domain = DOMAIN(MDLA_SECURE);
+			*ns = NS(MDLA_SECURE);
+			break;
+		case APUSYS_DEVICE_UP:
+			*domain = DOMAIN(UP_SECURE);
+			*ns = NS(UP_SECURE);
+			break;
+		default:
+			ERROR("invalid dev type %d\n", dev_type);
+			return -EINVAL;
+		};
+		break;
+	case SEC_LEVEL_SAPU:
+		*domain = DOMAIN(SAPU);
+		*ns = NS(SAPU);
+		break;
+	case SEC_LEVEL_AOV:
+		*domain = DOMAIN(AOV);
+		*ns = NS(AOV);
+		break;
+	default:
+		ERROR("invalid sec_level %d\n", sec_level);
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+int sec_set_rv_dns(void)
+{
+	uint8_t normal_domain;
+	uint8_t normal_ns;
+	uint8_t sec_domain;
+	uint8_t sec_ns;
+	int ret;
+
+	ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &sec_domain, &sec_ns);
+	if (ret) {
+		ERROR("%s failed.\n", __func__);
+		return ret;
+	}
+
+	ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &normal_domain, &normal_ns);
+	if (ret) {
+		ERROR("%s failed.\n", __func__);
+		return ret;
+	}
+
+	mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_DOMAIN_OFS,
+		      (sec_domain << SEC_CTRL_RV_DOMAIN_SHF) | normal_domain);
+	mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_NS_OFS,
+		      (sec_ns << SEC_CTRL_RV_NS_SHF) | normal_ns);
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
new file mode 100644
index 0000000..d57a536
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PERM_PLAT_H
+#define APUSYS_SECURITY_CTRL_PERM_PLAT_H
+
+enum apusys_dev_type {
+	APUSYS_DEVICE_MDLA,
+	APUSYS_DEVICE_EDPA,
+	APUSYS_DEVICE_MVPU,
+	APUSYS_DEVICE_UP,
+	APUSYS_DEVICE_NUM,
+};
+
+#endif /* APUSYS_SECURITY_CTRL_PERM_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
new file mode 100644
index 0000000..fbd2aa0
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define ENABLE_SMPU_PROTECT	(0)
+
+#if ENABLE_SMPU_PROTECT
+#include "emi.h"
+#include "mt_emi.h"
+#endif
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <apusys_security_ctrl_plat.h>
+
+#define APUSYS_SEC_FW_EMI_REGION	(23)
+
+#define bits_clr(x, m, o)	(x & (~(m << o)))
+#define bits_set(x, v, m, o)	((bits_clr(x, m, o)) | ((v & m) << o))
+
+static void sec_sideband_init(void)
+{
+	uint32_t value = mmio_read_32(SEC_CTRL_SIDE_BAND);
+
+	value = bits_set(value, SEC_CTRL_NARE_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+			 SEC_CTRL_NARE_DOMAIN_SHF);
+	value = bits_set(value, SEC_CTRL_NARE_NS, SEC_CTRL_NS_MASK, SEC_CTRL_NARE_NS_SHF);
+	value = bits_set(value, SEC_CTRL_SARE0_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+			 SEC_CTRL_SARE0_DOMAIN_SHF);
+	value = bits_set(value, SEC_CTRL_SARE0_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE0_NS_SHF);
+	value = bits_set(value, SEC_CTRL_SARE1_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+			 SEC_CTRL_SARE1_DOMAIN_SHF);
+	value = bits_set(value, SEC_CTRL_SARE1_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE1_NS_SHF);
+
+	mmio_write_32(SEC_CTRL_SIDE_BAND, value);
+}
+
+static void domain_remap_init(void)
+{
+	const uint32_t remap_domains[] = {
+		D0_REMAP_DOMAIN,  D1_REMAP_DOMAIN,  D2_REMAP_DOMAIN,  D3_REMAP_DOMAIN,
+		D4_REMAP_DOMAIN,  D5_REMAP_DOMAIN,  D6_REMAP_DOMAIN,  D7_REMAP_DOMAIN,
+		D8_REMAP_DOMAIN,  D9_REMAP_DOMAIN,  D10_REMAP_DOMAIN, D11_REMAP_DOMAIN,
+		D12_REMAP_DOMAIN, D13_REMAP_DOMAIN, D14_REMAP_DOMAIN, D15_REMAP_DOMAIN,
+	};
+	uint32_t lower_domain = 0;
+	uint32_t higher_domain = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(remap_domains); i++) {
+		if (i < SEC_CTRL_REG_DOMAIN_NUM)
+			lower_domain |= (remap_domains[i] << (i * REG_DOMAIN_BITS));
+		else
+			higher_domain |= (remap_domains[i] <<
+					  ((i - SEC_CTRL_REG_DOMAIN_NUM) * REG_DOMAIN_BITS));
+	}
+
+	mmio_write_32(SEC_CTRL_SOC2APU_SET1_0, lower_domain);
+	mmio_write_32(SEC_CTRL_SOC2APU_SET1_1, higher_domain);
+	mmio_setbits_32(APU_SEC_CON, SEC_CTRL_DOMAIN_REMAP_SEL);
+}
+
+void apusys_security_ctrl_init(void)
+{
+	domain_remap_init();
+	sec_sideband_init();
+}
+
+int apusys_plat_setup_sec_mem(void)
+{
+#if ENABLE_SMPU_PROTECT
+	return sip_emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
+		(APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >> EMI_MPU_ALIGN_BITS,
+		APUSYS_SEC_FW_EMI_REGION);
+#else
+	INFO("%s: Bypass SMPU protection setup.\n", __func__);
+	return 0;
+#endif
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h
new file mode 100644
index 0000000..5e69777
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PLAT_H
+#define APUSYS_SECURITY_CTRL_PLAT_H
+
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#define SEC_CTRL_SOC2APU_SET1_0		(APU_SEC_CON + 0xC)
+#define SEC_CTRL_SOC2APU_SET1_1		(APU_SEC_CON + 0x10)
+#define SEC_CTRL_SIDE_BAND		(APU_SEC_CON + 0x24)
+
+#define SEC_CTRL_REG_DOMAIN_NUM		(8)
+#define SEC_CTRL_DOMAIN_REMAP_SEL	BIT(6)
+#define SEC_CTRL_DOMAIN_MASK		(0xF)
+#define SEC_CTRL_NS_MASK		(0x1)
+
+#define SEC_CTRL_NARE_DOMAIN		(5)
+#define SEC_CTRL_NARE_NS		(0)
+#define SEC_CTRL_NARE_DOMAIN_SHF	(0)
+#define SEC_CTRL_NARE_NS_SHF		(4)
+
+#define SEC_CTRL_SARE0_DOMAIN		(5)
+#define SEC_CTRL_SARE0_NS		(0)
+#define SEC_CTRL_SARE0_DOMAIN_SHF	(5)
+#define SEC_CTRL_SARE0_NS_SHF		(9)
+
+#define SEC_CTRL_SARE1_DOMAIN		(5)
+#define SEC_CTRL_SARE1_NS		(0)
+#define SEC_CTRL_SARE1_DOMAIN_SHF	(10)
+#define SEC_CTRL_SARE1_NS_SHF		(14)
+
+#define REG_DOMAIN_BITS		(4)
+
+#define D0_REMAP_DOMAIN		(0)
+#define D1_REMAP_DOMAIN		(1)
+#define D2_REMAP_DOMAIN		(2)
+#define D3_REMAP_DOMAIN		(3)
+#define D4_REMAP_DOMAIN		(4)
+#define D5_REMAP_DOMAIN		(6)
+#define D6_REMAP_DOMAIN		(6)
+#define D7_REMAP_DOMAIN		(6)
+#define D8_REMAP_DOMAIN		(8)
+#define D9_REMAP_DOMAIN		(9)
+#define D10_REMAP_DOMAIN	(10)
+#define D11_REMAP_DOMAIN	(11)
+#define D12_REMAP_DOMAIN	(12)
+#define D13_REMAP_DOMAIN	(13)
+#define D14_REMAP_DOMAIN	(6)
+#define D15_REMAP_DOMAIN	(15)
+
+void apusys_security_ctrl_init(void);
+int apusys_plat_setup_sec_mem(void);
+
+#endif /* APUSYS_SECURITY_CTRL_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
new file mode 100644
index 0000000..4ffaf73
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys_${MTK_SOC}
+
+ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/${MTK_SOC}
+endif
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_devapc.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_rv_pwr_ctrl.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_perm_plat.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 498925c..24cc79c 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,10 +12,19 @@
 
 PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
 
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_CE_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_EMI_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_LOGTOP_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_SEC_CTRL))
+
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
 
 SUB_RULES-y := ${LOCAL_DIR}/${MTK_SOC}
 SUB_RULES-y += ${LOCAL_DIR}/devapc
 SUB_RULES-y += ${LOCAL_DIR}/apusys_rv/2.0
+SUB_RULES-${CONFIG_MTK_APUSYS_SEC_CTRL} += $(LOCAL_DIR)/security_ctrl
 
 $(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
new file mode 100644
index 0000000..17ccacf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_CTRL_PERM_H
+#define SECURITY_CTRL_PERM_H
+
+#include "apusys_security_ctrl_perm_plat.h"
+
+enum apusys_sec_level {
+	SEC_LEVEL_NORMAL,
+	SEC_LEVEL_SECURE,
+	SEC_LEVEL_SAPU,
+	SEC_LEVEL_AOV,
+	SEC_LEVEL_NUM,
+};
+
+int sec_set_rv_dns(void);
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+		uint8_t *domain, uint8_t *ns);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/rules.mk b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
new file mode 100644
index 0000000..a7ed5c9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/security_ctrl
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC}
diff --git a/plat/mediatek/drivers/emi/common/emi.h b/plat/mediatek/drivers/emi/common/emi.h
new file mode 100644
index 0000000..eb2a0d3
--- /dev/null
+++ b/plat/mediatek/drivers/emi/common/emi.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_H
+#define EMI_H
+
+#include <stdint.h>
+
+#define EMI_MPU_ALIGN_BITS	12
+
+uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end, u_register_t region);
+
+#endif /* EMI_H */
diff --git a/plat/mediatek/drivers/emi/emi_stub.c b/plat/mediatek/drivers/emi/emi_stub.c
new file mode 100644
index 0000000..3682bf7
--- /dev/null
+++ b/plat/mediatek/drivers/emi/emi_stub.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+
+#include "common/emi.h"
+#include <mtk_sip_svc.h>
+
+uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end,
+				    u_register_t region)
+{
+	return MTK_SIP_E_NOT_SUPPORTED;
+}
diff --git a/plat/mediatek/drivers/emi/rules.mk b/plat/mediatek/drivers/emi/rules.mk
new file mode 100644
index 0000000..9f462bb
--- /dev/null
+++ b/plat/mediatek/drivers/emi/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := emi
+
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/gpio/mtgpio_common.h b/plat/mediatek/drivers/gpio/mtgpio_common.h
index d6b858c..a93a065 100644
--- a/plat/mediatek/drivers/gpio/mtgpio_common.h
+++ b/plat/mediatek/drivers/gpio/mtgpio_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,7 +97,7 @@
 	}
 
 struct mt_pin_info {
-	uint8_t id;
+	uint16_t id;
 	uint8_t flag;
 	uint8_t bit;
 	uint16_t base;
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.c b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
new file mode 100644
index 0000000..691b923
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "rng_plat.h"
+
+static spinlock_t rng_lock;
+
+static int trng_wait(uint32_t reg, uint32_t expected_value)
+{
+	uint64_t timeout = timeout_init_us(TRNG_TIME_OUT);
+	uint32_t value = 0;
+
+	do {
+		value = mmio_read_32(reg);
+		if ((value & expected_value) == expected_value)
+			return 0;
+
+		udelay(10);
+	} while (!timeout_elapsed(timeout));
+
+	return -ETIMEDOUT;
+}
+
+static int trng_write(uint32_t reg, uint32_t value,
+			   uint32_t read_reg, uint32_t expected_value)
+{
+	int retry = MTK_TRNG_MAX_ROUND;
+	uint32_t read_value = 0;
+
+	do {
+		mmio_write_32(reg, value);
+
+		read_value = mmio_read_32(read_reg);
+		if ((read_value & value) == expected_value)
+			return 0;
+
+		udelay(10);
+	} while (--retry > 0);
+
+	return -ETIMEDOUT;
+}
+
+static uint32_t trng_prng(uint32_t *rand)
+{
+	int32_t ret = 0;
+	uint32_t seed[4] = {0};
+
+	if (rand == NULL)
+		return MTK_SIP_E_INVALID_PARAM;
+
+	/* ungate */
+	ret = trng_write(TRNG_PDN_CLR, TRNG_PDN_VALUE, TRNG_PDN_STATUS, 0);
+	if (ret) {
+		ERROR("%s: ungate fail\n", __func__);
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	/* read random data once and drop it */
+	seed[0] = mmio_read_32(TRNG_DATA);
+
+	/* enable von-neumann extractor */
+	mmio_setbits_32(TRNG_CONF, TRNG_CONF_VON_EN);
+
+	/* start */
+	mmio_setbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+	/* get seeds from trng */
+	for (int i = 0; i < ARRAY_SIZE(seed); i++) {
+		ret = trng_wait(TRNG_CTRL, TRNG_CTRL_RDY);
+		if (ret) {
+			ERROR("%s: trng NOT ready\n", __func__);
+			return MTK_SIP_E_NOT_SUPPORTED;
+		}
+
+		seed[i] = mmio_read_32(TRNG_DATA);
+	}
+
+	/* stop */
+	mmio_clrbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+	/* gate */
+	ret = trng_write(TRNG_PDN_SET, TRNG_PDN_VALUE, TRNG_PDN_STATUS, TRNG_PDN_VALUE);
+	if (ret) {
+		ERROR("%s: gate fail\n", __func__);
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(seed); i++)
+		rand[i] = seed[i];
+
+	return 0;
+}
+
+static uint32_t get_true_rnd(uint32_t *val, uint32_t num)
+{
+	uint32_t rand[4] = {0};
+	uint32_t ret;
+
+	if (val == NULL || num > ARRAY_SIZE(rand))
+		return MTK_SIP_E_INVALID_PARAM;
+
+	spin_lock(&rng_lock);
+	ret = trng_prng(rand);
+	spin_unlock(&rng_lock);
+
+	for (int i = 0; i < num; i++)
+		val[i] = rand[i];
+
+	return ret;
+}
+
+/*
+ * plat_get_entropy - get 64-bit random number data which is used form
+ * atf early stage
+ * output - out: output 64-bit entropy combine with 2 32-bit random number
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+	uint32_t entropy_pool[2] = {0};
+	uint32_t ret;
+
+	assert(out);
+	assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+	/* Get 2 32-bits entropy */
+	ret = get_true_rnd(entropy_pool, ARRAY_SIZE(entropy_pool));
+	if (ret)
+		return false;
+
+	/* Output 8 bytes entropy combine with 2 32-bit random number. */
+	*out = ((uint64_t)entropy_pool[0] << 32) | entropy_pool[1];
+
+	return true;
+}
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.h b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
new file mode 100644
index 0000000..ab22c45
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RNG_PLAT_H
+#define RNG_PLAT_H
+
+#define TRNG_TIME_OUT		1000
+#define MTK_TRNG_MAX_ROUND	4
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE_SIZE		0x1000
+#define TRNG_CTRL		(TRNG_BASE + 0x0000)
+#define TRNG_TIME		(TRNG_BASE + 0x0004)
+#define TRNG_DATA		(TRNG_BASE + 0x0008)
+#define TRNG_CONF		(TRNG_BASE + 0x000C)
+#define TRNG_CTRL_RDY		0x80000000
+#define TRNG_CTRL_START		0x00000001
+#define TRNG_CONF_VON_EN	0x00000020
+#define TRNG_PDN_BASE_SIZE	0x1000
+#define TRNG_PDN_SET		(INFRACFG_AO_BASE + 0x0088)
+#define TRNG_PDN_CLR		(INFRACFG_AO_BASE + 0x008C)
+#define TRNG_PDN_STATUS		(INFRACFG_AO_BASE + 0x0094)
+#define TRNG_PDN_VALUE		0x200
+
+#endif /* RNG_PLAT_H */
diff --git a/plat/mediatek/drivers/rng/mt8188/rng_plat.c b/plat/mediatek/drivers/rng/mt8188/rng_plat.c
new file mode 100644
index 0000000..361be22
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8188/rng_plat.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include "rng_plat.h"
+
+static void trng_external_swrst(void)
+{
+	/* External swrst to reset whole rng module */
+	mmio_setbits_32(TRNG_SWRST_SET_REG, RNG_SWRST_B);
+	mmio_setbits_32(TRNG_SWRST_CLR_REG, RNG_SWRST_B);
+
+	/* Disable irq */
+	mmio_clrbits_32(RNG_IRQ_CFG, IRQ_EN);
+	/* Set default cutoff value */
+	mmio_write_32(RNG_HTEST, RNG_DEFAULT_CUTOFF);
+	/* Enable rng */
+	mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+}
+
+static bool get_entropy_32(uint32_t *out)
+{
+	uint64_t time = timeout_init_us(MTK_TIMEOUT_POLL);
+	int retry_times = 0;
+
+	while (!(mmio_read_32(RNG_STATUS) & DRBG_VALID)) {
+		if (mmio_read_32(RNG_STATUS) & (RNG_ERROR | APB_ERROR)) {
+			mmio_clrbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+
+			mmio_clrbits_32(RNG_SWRST, SWRST_B);
+			mmio_setbits_32(RNG_SWRST, SWRST_B);
+
+			mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+		}
+
+		if (timeout_elapsed(time)) {
+			trng_external_swrst();
+			time = timeout_init_us(MTK_TIMEOUT_POLL);
+			retry_times++;
+		}
+
+		if (retry_times > MTK_RETRY_CNT) {
+			ERROR("%s: trng NOT ready\n", __func__);
+			return false;
+		}
+	}
+
+	*out = mmio_read_32(RNG_OUT);
+
+	return true;
+}
+
+/* Get random number from HWRNG and return 8 bytes of entropy.
+ * Return 'true' when random value generated successfully, otherwise return
+ * 'false'.
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+	uint32_t seed[2] = { 0 };
+	int i = 0;
+
+	assert(out);
+	assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+	/* Disable interrupt mode */
+	mmio_clrbits_32(RNG_IRQ_CFG, IRQ_EN);
+	/* Set rng health test cutoff value */
+	mmio_write_32(RNG_HTEST, RNG_DEFAULT_CUTOFF);
+	/* Enable rng module */
+	mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+
+	for (i = 0; i < ARRAY_SIZE(seed); i++) {
+		if (!get_entropy_32(&seed[i]))
+			return false;
+	}
+
+	/* Output 8 bytes entropy by combining 2 32-bit random numbers. */
+	*out = ((uint64_t)seed[0] << 32) | seed[1];
+
+	return true;
+}
diff --git a/plat/mediatek/drivers/rng/mt8188/rng_plat.h b/plat/mediatek/drivers/rng/mt8188/rng_plat.h
new file mode 100644
index 0000000..37ef271
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8188/rng_plat.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RNG_PLAT_H
+#define RNG_PLAT_H
+
+#include <lib/utils_def.h>
+
+#define MTK_TIMEOUT_POLL	1000
+
+#define MTK_RETRY_CNT		10
+
+#define RNG_DEFAULT_CUTOFF	0x04871C0B
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define RNG_STATUS		(TRNG_BASE + 0x0004)
+#define RNG_SWRST		(TRNG_BASE + 0x0010)
+#define RNG_IRQ_CFG		(TRNG_BASE + 0x0014)
+#define RNG_EN			(TRNG_BASE + 0x0020)
+#define RNG_HTEST		(TRNG_BASE + 0x0028)
+#define RNG_OUT			(TRNG_BASE + 0x0030)
+#define RNG_RAW			(TRNG_BASE + 0x0038)
+#define RNG_SRC			(TRNG_BASE + 0x0050)
+
+#define RAW_VALID		BIT(12)
+#define DRBG_VALID		BIT(4)
+#define RAW_EN			BIT(8)
+#define NRBG_EN			BIT(4)
+#define DRBG_EN			BIT(0)
+#define IRQ_EN			BIT(0)
+#define SWRST_B			BIT(0)
+/* Error conditions */
+#define RNG_ERROR		GENMASK_32(28, 24)
+#define APB_ERROR		BIT(16)
+
+/* External swrst */
+#define TRNG_SWRST_SET_REG	(INFRACFG_AO_BASE + 0x150)
+#define TRNG_SWRST_CLR_REG	(INFRACFG_AO_BASE + 0x154)
+#define RNG_SWRST_B		BIT(13)
+
+#endif /* RNG_PLAT_H */
diff --git a/plat/mediatek/drivers/rng/rng.c b/plat/mediatek/drivers/rng/rng.c
new file mode 100644
index 0000000..d611168
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rng.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/smccc.h>
+#include <plat/common/plat_trng.h>
+
+#include <mtk_sip_svc.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+	0xf6b2c8d9, 0x1abb, 0x4d83, 0xb2, 0x3f,
+	0x5c, 0x51, 0xb6, 0xef, 0xfc, 0xaf
+);
+uuid_t plat_trng_uuid;
+
+void plat_entropy_setup(void)
+{
+	uint64_t placeholder;
+
+	plat_trng_uuid = _plat_trng_uuid;
+
+	/* Initialise the entropy source and trigger RNG generation */
+	plat_get_entropy(&placeholder);
+}
diff --git a/plat/mediatek/drivers/rng/rules.mk b/plat/mediatek/drivers/rng/rules.mk
new file mode 100644
index 0000000..5bcd2cd
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := rng
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/rng.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/rng_plat.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/timer/mt_timer.h b/plat/mediatek/drivers/timer/mt_timer.h
index 1c08f90..fafbbcf 100644
--- a/plat/mediatek/drivers/timer/mt_timer.h
+++ b/plat/mediatek/drivers/timer/mt_timer.h
@@ -7,7 +7,12 @@
 #ifndef MT_TIMER_H
 #define MT_TIMER_H
 
+#include "platform_def.h"
+
+#ifndef SYSTIMER_BASE
 #define SYSTIMER_BASE       (0x10017000)
+#endif
+
 #define CNTCR_REG           (SYSTIMER_BASE + 0x0)
 #define CNTSR_REG           (SYSTIMER_BASE + 0x4)
 #define CNTSYS_L_REG        (SYSTIMER_BASE + 0x8)
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
new file mode 100644
index 0000000..3d87d40
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_HELPER_H
+#define VCP_HELPER_H
+
+#define MTK_VCP_SRAM_SIZE		(0x60000)
+
+/* Export extern API */
+uint32_t get_mmup_fw_size(void);
+uint64_t get_mmup_l2tcm_offset(void);
+
+/* SMC calls OPS */
+enum mtk_tinysys_vcp_kernel_op {
+	MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET = 0,
+	MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE,
+	MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP,
+	MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET,
+	MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE,
+	MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET,
+	MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE,
+	MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP,
+	MTK_TINYSYS_VCP_KERNEL_OP_NUM,
+};
+
+#endif /* VCP_HELPER_H */
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
new file mode 100644
index 0000000..4aa8332
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_REG_H
+#define VCP_REG_H
+
+#include <platform_def.h>
+
+#define MTK_VCP_REG_BASE		(IO_PHYS + 0x21800000)
+#define MTK_VCP_REG_BANK_SIZE		(0x1000)
+
+/*******************************************************************************
+ * VCP power related setting
+ ******************************************************************************/
+#define VCP_POWER_STATUS		(0xE60)
+#define MMUP_PWR_STA_BIT		(30)
+#define MMUP_PWR_STA_EN			((uint32_t)(0x3))
+
+/*******************************************************************************
+ * VCP registers
+ ******************************************************************************/
+/* cfgreg */
+#define VCP_R_CFGREG			(MTK_VCP_REG_BASE + 0x3d0000)
+
+#define VCP_R_CORE0_SW_RSTN_CLR		(VCP_R_CFGREG + 0x0000)
+#define VCP_R_CORE0_SW_RSTN_SET		(VCP_R_CFGREG + 0x0004)
+#define VCP_R_CORE1_SW_RSTN_CLR		(VCP_R_CFGREG + 0x0008)
+#define VCP_R_CORE1_SW_RSTN_SET		(VCP_R_CFGREG + 0x000c)
+#define VCP_R_GIPC_IN_SET		(VCP_R_CFGREG + 0x0028)
+#define VCP_R_GIPC_IN_CLR		(VCP_R_CFGREG + 0x002c)
+#define B_GIPC3_SETCLR_1		BIT(13)
+
+/* cfgreg_core0 */
+#define VCP_R_CFGREG_CORE0		(MTK_VCP_REG_BASE + 0x20a000)
+
+#define VCP_R_CORE0_STATUS		(VCP_R_CFGREG_CORE0 + 0x0070)
+
+#define CORE0_R_GPR5			(VCP_R_CFGREG_CORE0 + 0x0054)
+#define VCP_GPR_C0_H0_REBOOT		CORE0_R_GPR5
+#define CORE0_R_GPR6			(VCP_R_CFGREG_CORE0 + 0x0058)
+#define VCP_GPR_C0_H1_REBOOT		CORE0_R_GPR6
+#define VCP_CORE_RDY_TO_REBOOT		(0x34)
+#define VCP_CORE_REBOOT_OK		BIT(0)
+
+/* cfgreg_core1 */
+#define VCP_R_CFGREG_CORE1		(MTK_VCP_REG_BASE + 0x20d000)
+
+#define VCP_R_CORE1_STATUS		(VCP_R_CFGREG_CORE1 + 0x0070)
+#define CORE1_R_GPR5			(VCP_R_CFGREG_CORE1 + 0x0054)
+#define VCP_GPR_CORE1_REBOOT		CORE1_R_GPR5
+
+/* sec */
+#define VCP_R_SEC_CTRL			(MTK_VCP_REG_BASE + 0x270000)
+#define VCP_OFFSET_ENABLE_P		BIT(13)
+#define VCP_OFFSET_ENABLE_B		BIT(12)
+#define VCP_R_SEC_CTRL_2		(VCP_R_SEC_CTRL + 0x0004)
+#define CORE0_SEC_BIT_SEL		BIT(0)
+#define CORE1_SEC_BIT_SEL		BIT(8)
+#define VCP_GPR0_CFGREG_SEC		(VCP_R_SEC_CTRL + 0x0040)
+#define VCP_GPR1_CFGREG_SEC		(VCP_R_SEC_CTRL + 0x0044)
+#define VCP_GPR2_CFGREG_SEC		(VCP_R_SEC_CTRL + 0x0048)
+#define VCP_GPR3_CFGREG_SEC		(VCP_R_SEC_CTRL + 0x004C)
+#define VCP_R_SEC_DOMAIN		(VCP_R_SEC_CTRL + 0x0080)
+#define VCP_DOMAIN_ID			U(13)
+#define VCP_DOMAIN_MASK			U(0xF)
+#define VCP_CORE0_TH0_PM_AXI_DOMAIN	(0)
+#define VCP_CORE0_TH0_DM_AXI_DOMAIN	(4)
+#define VCP_S_DMA0_DOMAIN		(12)
+#define VCP_HWCCF_DOMAIN		(16)
+#define VCP_CORE0_TH1_PM_AXI_DOMAIN	(20)
+#define VCP_CORE0_TH1_DM_AXI_DOMAIN	(24)
+#define VCP_DOMAIN_SET			((VCP_DOMAIN_ID << VCP_CORE0_TH0_PM_AXI_DOMAIN) | \
+					 (VCP_DOMAIN_ID << VCP_CORE0_TH0_DM_AXI_DOMAIN) | \
+					 (VCP_DOMAIN_ID << VCP_CORE0_TH1_PM_AXI_DOMAIN) | \
+					 (VCP_DOMAIN_ID << VCP_CORE0_TH1_DM_AXI_DOMAIN) | \
+					 (VCP_DOMAIN_ID << VCP_S_DMA0_DOMAIN))
+#define VCP_R_SEC_DOMAIN_MMPC		(VCP_R_SEC_CTRL + 0x0084)
+#define VCP_CORE_MMPC_PM_AXI_DOMAIN	(0)
+#define VCP_CORE_MMPC_DM_AXI_DOMAIN	(4)
+#define VCP_DOMAIN_SET_MMPC		((VCP_DOMAIN_ID << VCP_CORE_MMPC_PM_AXI_DOMAIN) | \
+					(VCP_DOMAIN_ID << VCP_CORE_MMPC_DM_AXI_DOMAIN))
+#define R_L2TCM_OFFSET_RANGE_0_LOW	(VCP_R_SEC_CTRL + 0x00B0)
+#define R_L2TCM_OFFSET_RANGE_0_HIGH	(VCP_R_SEC_CTRL + 0x00B4)
+#define R_L2TCM_OFFSET			(VCP_R_SEC_CTRL + 0x00D0)
+#define VCP_R_DYN_SECURE		(VCP_R_SEC_CTRL + 0x01d0)
+#define VCP_NS_I0			BIT(4)
+#define VCP_NS_D0			BIT(6)
+#define VCP_NS_SECURE_B_REGION_ENABLE	(24)
+#define RESET_NS_SECURE_B_REGION	U(0xFF)
+#define VCP_R_DYN_SECURE_TH1		(VCP_R_SEC_CTRL + 0x01d4)
+#define VCP_NS_I1			BIT(5)
+#define VCP_NS_D1			BIT(7)
+#define VCP_R_S_DOM_EN0_31		(VCP_R_SEC_CTRL + 0x0200)
+#define VCP_R_S_DOM_EN32_63		(VCP_R_SEC_CTRL + 0x0204)
+#define VCP_R_NS_DOM_EN0_31		(VCP_R_SEC_CTRL + 0x0208)
+#define VCP_R_NS_DOM_EN32_63		(VCP_R_SEC_CTRL + 0x020c)
+/* IOMMU */
+#define VCP_R_AXIOMMUEN_DEV_APC		(VCP_R_SEC_CTRL + 0x0088)
+#define VCP_R_CFG_DEVAPC_AO_BASE	(MTK_VCP_REG_BASE + 0x2d0000)
+
+#endif /* VCP_REG_H */
diff --git a/plat/mediatek/drivers/vcp/rules.mk b/plat/mediatek/drivers/vcp/rules.mk
new file mode 100644
index 0000000..9e342de
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := vcp
+
+SUB_RULES-y := $(LOCAL_DIR)/rv
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.c b/plat/mediatek/drivers/vcp/rv/mmup_common.c
new file mode 100644
index 0000000..a6d0819
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "mmup_common.h"
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[MMUP]"
+
+bool mmup_smc_rstn_set(bool boot_ok)
+{
+	if (mmio_read_32(VCP_GPR_CORE1_REBOOT) != 0 &&
+	    mmio_read_32(VCP_R_CORE1_STATUS) != 0 &&
+	    (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+	    (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+	    mmio_read_32(VCP_GPR_CORE1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+		ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x\n",
+		      MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+		      mmio_read_32(VCP_R_GIPC_IN_CLR),
+		      mmio_read_32(VCP_GPR_CORE1_REBOOT));
+		return false;
+	}
+
+	mmio_write_32(VCP_R_CORE1_SW_RSTN_SET, BIT(0));
+
+	/* reset sec control */
+	mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+	/* reset domain setting */
+	mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+	mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+	mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+	mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+	/* reset sec setting */
+	mmio_clrbits_32(VCP_R_DYN_SECURE,
+			RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+	if (boot_ok)
+		mmio_write_32(VCP_GPR_CORE1_REBOOT, VCP_CORE_REBOOT_OK);
+
+	dsbsy();
+	return true;
+}
+
+bool mmup_smc_rstn_clr(void)
+{
+	if ((mmio_read_32(VCP_R_CORE1_SW_RSTN_SET) & BIT(0)) == 1) {
+		ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+		return false;
+	}
+
+	if ((get_mmup_fw_size() == 0) || get_mmup_l2tcm_offset() == 0) {
+		ERROR("%s: [%s] mmup no enough l2tcm to run !\n", MODULE_TAG, __func__);
+		return false;
+	}
+
+	mmio_write_32(VCP_R_SEC_DOMAIN_MMPC, VCP_DOMAIN_SET_MMPC);
+
+	/* enable IOVA Mode */
+	mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+	/* reset secure setting */
+	mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE1_SEC_BIT_SEL);
+
+	/* l2tcm offset*/
+	mmio_setbits_32(VCP_R_SEC_CTRL, VCP_OFFSET_ENABLE_P | VCP_OFFSET_ENABLE_B);
+	mmio_write_32(R_L2TCM_OFFSET_RANGE_0_LOW, 0x0);
+	mmio_write_32(R_L2TCM_OFFSET_RANGE_0_HIGH, round_up(get_mmup_fw_size(), PAGE_SIZE));
+	mmio_write_32(R_L2TCM_OFFSET, get_mmup_l2tcm_offset());
+
+	/* start vcp-mmup */
+	mmio_write_32(VCP_R_CORE1_SW_RSTN_CLR, BIT(0));
+	dsbsy();
+	return true;
+}
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.h b/plat/mediatek/drivers/vcp/rv/mmup_common.h
new file mode 100644
index 0000000..e70d25f
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MMUP_COMMON_H
+#define MMUP_COMMON_H
+
+bool mmup_smc_rstn_set(bool boot_ok);
+bool mmup_smc_rstn_clr(void);
+
+#endif /* MMUP_COMMON_H */
diff --git a/plat/mediatek/drivers/vcp/rv/rules.mk b/plat/mediatek/drivers/vcp/rv/rules.mk
new file mode 100644
index 0000000..e637067
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := vcp_rv_${MTK_SOC}
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/vcp/${MTK_SOC}
+
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} := ${LOCAL_DIR}/vcp_common.c
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} += ${LOCAL_DIR}/mmup_common.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/vcp/rv/vcp_common.c b/plat/mediatek/drivers/vcp/rv/vcp_common.c
new file mode 100644
index 0000000..9dfb133
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/vcp_common.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+
+#include "mmup_common.h"
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[VCP]"
+
+static const mmap_region_t vcp_mmap[] MTK_MMAP_SECTION = {
+	MAP_REGION_FLAT(VCP_R_CFGREG, MTK_VCP_REG_BANK_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(VCP_R_CFGREG_CORE0, MTK_VCP_REG_BANK_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(VCP_R_CFGREG_CORE1, MTK_VCP_REG_BANK_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(VCP_R_SEC_CTRL, MTK_VCP_REG_BANK_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+DECLARE_MTK_MMAP_REGIONS(vcp_mmap);
+
+/* vcp-mmup l2tcm memory offset */
+static uint64_t g_l2tcm_offset;
+static uint32_t g_mmup_fw_size;
+
+static bool get_vcp_pwr_status(void)
+{
+#if defined(SPM_BASE)
+	uint32_t spm_pwr_sta = mmio_read_32(SPM_BASE + VCP_POWER_STATUS);
+
+	if (!(spm_pwr_sta & (MMUP_PWR_STA_EN << MMUP_PWR_STA_BIT))) {
+		ERROR("%s: pwr_sta:%x, bit:%d disable\n", MODULE_TAG,
+		      spm_pwr_sta, MMUP_PWR_STA_BIT);
+		return false;
+	}
+#endif
+	return true;
+}
+
+uint32_t get_mmup_fw_size(void)
+{
+	return g_mmup_fw_size;
+}
+
+uint64_t get_mmup_l2tcm_offset(void)
+{
+	return g_l2tcm_offset;
+}
+
+static bool vcp_cold_boot_reset(void)
+{
+	mmio_write_32(VCP_GPR2_CFGREG_SEC, 0);
+	mmio_write_32(VCP_GPR3_CFGREG_SEC, 0);
+
+	return true;
+}
+
+static bool mmup_cold_boot_reset(void)
+{
+	mmio_write_32(VCP_GPR0_CFGREG_SEC, 0);
+	mmio_write_32(VCP_GPR1_CFGREG_SEC, 0);
+
+	return true;
+}
+
+static bool vcp_set_mmup_l2tcm_offset(uint64_t l2tcm_offset)
+{
+	g_l2tcm_offset = l2tcm_offset;
+
+	if (g_l2tcm_offset > MTK_VCP_SRAM_SIZE) {
+		g_l2tcm_offset = 0;
+		return false;
+	}
+
+	return true;
+}
+
+static bool vcp_set_mmup_fw_size(uint64_t fw_size)
+{
+	g_mmup_fw_size = fw_size;
+
+	if (g_mmup_fw_size > MTK_VCP_SRAM_SIZE - g_l2tcm_offset) {
+		g_mmup_fw_size = 0;
+		return false;
+	}
+
+	return true;
+}
+
+static bool vcp_smc_rstn_set(bool boot_ok)
+{
+	if (mmio_read_32(VCP_GPR_C0_H0_REBOOT) != 0 &&
+	    mmio_read_32(VCP_R_CORE0_STATUS) != 0 &&
+	    (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+	    (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+	    mmio_read_32(VCP_GPR_C0_H0_REBOOT) != VCP_CORE_RDY_TO_REBOOT &&
+	    mmio_read_32(VCP_GPR_C0_H1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+		ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x 0x%x\n",
+		      MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+		      mmio_read_32(VCP_R_GIPC_IN_CLR),
+		      mmio_read_32(VCP_GPR_C0_H0_REBOOT),
+		      mmio_read_32(VCP_GPR_C0_H1_REBOOT));
+		return false;
+	}
+
+	mmio_write_32(VCP_R_CORE0_SW_RSTN_SET, BIT(0));
+
+	/* reset sec control */
+	mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+	/* reset domain setting */
+	mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+	mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+	mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+	mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+	/* reset sec setting */
+	mmio_clrbits_32(VCP_R_DYN_SECURE,
+			RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+	if (boot_ok) {
+		mmio_write_32(VCP_GPR_C0_H0_REBOOT, VCP_CORE_REBOOT_OK);
+		mmio_write_32(VCP_GPR_C0_H1_REBOOT, VCP_CORE_REBOOT_OK);
+	}
+
+	dsbsy();
+	return true;
+}
+
+static bool vcp_smc_rstn_clr(void)
+{
+	if ((mmio_read_32(VCP_R_CORE0_SW_RSTN_SET) & BIT(0)) == 1) {
+		ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+		return false;
+	}
+
+	mmio_clrsetbits_32(VCP_R_SEC_DOMAIN,
+			   ~(VCP_DOMAIN_MASK << VCP_HWCCF_DOMAIN), VCP_DOMAIN_SET);
+
+	/* enable IOVA Mode */
+	mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+	/* reset secure setting */
+	mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE0_SEC_BIT_SEL);
+	mmio_clrbits_32(VCP_R_DYN_SECURE, VCP_NS_I0 | VCP_NS_D0);
+	mmio_clrbits_32(VCP_R_DYN_SECURE_TH1, VCP_NS_I1 | VCP_NS_D1);
+
+	/* start vcp */
+	mmio_write_32(VCP_R_CORE0_SW_RSTN_CLR, BIT(0));
+	dsbsy();
+	return true;
+}
+
+static u_register_t tinysys_vcp_kernel_control(u_register_t arg0,
+					       u_register_t arg1,
+					       u_register_t arg2,
+					       u_register_t arg3,
+					       void *handle,
+					       struct smccc_res *smccc_ret)
+{
+	uint32_t request_ops;
+	uint64_t ret = MTK_SIP_E_SUCCESS;
+
+	if (!get_vcp_pwr_status())
+		return MTK_SIP_E_NOT_SUPPORTED;
+
+	request_ops = (uint32_t)arg0;
+
+	switch (request_ops) {
+	case MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET:
+		ret = vcp_smc_rstn_set((bool)!!arg1);
+		break;
+	case MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE:
+		ret = vcp_smc_rstn_clr();
+		break;
+	case MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP:
+		ret = vcp_cold_boot_reset();
+		break;
+	case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET:
+		ret = mmup_smc_rstn_set((bool)!!arg1);
+		break;
+	case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE:
+		ret = mmup_smc_rstn_clr();
+		break;
+	case MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET:
+		ret = vcp_set_mmup_l2tcm_offset(arg1);
+		break;
+	case MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE:
+		ret = vcp_set_mmup_fw_size(arg1);
+		break;
+	case MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP:
+		ret = mmup_cold_boot_reset();
+		break;
+	default:
+		ERROR("%s: %s, unknown request_ops = %x\n", MODULE_TAG, __func__, request_ops);
+		ret = MTK_SIP_E_INVALID_PARAM;
+		break;
+	}
+
+	return ret;
+}
+
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_VCP_CONTROL, tinysys_vcp_kernel_control);
diff --git a/plat/mediatek/helpers/armv9/arch_helpers.S b/plat/mediatek/helpers/armv9/arch_helpers.S
new file mode 100644
index 0000000..f96fff9
--- /dev/null
+++ b/plat/mediatek/helpers/armv9/arch_helpers.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#if CONFIG_MTK_MCUSYS
+#include <mcucfg.h>
+#endif
+
+	/*
+	 * Declare as weak function so that can be
+	 * overwritten by platform helpers
+	 */
+	.weak platform_mem_init
+	.weak plat_core_pos_by_mpidr
+	.weak plat_my_core_pos
+	.weak plat_mediatek_calc_core_pos
+	.global plat_mpidr_by_core_pos
+	.global plat_reset_handler
+
+	/* -----------------------------------------------------
+	 * unsigned long plat_mpidr_by_core_pos(uint32_t cpuid)
+	 * This function calcuate mpidr by cpu pos if cpu
+	 * topology is linear.
+	 *
+	 * Clobbers: x0-x1
+	 * -----------------------------------------------------
+	 */
+func plat_mpidr_by_core_pos
+	lsl x0, x0, #MPIDR_AFF1_SHIFT
+	mrs x1, mpidr_el1
+	and x1, x1, #MPIDR_MT_MASK
+	orr x0, x0, x1
+	ret
+endfunc plat_mpidr_by_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_arm_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * int plat_mediatek_calc_core_pos(u_register_t mpidr);
+	 *
+	 * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
+	 * AFF0 is thread id. There is only one cluster in ARMv8.2
+	 * and one thread in current implementation.
+	 *
+	 * With this function: CorePos = CoreID (AFF1)
+	 * we do it with x0 = (x0 >> 8) & 0xff
+	 * -----------------------------------------------------
+	 */
+func plat_mediatek_calc_core_pos
+	b plat_core_pos_by_mpidr
+endfunc plat_mediatek_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+	 *
+	 * This function implements a part of the critical
+	 * interface between the psci generic layer and the
+	 * platform that allows the former to query the platform
+	 * to convert an MPIDR to a unique linear index.
+	 *
+	 * Clobbers: x0-x1
+	 * ------------------------------------------------------
+	 */
+func plat_core_pos_by_mpidr
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_core_pos_by_mpidr
+
+	/* --------------------------------------------------------
+	 * 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
+
+func plat_reset_handler
+#if CONFIG_MTK_MCUSYS
+	mov x10, x30
+	bl plat_my_core_pos
+	mov x30, x10
+	mov w1, #0x1
+	lsl w1, w1, w0
+	ldr x0, =CPC_MCUSYS_CPU_ON_SW_HINT_SET
+	str w1, [x0]
+	dsb sy
+#endif
+
+	ret
+endfunc plat_reset_handler
diff --git a/plat/mediatek/include/armv9/arch_def.h b/plat/mediatek/include/armv9/arch_def.h
new file mode 100644
index 0000000..d1d5a14
--- /dev/null
+++ b/plat/mediatek/include/armv9/arch_def.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_DEF_H
+#define ARCH_DEF_H
+
+#include <arch.h>
+
+/* Topology constants */
+#ifndef PLAT_MAX_PWR_LVL
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#endif
+#define PLAT_MAX_RET_STATE		MPIDR_AFFLVL1
+
+#ifndef PLAT_MAX_OFF_STATE
+#define PLAT_MAX_OFF_STATE		MPIDR_AFFLVL2
+#endif
+
+#define PLATFORM_SYSTEM_COUNT         1
+#define PLATFORM_CLUSTER_COUNT        1
+#define PLATFORM_CLUSTER0_CORE_COUNT  8
+#define PLATFORM_CORE_COUNT	(PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	8
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+/* Cachline size */
+#define CACHE_WRITEBACK_SHIFT	6
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+#endif /* ARCH_DEF_H */
diff --git a/plat/mediatek/include/drivers/apusys_rv_public.h b/plat/mediatek/include/drivers/apusys_rv_public.h
new file mode 100644
index 0000000..485453f
--- /dev/null
+++ b/plat/mediatek/include/drivers/apusys_rv_public.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PUBLIC_H
+#define APUSYS_RV_PUBLIC_H
+
+#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
+int apusys_rv_iommu_hw_sem_trylock(void);
+int apusys_rv_iommu_hw_sem_unlock(void);
+#else
+#define apusys_rv_iommu_hw_sem_trylock() 0
+#define apusys_rv_iommu_hw_sem_unlock() 0
+#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
+
+#endif /* APUSYS_RV_PUBLIC_H */
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
index a86a46c..6f496d2 100644
--- a/plat/mediatek/include/mtk_sip_def.h
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -13,16 +13,20 @@
 	_func(MTK_SIP_KERNEL_DFD, 0x205) \
 	_func(MTK_SIP_KERNEL_MSDC, 0x273) \
 	_func(MTK_SIP_VCORE_CONTROL, 0x506) \
+	_func(MTK_SIP_EMIDBG_CONTROL, 0x50B) \
 	_func(MTK_SIP_IOMMU_CONTROL, 0x514) \
 	_func(MTK_SIP_AUDIO_CONTROL, 0x517) \
 	_func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
 	_func(MTK_SIP_DP_CONTROL, 0x523) \
-	_func(MTK_SIP_KERNEL_GIC_OP, 0x526)
+	_func(MTK_SIP_KERNEL_GIC_OP, 0x526) \
+	_func(MTK_SIP_KERNEL_VCP_CONTROL, 0x52C)
 
 #define MTK_SIP_SMC_FROM_S_EL1_TABLE(_func) \
-	_func(MTK_SIP_TEE_MPU_PERM_SET, 0x031)
+	_func(MTK_SIP_TEE_MPU_PERM_SET, 0x031) \
+	_func(MTK_SIP_TEE_EMI_MPU_CONTROL, 0x048)
 
 #define MTK_SIP_SMC_FROM_BL33_TABLE(_func) \
-	_func(MTK_SIP_KERNEL_BOOT, 0x115)
+	_func(MTK_SIP_KERNEL_BOOT, 0x115) \
+	_func(MTK_SIP_BL_EMIMPU_CONTROL, 0x415)
 
 #endif /* MTK_SIP_DEF_H */
diff --git a/plat/mediatek/mt8188/include/plat_helpers.h b/plat/mediatek/include/plat_helpers.h
similarity index 71%
rename from plat/mediatek/mt8188/include/plat_helpers.h
rename to plat/mediatek/include/plat_helpers.h
index eb78623..b86ed23 100644
--- a/plat/mediatek/mt8188/include/plat_helpers.h
+++ b/plat/mediatek/include/plat_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/mediatek/lib/pm/armv9_0/rules.mk b/plat/mediatek/lib/pm/armv9_0/rules.mk
new file mode 100644
index 0000000..08a7957
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv9_0/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := armv${CONFIG_MTK_PM_ARCH}
+
+LOCAL_SRCS-y :=
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
index 8c012e7..9eb348e 100644
--- a/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
 #include <plat_mtk_lpm.h>
 #include <plat_pm.h>
 
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
 static int plat_mt_lp_cpu_rc;
 
 static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8186/include/plat_helpers.h b/plat/mediatek/mt8186/include/plat_helpers.h
deleted file mode 100644
index ebc9fa0..0000000
--- a/plat/mediatek/mt8186/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index 98b88bd..707f4a5 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -77,6 +77,11 @@
 #define MSDC0_BASE		(IO_PHYS + 0x01230000)
 
 /*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE		(IO_PHYS + 0x0020F000)
+
+/*******************************************************************************
  * GIC-600 & interrupt handling related constants
  ******************************************************************************/
 /* Base MTK_platform compatible GIC memory map */
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 2bd2fb4..9c03340 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,6 +7,9 @@
 MTK_PLAT     := plat/mediatek
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
+# True Random Number Generator firmware Interface
+TRNG_SUPPORT := 1
+
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
@@ -79,6 +82,11 @@
                 ${MTK_PLAT_SOC}/plat_sip_calls.c                      \
                 ${MTK_PLAT_SOC}/plat_topology.c
 
+ifeq (${TRNG_SUPPORT},1)
+BL31_SOURCES += ${MTK_PLAT}/drivers/rng/rng.c                         \
+                ${MTK_PLAT}/drivers/rng/${PLAT}/rng_plat.c
+endif
+
 # Build SPM drivers
 include ${MTK_PLAT_SOC}/drivers/spm/build.mk
 
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 8e0f5f9..dccb052 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -190,6 +190,11 @@
 #define SUB_EMI_MPU_BASE	(IO_PHYS + 0x00225000)
 
 /*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE		(IO_PHYS + 0x0020F000)
+
+/*******************************************************************************
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_HZ	(13000000)
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 2e3392f..82ef7e8 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -46,5 +46,8 @@
 CPU_PM_TINYSYS_SUPPORT := y
 MTK_PUBEVENT_ENABLE := y
 
+# True Random Number Generator firmware Interface
+TRNG_SUPPORT := 1
+
 MACH_MT8188 := 1
 $(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index 5096e15..b776447 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -39,6 +39,9 @@
 MODULES-y += $(MTK_PLAT)/drivers/pmic
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
 MODULES-y += $(MTK_PLAT)/drivers/ptp3
+ifeq (${TRNG_SUPPORT},1)
+MODULES-y += $(MTK_PLAT)/drivers/rng
+endif
 MODULES-y += $(MTK_PLAT)/drivers/rtc
 MODULES-y += $(MTK_PLAT)/drivers/spm
 MODULES-y += $(MTK_PLAT)/drivers/timer
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
index 26bed29..7b867d8 100644
--- a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
@@ -97,7 +97,7 @@
 
 	/* PCI-e protect address(64MB) */
 	region_info.start = 0xC0000000ULL;
-	region_info.end = 0xC3FF0000ULL;
+	region_info.end = 0xC3FFFFFFULL;
 	region_info.region = 1;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -108,7 +108,7 @@
 
 	/* SCP protect address */
 	region_info.start = 0x50000000ULL;
-	region_info.end = 0x513F0000ULL;
+	region_info.end = 0x513FFFFFULL;
 	region_info.region = 2;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -117,21 +117,10 @@
 			      NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
 	emi_mpu_set_protection(&region_info);
 
-	/* DSP protect address */
-	region_info.start = 0x40000000ULL;	/* dram base addr */
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 3;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
-	emi_mpu_set_protection(&region_info);
-
 	/* Forbidden All */
 	region_info.start = 0x40000000ULL;	/* dram base addr */
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 4;
+	region_info.end = 0x1FFFFFFFFULL;
+	region_info.region = 3;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
index b483c36..1df75f7 100644
--- a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
 #include <plat_mtk_lpm.h>
 #include <plat_pm.h>
 
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
 static int plat_mt_lp_cpu_rc;
 
 static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8192/include/plat_helpers.h b/plat/mediatek/mt8192/include/plat_helpers.h
deleted file mode 100644
index 9b550ee..0000000
--- a/plat/mediatek/mt8192/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
index b6e5a2d..8e4a675 100644
--- a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
@@ -118,7 +118,7 @@
 
 	/* SCP DRAM */
 	region_info.start = 0x50000000ULL;
-	region_info.end = 0x51400000ULL;
+	region_info.end = 0x513FFFFFULL;
 	region_info.region = 2;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
index 5a80d95..d32a7df 100644
--- a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
 #include <plat_mtk_lpm.h>
 #include <plat_pm.h>
 
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
 static int plat_mt_lp_cpu_rc;
 
 static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8195/include/plat_helpers.h b/plat/mediatek/mt8195/include/plat_helpers.h
deleted file mode 100644
index ebc9fa0..0000000
--- a/plat/mediatek/mt8195/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.c b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
new file mode 100644
index 0000000..6257159
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+#include <mtgpio.h>
+
+typedef enum {
+	REG_0 = 0,
+	REG_1,
+	REG_2,
+	REG_3,
+	REG_4,
+	REG_5,
+	REG_6,
+	REG_7,
+	REG_8,
+	REG_9,
+	REG_10,
+	REG_11,
+	REG_12,
+	REG_13,
+	REG_14
+} RegEnum;
+
+uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
+{
+	uintptr_t reg_addr = 0U;
+	struct mt_pin_info gpio_info;
+
+	assert(pin < MAX_GPIO_PIN);
+
+	gpio_info = mt_pin_infos[pin];
+
+	switch (gpio_info.base & 0xF) {
+	case REG_0:
+		reg_addr = IOCFG_RT_BASE;
+		break;
+	case REG_1:
+		reg_addr = IOCFG_RM1_BASE;
+		break;
+	case REG_2:
+		reg_addr = IOCFG_RM2_BASE;
+		break;
+	case REG_3:
+		reg_addr = IOCFG_RB_BASE;
+		break;
+	case REG_4:
+		reg_addr = IOCFG_BM1_BASE;
+		break;
+	case REG_5:
+		reg_addr = IOCFG_BM2_BASE;
+		break;
+	case REG_6:
+		reg_addr = IOCFG_BM3_BASE;
+		break;
+	case REG_7:
+		reg_addr = IOCFG_LT_BASE;
+		break;
+	case REG_8:
+		reg_addr = IOCFG_LM1_BASE;
+		break;
+	case REG_9:
+		reg_addr = IOCFG_LM2_BASE;
+		break;
+	case REG_10:
+		reg_addr = IOCFG_LB1_BASE;
+		break;
+	case REG_11:
+		reg_addr = IOCFG_LB2_BASE;
+		break;
+	case REG_12:
+		reg_addr = IOCFG_TM1_BASE;
+		break;
+	case REG_13:
+		reg_addr = IOCFG_TM2_BASE;
+		break;
+	case REG_14:
+		reg_addr = IOCFG_TM3_BASE;
+		break;
+	default:
+		break;
+	}
+
+	return reg_addr;
+}
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.h b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
new file mode 100644
index 0000000..a33bdad
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GPIO_H
+#define MT_GPIO_H
+
+#include <mtgpio_common.h>
+
+/* Enumeration for GPIO pin */
+typedef enum GPIO_PIN {
+	GPIO_UNSUPPORTED = -1,
+	GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6,
+	GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14,
+	GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22,
+	GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30,
+	GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
+	GPIO39, GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46,
+	GPIO47, GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54,
+	GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62,
+	GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70,
+	GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78,
+	GPIO79, GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86,
+	GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94,
+	GPIO95, GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102,
+	GPIO103, GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110,
+	GPIO111, GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118,
+	GPIO119, GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126,
+	GPIO127, GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134,
+	GPIO135, GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142,
+	GPIO143, GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150,
+	GPIO151, GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158,
+	GPIO159, GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166,
+	GPIO167, GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174,
+	GPIO175, GPIO176, GPIO177, GPIO178, GPIO179, GPIO180, GPIO181, GPIO182,
+	GPIO183, GPIO184, GPIO185, GPIO186, GPIO187, GPIO188, GPIO189, GPIO190,
+	GPIO191, GPIO192, GPIO193, GPIO194, GPIO195, GPIO196, GPIO197, GPIO198,
+	GPIO199, GPIO200, GPIO201, GPIO202, GPIO203, GPIO204, GPIO205, GPIO206,
+	GPIO207, GPIO208, GPIO209, GPIO210, GPIO211, GPIO212, GPIO213, GPIO214,
+	GPIO215, GPIO216, GPIO217, GPIO218, GPIO219, GPIO220, GPIO221, GPIO222,
+	GPIO223, GPIO224, GPIO225, GPIO226, GPIO227, GPIO228, GPIO229, GPIO230,
+	GPIO231, GPIO232, GPIO233, GPIO234, GPIO235, GPIO236, GPIO237, GPIO238,
+	GPIO239, GPIO240, GPIO241, GPIO242, GPIO243, GPIO244, GPIO245, GPIO246,
+	GPIO247, GPIO248, GPIO249, GPIO250, GPIO251, GPIO252, GPIO253, GPIO254,
+	GPIO255, GPIO256, GPIO257, GPIO258, GPIO259, GPIO260, GPIO261, GPIO262,
+	GPIO263, GPIO264, GPIO265, GPIO266, GPIO267, GPIO268, GPIO269, GPIO270,
+	MT_GPIO_BASE_MAX
+} GPIO_PIN;
+
+static const struct mt_pin_info mt_pin_infos[] = {
+	PIN(0, 0, 0, 0x18, 0x90),
+	PIN(1, 0, 1, 0x18, 0x90),
+	PIN(2, 0, 1, 0x1b, 0x70),
+	PIN(3, 0, 2, 0x1b, 0x70),
+	PIN(4, 0, 3, 0x1b, 0x70),
+	PIN(5, 0, 4, 0x1b, 0x70),
+	PIN(6, 0, 5, 0x1b, 0x70),
+	PIN(7, 0, 6, 0x1b, 0x70),
+	PIN(8, 0, 7, 0x1b, 0x70),
+	PIN(9, 0, 14, 0x29, 0xa0),
+	PIN(10, 0, 12, 0x29, 0xa0),
+	PIN(11, 0, 2, 0x18, 0x90),
+	PIN(12, 0, 13, 0x29, 0xa0),
+	PIN(13, 0, 1, 0x26, 0x90),
+	PIN(14, 0, 0, 0x13, 0x80),
+	PIN(15, 0, 2, 0x26, 0x90),
+	PIN(16, 0, 3, 0x26, 0x90),
+	PIN(17, 0, 4, 0x26, 0x90),
+	PIN(18, 0, 5, 0x26, 0x90),
+	PIN(19, 0, 6, 0x26, 0x90),
+	PIN(20, 0, 1, 0x13, 0x80),
+	PIN(21, 0, 3, 0x12, 0x80),
+	PIN(22, 0, 4, 0x12, 0x80),
+	PIN(23, 0, 5, 0x12, 0x80),
+	PIN(24, 0, 6, 0x12, 0x80),
+	PIN(25, 0, 7, 0x12, 0x80),
+	PIN(26, 0, 8, 0x12, 0x80),
+	PIN(27, 0, 9, 0x12, 0x80),
+	PIN(28, 0, 10, 0x12, 0x80),
+	PIN(29, 0, 11, 0x12, 0x80),
+	PIN(30, 0, 12, 0x12, 0x80),
+	PIN(31, 0, 13, 0x12, 0x80),
+	PIN(32, 0, 8, 0x11, 0x80),
+	PIN(33, 0, 9, 0x11, 0x80),
+	PIN(34, 0, 10, 0x11, 0x80),
+	PIN(35, 0, 11, 0x11, 0x80),
+	PIN(36, 0, 12, 0x11, 0x80),
+	PIN(37, 0, 13, 0x11, 0x80),
+	PIN(38, 0, 14, 0x11, 0x80),
+	PIN(39, 0, 6, 0x18, 0x90),
+	PIN(40, 0, 3, 0x18, 0x90),
+	PIN(41, 0, 5, 0x18, 0x90),
+	PIN(42, 0, 4, 0x18, 0x90),
+	PIN(43, 0, 7, 0x18, 0x90),
+	PIN(44, 0, 8, 0x18, 0x90),
+	PIN(45, 0, 9, 0x18, 0x90),
+	PIN(46, 0, 10, 0x18, 0x90),
+	PIN(47, 0, 13, 0x18, 0x90),
+	PIN(48, 0, 11, 0x18, 0x90),
+	PIN(49, 0, 14, 0x18, 0x90),
+	PIN(50, 0, 12, 0x18, 0x90),
+	PIN(51, 0, 15, 0x18, 0x90),
+	PIN(52, 0, 7, 0x29, 0xa0),
+	PIN(53, 0, 8, 0x29, 0xa0),
+	PIN(54, 0, 2, 0x29, 0xa0),
+	PIN(55, 0, 1, 0x29, 0xa0),
+	PIN(56, 0, 5, 0x29, 0xa0),
+	PIN(57, 0, 6, 0x29, 0xa0),
+	PIN(58, 0, 3, 0x29, 0xa0),
+	PIN(59, 0, 4, 0x29, 0xa0),
+	PIN(60, 1, 0, 0x29, 0xb0),
+	PIN(61, 0, 10, 0x29, 0xa0),
+	PIN(62, 0, 9, 0x29, 0xa0),
+	PIN(63, 0, 18, 0x29, 0xa0),
+	PIN(64, 0, 0, 0x29, 0xa0),
+	PIN(65, 0, 11, 0x29, 0xa0),
+	PIN(66, 0, 24, 0x29, 0xa0),
+	PIN(67, 0, 21, 0x29, 0xa0),
+	PIN(68, 0, 20, 0x29, 0xa0),
+	PIN(69, 0, 25, 0x29, 0xa0),
+	PIN(70, 0, 16, 0x29, 0xa0),
+	PIN(71, 0, 15, 0x29, 0xa0),
+	PIN(72, 0, 23, 0x29, 0xa0),
+	PIN(73, 0, 19, 0x29, 0xa0),
+	PIN(74, 0, 17, 0x29, 0xa0),
+	PIN(75, 0, 2, 0x1a, 0x80),
+	PIN(76, 0, 3, 0x1a, 0x80),
+	PIN(77, 0, 4, 0x1a, 0x80),
+	PIN(78, 0, 5, 0x1a, 0x80),
+	PIN(79, 0, 0, 0x1a, 0x80),
+	PIN(80, 0, 1, 0x1a, 0x80),
+	PIN(81, 0, 9, 0x1b, 0x70),
+	PIN(82, 0, 10, 0x1b, 0x70),
+	PIN(83, 0, 12, 0x1b, 0x70),
+	PIN(84, 0, 11, 0x1b, 0x70),
+	PIN(85, 0, 13, 0x1b, 0x70),
+	PIN(86, 0, 14, 0x1b, 0x70),
+	PIN(87, 0, 16, 0x1b, 0x70),
+	PIN(88, 0, 15, 0x1b, 0x70),
+	PIN(89, 0, 0, 0x1b, 0x70),
+	PIN(90, 0, 8, 0x1b, 0x70),
+	PIN(91, 0, 6, 0x1c, 0x80),
+	PIN(92, 0, 7, 0x1c, 0x80),
+	PIN(93, 0, 8, 0x1c, 0x80),
+	PIN(94, 0, 4, 0x1c, 0x80),
+	PIN(95, 0, 1, 0x1c, 0x80),
+	PIN(96, 0, 3, 0x1c, 0x80),
+	PIN(97, 0, 2, 0x1c, 0x80),
+	PIN(98, 0, 5, 0x1c, 0x80),
+	PIN(99, 0, 9, 0x1c, 0x80),
+	PIN(100, 0, 12, 0x1c, 0x80),
+	PIN(101, 0, 10, 0x1c, 0x80),
+	PIN(102, 0, 13, 0x1c, 0x80),
+	PIN(103, 0, 0, 0x1c, 0x80),
+	PIN(104, 0, 11, 0x1c, 0x80),
+	PIN(105, 0, 14, 0x1c, 0x80),
+	PIN(106, 0, 0, 0x15, 0x80),
+	PIN(107, 0, 1, 0x15, 0x80),
+	PIN(108, 0, 3, 0x15, 0x80),
+	PIN(109, 0, 2, 0x15, 0x80),
+	PIN(110, 0, 4, 0x15, 0x80),
+	PIN(111, 0, 5, 0x15, 0x80),
+	PIN(112, 0, 7, 0x15, 0x80),
+	PIN(113, 0, 6, 0x15, 0x80),
+	PIN(114, 0, 8, 0x15, 0x80),
+	PIN(115, 0, 9, 0x15, 0x80),
+	PIN(116, 0, 11, 0x15, 0x80),
+	PIN(117, 0, 10, 0x15, 0x80),
+	PIN(118, 0, 9, 0x26, 0x90),
+	PIN(119, 0, 10, 0x26, 0x90),
+	PIN(120, 0, 12, 0x26, 0x90),
+	PIN(121, 0, 11, 0x26, 0x90),
+	PIN(122, 0, 0, 0x26, 0x90),
+	PIN(123, 0, 7, 0x26, 0x90),
+	PIN(124, 0, 8, 0x26, 0x90),
+	PIN(125, 1, 0, 0x17, 0x80),
+	PIN(126, 1, 1, 0x17, 0x80),
+	PIN(127, 1, 2, 0x17, 0x80),
+	PIN(128, 1, 3, 0x17, 0x80),
+	PIN(129, 1, 4, 0x17, 0x80),
+	PIN(130, 1, 5, 0x17, 0x80),
+	PIN(131, 1, 9, 0x17, 0x80),
+	PIN(132, 1, 11, 0x17, 0x80),
+	PIN(133, 1, 10, 0x17, 0x80),
+	PIN(134, 1, 6, 0x17, 0x80),
+	PIN(135, 1, 8, 0x17, 0x80),
+	PIN(136, 1, 7, 0x17, 0x80),
+	PIN(137, 1, 10, 0x14, 0x70),
+	PIN(138, 1, 11, 0x14, 0x70),
+	PIN(139, 1, 12, 0x14, 0x70),
+	PIN(140, 1, 13, 0x14, 0x70),
+	PIN(141, 1, 14, 0x14, 0x70),
+	PIN(142, 1, 15, 0x14, 0x70),
+	PIN(143, 1, 16, 0x14, 0x70),
+	PIN(144, 1, 17, 0x14, 0x70),
+	PIN(145, 1, 0, 0x14, 0x70),
+	PIN(146, 1, 1, 0x14, 0x70),
+	PIN(147, 1, 2, 0x14, 0x70),
+	PIN(148, 1, 3, 0x14, 0x70),
+	PIN(149, 1, 4, 0x14, 0x70),
+	PIN(150, 1, 5, 0x14, 0x70),
+	PIN(151, 1, 6, 0x14, 0x70),
+	PIN(152, 1, 7, 0x14, 0x70),
+	PIN(153, 1, 9, 0x14, 0x70),
+	PIN(154, 1, 8, 0x14, 0x70),
+	PIN(155, 1, 18, 0x14, 0x70),
+	PIN(156, 1, 19, 0x14, 0x70),
+	PIN(157, 0, 1, 0x12, 0x80),
+	PIN(158, 0, 2, 0x12, 0x80),
+	PIN(159, 0, 0, 0x12, 0x80),
+	PIN(160, 0, 22, 0x13, 0x80),
+	PIN(161, 0, 20, 0x13, 0x80),
+	PIN(162, 0, 23, 0x13, 0x80),
+	PIN(163, 0, 21, 0x13, 0x80),
+	PIN(164, 0, 12, 0x13, 0x80),
+	PIN(165, 0, 14, 0x13, 0x80),
+	PIN(166, 0, 13, 0x13, 0x80),
+	PIN(167, 0, 15, 0x13, 0x80),
+	PIN(168, 0, 16, 0x13, 0x80),
+	PIN(169, 0, 17, 0x13, 0x80),
+	PIN(170, 0, 19, 0x13, 0x80),
+	PIN(171, 0, 18, 0x13, 0x80),
+	PIN(172, 0, 10, 0x13, 0x80),
+	PIN(173, 0, 11, 0x13, 0x80),
+	PIN(174, 0, 15, 0x11, 0x80),
+	PIN(175, 0, 16, 0x11, 0x80),
+	PIN(176, 0, 17, 0x11, 0x80),
+	PIN(177, 0, 18, 0x11, 0x80),
+	PIN(178, 0, 6, 0x11, 0x80),
+	PIN(179, 0, 7, 0x11, 0x80),
+	PIN(180, 0, 0, 0x11, 0x80),
+	PIN(181, 0, 1, 0x11, 0x80),
+	PIN(182, 0, 2, 0x11, 0x80),
+	PIN(183, 0, 3, 0x11, 0x80),
+	PIN(184, 0, 4, 0x11, 0x80),
+	PIN(185, 0, 5, 0x11, 0x80),
+	PIN(186, 0, 4, 0x1d, 0xc0),
+	PIN(187, 0, 5, 0x1d, 0xc0),
+	PIN(188, 0, 12, 0x1d, 0xc0),
+	PIN(189, 0, 17, 0x1d, 0xc0),
+	PIN(190, 0, 13, 0x1d, 0xc0),
+	PIN(191, 0, 18, 0x1d, 0xc0),
+	PIN(192, 0, 0, 0x1d, 0xc0),
+	PIN(193, 0, 6, 0x1d, 0xc0),
+	PIN(194, 0, 14, 0x1d, 0xc0),
+	PIN(195, 0, 19, 0x1d, 0xc0),
+	PIN(196, 0, 1, 0x1d, 0xc0),
+	PIN(197, 0, 7, 0x1d, 0xc0),
+	PIN(198, 0, 15, 0x1d, 0xc0),
+	PIN(199, 0, 20, 0x1d, 0xc0),
+	PIN(200, 0, 22, 0x1d, 0xc0),
+	PIN(201, 0, 25, 0x1d, 0xc0),
+	PIN(202, 0, 16, 0x1d, 0xc0),
+	PIN(203, 0, 21, 0x1d, 0xc0),
+	PIN(204, 0, 2, 0x1d, 0xc0),
+	PIN(205, 0, 3, 0x1d, 0xc0),
+	PIN(206, 0, 8, 0x1d, 0xc0),
+	PIN(207, 0, 9, 0x1d, 0xc0),
+	PIN(208, 0, 10, 0x1d, 0xc0),
+	PIN(209, 0, 11, 0x1d, 0xc0),
+	PIN(210, 0, 0, 0x2e, 0x90),
+	PIN(211, 0, 1, 0x2e, 0x90),
+	PIN(212, 0, 2, 0x2e, 0x90),
+	PIN(213, 0, 3, 0x2e, 0x90),
+	PIN(214, 0, 23, 0x1d, 0xc0),
+	PIN(215, 0, 24, 0x1d, 0xc0),
+	PIN(216, 0, 4, 0x2e, 0x90),
+	PIN(217, 1, 1, 0x2e, 0xa0),
+	PIN(218, 1, 2, 0x2e, 0xa0),
+	PIN(219, 1, 0, 0x2e, 0xa0),
+	PIN(220, 0, 5, 0x2e, 0x90),
+	PIN(221, 0, 6, 0x2e, 0x90),
+	PIN(222, 0, 8, 0x2e, 0x90),
+	PIN(223, 0, 7, 0x2e, 0x90),
+	PIN(224, 1, 3, 0x2e, 0xa0),
+	PIN(225, 1, 4, 0x2e, 0xa0),
+	PIN(226, 1, 5, 0x2e, 0xa0),
+	PIN(227, 1, 6, 0x2e, 0xa0),
+	PIN(228, 1, 7, 0x2e, 0xa0),
+	PIN(229, 1, 8, 0x2e, 0xa0),
+	PIN(230, 0, 13, 0x2f, 0x70),
+	PIN(231, 0, 14, 0x2f, 0x70),
+	PIN(232, 0, 10, 0x2f, 0x70),
+	PIN(233, 0, 0, 0x2f, 0x70),
+	PIN(234, 0, 3, 0x2f, 0x70),
+	PIN(235, 0, 1, 0x2f, 0x70),
+	PIN(236, 0, 2, 0x2f, 0x70),
+	PIN(237, 0, 6, 0x2f, 0x70),
+	PIN(238, 0, 5, 0x2f, 0x70),
+	PIN(239, 0, 19, 0x2f, 0x70),
+	PIN(240, 0, 18, 0x2f, 0x70),
+	PIN(241, 0, 16, 0x2f, 0x70),
+	PIN(242, 0, 17, 0x2f, 0x70),
+	PIN(243, 0, 15, 0x2f, 0x70),
+	PIN(244, 0, 12, 0x2f, 0x70),
+	PIN(245, 0, 9, 0x2f, 0x70),
+	PIN(246, 0, 8, 0x2f, 0x70),
+	PIN(247, 0, 7, 0x2f, 0x70),
+	PIN(248, 0, 4, 0x2f, 0x70),
+	PIN(249, 0, 20, 0x2f, 0x70),
+	PIN(250, 0, 11, 0x2f, 0x70),
+	PIN(251, 0, 2, 0x13, 0x80),
+	PIN(252, 0, 3, 0x13, 0x80),
+	PIN(253, 0, 4, 0x13, 0x80),
+	PIN(254, 0, 5, 0x13, 0x80),
+	PIN(255, 0, 6, 0x13, 0x80),
+	PIN(256, 0, 7, 0x13, 0x80),
+	PIN(257, 0, 8, 0x13, 0x80),
+	PIN(258, 0, 9, 0x13, 0x80),
+	PIN(259, 1, 9, 0x2e, 0xa0),
+	PIN(260, 1, 10, 0x2e, 0xa0),
+	PIN(261, 1, 11, 0x2e, 0xa0),
+	PIN(262, 1, 12, 0x2e, 0xa0),
+	PIN(263, 1, 13, 0x2e, 0xa0),
+	PIN(264, 1, 14, 0x2e, 0xa0),
+	PIN(265, 1, 15, 0x2e, 0xa0),
+	PIN(266, 1, 16, 0x2e, 0xa0),
+	PIN(267, 1, 2, 0x2f, 0x80),
+	PIN(268, 1, 3, 0x2f, 0x80),
+	PIN(269, 1, 0, 0x2f, 0x80),
+	PIN(270, 1, 1, 0x2f, 0x80),
+};
+
+#endif /* MT_GPIO_H */
diff --git a/plat/mediatek/mt8196/include/plat_macros.S b/plat/mediatek/mt8196/include/plat_macros.S
new file mode 100644
index 0000000..c646edd
--- /dev/null
+++ b/plat/mediatek/mt8196/include/plat_macros.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#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"
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+	/* ---------------------------------------------
+	 * The below macro prints out relevant GIC
+	 * registers whenever an unhandled exception
+	 * is taken in BL31.
+	 * Clobbers: x0 - x10, x26, x27, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/* TODO: leave implementation to GIC owner */
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/mediatek/mt8196/include/plat_private.h b/plat/mediatek/mt8196/include/plat_private.h
new file mode 100644
index 0000000..1ed1973
--- /dev/null
+++ b/plat/mediatek/mt8196/include/plat_private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_configure_mmu_el3(uintptr_t total_base,
+			    uintptr_t total_size,
+			    uintptr_t ro_start,
+			    uintptr_t ro_limit);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
new file mode 100644
index 0000000..6b6416a
--- /dev/null
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+
+#include <arch_def.h>
+
+#define PLAT_PRIMARY_CPU	(0x0)
+
+#define MT_GIC_BASE		(0x0C400000)
+#define MCUCFG_BASE		(0x0C000000)
+#define MCUCFG_REG_SIZE		(0x50000)
+#define IO_PHYS			(0x10000000)
+
+/* Aggregate of all devices for MMU mapping */
+#define MTK_DEV_RNG1_BASE	(IO_PHYS)
+#define MTK_DEV_RNG1_SIZE	(0x10000000)
+
+#define TOPCKGEN_BASE		(IO_PHYS)
+
+/*******************************************************************************
+ * AUDIO related constants
+ ******************************************************************************/
+#define AUDIO_BASE		(IO_PHYS + 0x0a110000)
+
+/*******************************************************************************
+ * APUSYS related constants
+ ******************************************************************************/
+#define APUSYS_BASE			(IO_PHYS + 0x09000000)
+#define APU_MD32_SYSCTRL		(IO_PHYS + 0x09001000)
+#define APU_MD32_WDT			(IO_PHYS + 0x09002000)
+#define APU_LOGTOP			(IO_PHYS + 0x09024000)
+#define APUSYS_CTRL_DAPC_RCX_BASE	(IO_PHYS + 0x09030000)
+#define APU_REVISER			(IO_PHYS + 0x0903C000)
+#define APU_RCX_UPRV_TCU		(IO_PHYS + 0x09060000)
+#define APU_RCX_EXTM_TCU		(IO_PHYS + 0x09061000)
+#define APU_CMU_TOP			(IO_PHYS + 0x09067000)
+#define APUSYS_CE_BASE			(IO_PHYS + 0x090B0000)
+#define APU_ARE_REG_BASE		(IO_PHYS + 0x090B0000)
+#define APU_RCX_VCORE_CONFIG		(IO_PHYS + 0x090E0000)
+#define APU_AO_CTRL			(IO_PHYS + 0x090F2000)
+#define APU_SEC_CON			(IO_PHYS + 0x090F5000)
+#define APUSYS_CTRL_DAPC_AO_BASE	(IO_PHYS + 0x090FC000)
+
+#define APU_MBOX0			(0x4C200000)
+#define APU_MD32_TCM			(0x4D000000)
+
+#define APU_MD32_TCM_SZ			(0x50000)
+#define APU_MBOX0_SZ			(0x100000)
+#define APU_INFRA_BASE			(0x1002C000)
+#define APU_INFRA_SZ			(0x1000)
+
+#define APU_RESERVE_MEMORY		(0x95000000)
+#define APU_SEC_INFO_OFFSET		(0x100000)
+#define APU_RESERVE_SIZE		(0x1400000)
+
+/*******************************************************************************
+ * SPM related constants
+ ******************************************************************************/
+#define SPM_BASE		(IO_PHYS + 0x0C004000)
+
+/*******************************************************************************
+ * GPIO related constants
+ ******************************************************************************/
+#define GPIO_BASE		(IO_PHYS + 0x0002D000)
+#define RGU_BASE		(IO_PHYS + 0x0C00B000)
+#define DRM_BASE		(IO_PHYS + 0x0000D000)
+#define IOCFG_RT_BASE		(IO_PHYS + 0x02000000)
+#define IOCFG_RM1_BASE		(IO_PHYS + 0x02020000)
+#define IOCFG_RM2_BASE		(IO_PHYS + 0x02040000)
+#define IOCFG_RB_BASE		(IO_PHYS + 0x02060000)
+#define IOCFG_BM1_BASE		(IO_PHYS + 0x02820000)
+#define IOCFG_BM2_BASE		(IO_PHYS + 0x02840000)
+#define IOCFG_BM3_BASE		(IO_PHYS + 0x02860000)
+#define IOCFG_LT_BASE		(IO_PHYS + 0x03000000)
+#define IOCFG_LM1_BASE		(IO_PHYS + 0x03020000)
+#define IOCFG_LM2_BASE		(IO_PHYS + 0x03040000)
+#define IOCFG_LB1_BASE		(IO_PHYS + 0x030f0000)
+#define IOCFG_LB2_BASE		(IO_PHYS + 0x03110000)
+#define IOCFG_TM1_BASE		(IO_PHYS + 0x03800000)
+#define IOCFG_TM2_BASE		(IO_PHYS + 0x03820000)
+#define IOCFG_TM3_BASE		(IO_PHYS + 0x03860000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE	(IO_PHYS + 0x06000000)
+#define UART_BAUDRATE	(115200)
+
+/*******************************************************************************
+ * Infra IOMMU related constants
+ ******************************************************************************/
+#define INFRACFG_AO_BASE	(IO_PHYS + 0x00001000)
+#define INFRACFG_AO_MEM_BASE	(IO_PHYS + 0x00404000)
+#define PERICFG_AO_BASE		(IO_PHYS + 0x06630000)
+#define PERICFG_AO_REG_SIZE	(0x1000)
+
+/*******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+/* Base MTK_platform compatible GIC memory map */
+#define BASE_GICD_BASE		(MT_GIC_BASE)
+#define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define MTK_GIC_REG_SIZE	0x400000
+
+/*******************************************************************************
+ * MM IOMMU & SMI related constants
+ ******************************************************************************/
+#define SMI_LARB_0_BASE		(IO_PHYS + 0x0c022000)
+#define SMI_LARB_1_BASE		(IO_PHYS + 0x0c023000)
+#define SMI_LARB_2_BASE		(IO_PHYS + 0x0c102000)
+#define SMI_LARB_3_BASE		(IO_PHYS + 0x0c103000)
+#define SMI_LARB_4_BASE		(IO_PHYS + 0x04013000)
+#define SMI_LARB_5_BASE		(IO_PHYS + 0x04f02000)
+#define SMI_LARB_6_BASE		(IO_PHYS + 0x04f03000)
+#define SMI_LARB_7_BASE		(IO_PHYS + 0x04e04000)
+#define SMI_LARB_9_BASE		(IO_PHYS + 0x05001000)
+#define SMI_LARB_10_BASE	(IO_PHYS + 0x05120000)
+#define SMI_LARB_11A_BASE	(IO_PHYS + 0x05230000)
+#define SMI_LARB_11B_BASE	(IO_PHYS + 0x05530000)
+#define SMI_LARB_11C_BASE	(IO_PHYS + 0x05630000)
+#define SMI_LARB_12_BASE	(IO_PHYS + 0x05340000)
+#define SMI_LARB_13_BASE	(IO_PHYS + 0x06001000)
+#define SMI_LARB_14_BASE	(IO_PHYS + 0x06002000)
+#define SMI_LARB_15_BASE	(IO_PHYS + 0x05140000)
+#define SMI_LARB_16A_BASE	(IO_PHYS + 0x06008000)
+#define SMI_LARB_16B_BASE	(IO_PHYS + 0x0600a000)
+#define SMI_LARB_17A_BASE	(IO_PHYS + 0x06009000)
+#define SMI_LARB_17B_BASE	(IO_PHYS + 0x0600b000)
+#define SMI_LARB_19_BASE	(IO_PHYS + 0x0a010000)
+#define SMI_LARB_21_BASE	(IO_PHYS + 0x0802e000)
+#define SMI_LARB_23_BASE	(IO_PHYS + 0x0800d000)
+#define SMI_LARB_27_BASE	(IO_PHYS + 0x07201000)
+#define SMI_LARB_28_BASE	(IO_PHYS + 0x00000000)
+#define SMI_LARB_REG_RNG_SIZE	(0x1000)
+
+/*******************************************************************************
+ * APMIXEDSYS related constants
+ ******************************************************************************/
+#define APMIXEDSYS		(IO_PHYS + 0x0000C000)
+
+/*******************************************************************************
+ * VPPSYS related constants
+ ******************************************************************************/
+#define VPPSYS0_BASE		(IO_PHYS + 0x04000000)
+#define VPPSYS1_BASE		(IO_PHYS + 0x04f00000)
+
+/*******************************************************************************
+ * VDOSYS related constants
+ ******************************************************************************/
+#define VDOSYS0_BASE		(IO_PHYS + 0x0C01D000)
+#define VDOSYS1_BASE		(IO_PHYS + 0x0C100000)
+
+/*******************************************************************************
+ * DP related constants
+ ******************************************************************************/
+#define EDP_SEC_BASE		(IO_PHYS + 0x2EC50000)
+#define DP_SEC_BASE		(IO_PHYS + 0x2EC10000)
+#define EDP_SEC_SIZE		(0x1000)
+#define DP_SEC_SIZE		(0x1000)
+
+/*******************************************************************************
+ * EMI MPU related constants
+ *******************************************************************************/
+#define EMI_MPU_BASE			(IO_PHYS + 0x00428000)
+#define SUB_EMI_MPU_BASE		(IO_PHYS + 0x00528000)
+#define EMI_SLB_BASE			(IO_PHYS + 0x0042e000)
+#define SUB_EMI_SLB_BASE		(IO_PHYS + 0x0052e000)
+#define CHN0_EMI_APB_BASE		(IO_PHYS + 0x00201000)
+#define CHN1_EMI_APB_BASE		(IO_PHYS + 0x00205000)
+#define CHN2_EMI_APB_BASE		(IO_PHYS + 0x00209000)
+#define CHN3_EMI_APB_BASE		(IO_PHYS + 0x0020D000)
+#define EMI_APB_BASE			(IO_PHYS + 0x00429000)
+#define INFRA_EMI_DEBUG_CFG_BASE	(IO_PHYS + 0x00425000)
+#define NEMI_SMPU_BASE			(IO_PHYS + 0x0042f000)
+#define SEMI_SMPU_BASE			(IO_PHYS + 0x0052f000)
+#define SUB_EMI_APB_BASE		(IO_PHYS + 0x00529000)
+#define SUB_INFRA_EMI_DEBUG_CFG_BASE	(IO_PHYS + 0x00525000)
+#define SUB_INFRACFG_AO_MEM_BASE	(IO_PHYS + 0x00504000)
+
+/*******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_HZ	(13000000)
+#define SYS_COUNTER_FREQ_IN_MHZ	(13)
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+#define PLATFORM_STACK_SIZE		(0x800)
+#define SOC_CHIP_ID			U(0x8196)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define TZRAM_BASE			(0x94600000)
+#define TZRAM_SIZE			(0x00200000)
+
+/*******************************************************************************
+ * 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)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 39)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 39)
+#define MAX_XLAT_TABLES			(128)
+#define MAX_MMAP_REGIONS		(512)
+
+/*******************************************************************************
+ * CPU PM definitions
+ *******************************************************************************/
+#define PLAT_CPU_PM_B_BUCK_ISO_ID	(6)
+#define PLAT_CPU_PM_ILDO_ID		(6)
+#define CPU_IDLE_SRAM_BASE		(0x11B000)
+#define CPU_IDLE_SRAM_SIZE		(0x1000)
+
+/*******************************************************************************
+ * SYSTIMER related definitions
+ ******************************************************************************/
+#define SYSTIMER_BASE		(0x1C400000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
new file mode 100644
index 0000000..0239a3f
--- /dev/null
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Separate text code and read only data
+SEPARATE_CODE_AND_RODATA := 1
+
+# ARMv8.2 and above need enable HW assist coherence
+HW_ASSISTED_COHERENCY := 1
+
+# No need coherency memory because of HW assistency
+USE_COHERENT_MEM := 0
+
+# GIC600
+GICV3_SUPPORT_GIC600 := 1
+
+#
+# MTK options
+#
+PLAT_EXTRA_RODATA_INCLUDES := 1
+USE_PMIC_WRAP_INIT_V2 := 1
+
+# Configs for A78 and A55
+CTX_INCLUDE_AARCH32_REGS := 0
+
+CONFIG_ARCH_ARM_V9 := y
+CONFIG_MTK_APUSYS_CE_SUPPORT := y
+CONFIG_MTK_APUSYS_EMI_SUPPORT := n
+CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT := y
+CONFIG_MTK_APUSYS_SEC_CTRL := y
+CONFIG_MTK_APUSYS_SETUP_CE := y
+CONFIG_MTK_MCUSYS := y
+MCUSYS_VERSION := v1
+CONFIG_MTK_PM_SUPPORT := y
+CONFIG_MTK_PM_ARCH := 9_0
+CONFIG_MTK_CPU_PM_SUPPORT := y
+CONFIG_MTK_CPU_PM_ARCH := 5_4
+CONFIG_MTK_SMP_EN := n
+CONFIG_MTK_CPU_SUSPEND_EN := y
+CONFIG_MTK_SPM_VERSION := mt8196
+CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
+CONFIG_MTK_TINYSYS_VCP := y
+CPU_PM_TINYSYS_SUPPORT := y
+MTK_PUBEVENT_ENABLE := y
+
+ENABLE_FEAT_AMU := 1
+ENABLE_FEAT_ECV := 1
+ENABLE_FEAT_FGT := 1
+ENABLE_FEAT_HCX := 1
+ENABLE_SVE_FOR_SWD := 1
diff --git a/plat/mediatek/mt8196/plat_mmap.c b/plat/mediatek/mt8196/plat_mmap.c
new file mode 100644
index 0000000..d32f4ee
--- /dev/null
+++ b/plat/mediatek/mt8196/plat_mmap.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <platform_def.h>
+
+#include <mtk_mmap_pool.h>
+
+static const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(MT_GIC_BASE, MTK_GIC_REG_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(CPU_IDLE_SRAM_BASE, CPU_IDLE_SRAM_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DP_SEC_BASE, DP_SEC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(EDP_SEC_BASE, EDP_SEC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(APU_MBOX0, APU_MBOX0_SZ,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	{ 0 }
+};
+DECLARE_MTK_MMAP_REGIONS(plat_mmap);
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
new file mode 100644
index 0000000..8ae8e28
--- /dev/null
+++ b/plat/mediatek/mt8196/platform.mk
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
+MTK_SOC := ${PLAT}
+ARM_ARCH_MAJOR := 9
+
+include plat/mediatek/build_helpers/mtk_build_helpers.mk
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES := -I${MTK_PLAT}/common \
+                 -I${MTK_PLAT}/drivers/gpio/ \
+		 -I${MTK_PLAT}/include \
+		 -I${MTK_PLAT}/include/${ARCH_VERSION} \
+		 -I${MTK_PLAT} \
+		 -I${MTK_PLAT_SOC}/drivers/gpio/ \
+		 -I${MTK_PLAT_SOC}/include \
+		 -Idrivers/arm/gic \
+
+MODULES-y += $(MTK_PLAT)/common
+MODULES-y += $(MTK_PLAT)/lib/mtk_init
+MODULES-y += $(MTK_PLAT)/lib/pm
+MODULES-y += $(MTK_PLAT)/drivers/apusys
+MODULES-y += $(MTK_PLAT)/drivers/dp
+MODULES-y += $(MTK_PLAT)/drivers/emi
+MODULES-y += $(MTK_PLAT)/drivers/mcusys
+MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/drivers/vcp
+MODULES-y += $(MTK_PLAT)/helpers
+MODULES-y += $(MTK_PLAT)/topology
+
+ifneq ($(MTKLIB_PATH),)
+LDFLAGS += -L $(dir $(MTKLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(MTKLIB_PATH)))
+endif
+
+PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
+			  drivers/ti/uart/aarch64/16550_console.S \
+			  lib/bl_aux_params/bl_aux_params.c
+
+BL31_SOURCES += drivers/delay_timer/delay_timer.c \
+		drivers/delay_timer/generic_delay_timer.c \
+		drivers/gpio/gpio.c \
+		lib/cpus/aarch64/cortex_a720.S	\
+		lib/cpus/aarch64/cortex_x4.S	\
+		lib/cpus/aarch64/cortex_x925.S \
+		${GICV3_SOURCES} \
+		${XLAT_TABLES_LIB_SRCS} \
+		plat/common/plat_gicv3.c \
+		plat/common/plat_psci_common.c \
+		plat/common/aarch64/crash_console_helpers.S \
+		${MTK_PLAT}/common/mtk_plat_common.c \
+		${MTK_PLAT}/common/params_setup.c \
+                ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+                $(MTK_PLAT)/$(MTK_SOC)/drivers/gpio/mtgpio.c \
+		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c
+
+include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+
+include lib/coreboot/coreboot.mk
diff --git a/plat/mediatek/topology/armv9/topology.c b/plat/mediatek/topology/armv9/topology.c
new file mode 100644
index 0000000..d6ecc83
--- /dev/null
+++ b/plat/mediatek/topology/armv9/topology.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+
+#pragma weak plat_get_power_domain_tree_desc
+
+static const unsigned char mtk_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* Number of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return mtk_power_domain_tree_desc;
+}
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
index 1959aac..d73756c 100644
--- a/plat/nuvoton/npcm845x/platform.mk
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -318,9 +318,8 @@
 endif
 
 # Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c \
-		lib/extensions/pauth/pauth_helpers.S
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif
 
 ifeq (${SPD},spmd)
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 000e419..0233398 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -130,13 +130,13 @@
     $(BUILD_PLAT)/bl2/nxp_rotpk.o: $(ROTPK_HASH)
 
     certificates: $(ROT_KEY)
-    $(ROT_KEY): | $(BUILD_PLAT)
+    $(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-    $(ROTPK_HASH): $(ROT_KEY)
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/nxp/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
index 1a4c495..cb16658 100644
--- a/plat/nxp/s32/s32g274ardb2/include/platform_def.h
+++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
@@ -48,7 +48,7 @@
 /* We'll be doing a 1:1 mapping anyway */
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 36)
 
-#define MAX_MMAP_REGIONS		U(8)
+#define MAX_MMAP_REGIONS		U(18)
 #define MAX_XLAT_TABLES			U(32)
 
 /* Console settings */
diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h
new file mode 100644
index 0000000..0f0c804
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32CC_BL_COMMON_H
+#define S32CC_BL_COMMON_H
+
+int s32cc_bl_mmu_setup(void);
+
+#endif /* S32CC_BL_COMMON_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index 4645f01..0929f9d 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -4,15 +4,21 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
+
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <plat_console.h>
 #include <s32cc-clk-drv.h>
+
 #include <plat_io_storage.h>
+#include <s32cc-bl-common.h>
 #include <s32cc-ncore.h>
 
+#define SIUL20_BASE		UL(0x4009C000)
 #define SIUL2_PC09_MSCR		UL(0x4009C2E4)
 #define SIUL2_PC10_MSCR		UL(0x4009C2E8)
 #define SIUL2_PC10_LIN0_IMCR	UL(0x4009CA40)
@@ -38,6 +44,20 @@
 
 void bl2_platform_setup(void)
 {
+	int ret;
+
+	ret = mmap_add_dynamic_region(S32G_FIP_BASE, S32G_FIP_BASE,
+				      S32G_FIP_SIZE,
+				      MT_MEMORY | MT_RW | MT_SECURE);
+	if (ret != 0) {
+		panic();
+	}
+}
+
+static int s32g_mmap_siul2(void)
+{
+	return mmap_add_dynamic_region(SIUL20_BASE, SIUL20_BASE, PAGE_SIZE,
+				       MT_DEVICE | MT_RW | MT_SECURE);
 }
 
 static void linflex_config_pinctrl(void)
@@ -55,14 +75,6 @@
 {
 	int ret;
 
-	ret = s32cc_init_early_clks();
-	if (ret != 0) {
-		panic();
-	}
-
-	linflex_config_pinctrl();
-	console_s32g2_register();
-
 	/* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
 	 * we have manually set during early BL2 boot.
 	 */
@@ -71,6 +83,29 @@
 	ncore_init();
 	ncore_caiu_online(A53_CLUSTER0_CAIU);
 
+	ret = s32cc_init_core_clocks();
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = s32cc_bl_mmu_setup();
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = s32cc_init_early_clks();
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = s32g_mmap_siul2();
+	if (ret != 0) {
+		panic();
+	}
+
+	linflex_config_pinctrl();
+	console_s32g2_register();
+
 	plat_s32g2_io_setup();
 }
 
@@ -78,3 +113,26 @@
 {
 }
 
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+	const struct bl_mem_params_node *desc = get_bl_mem_params_node(image_id);
+	const struct image_info *img_info;
+	size_t size;
+
+	if (desc == NULL) {
+		return -EINVAL;
+	}
+
+	img_info = &desc->image_info;
+
+	if ((img_info == NULL) || (img_info->image_max_size == 0U)) {
+		return -EINVAL;
+	}
+
+	size = page_align(img_info->image_max_size, UP);
+
+	return mmap_add_dynamic_region(img_info->image_base,
+				       img_info->image_base,
+				       size,
+				       MT_MEMORY | MT_RW | MT_SECURE);
+}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
index 03bf35c..22c66b0 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
@@ -4,10 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/debug.h>
 #include <drivers/arm/gicv3.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <plat_console.h>
 
+#include <s32cc-bl-common.h>
+
 static entry_point_info_t bl33_image_ep_info;
 
 static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr);
@@ -25,8 +29,6 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	console_s32g2_register();
-
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	bl33_image_ep_info.pc = BL33_BASE;
 	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
@@ -35,6 +37,14 @@
 
 void bl31_plat_arch_setup(void)
 {
+	int ret;
+
+	ret = s32cc_bl_mmu_setup();
+	if (ret != 0) {
+		panic();
+	}
+
+	console_s32g2_register();
 }
 
 struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
@@ -42,6 +52,31 @@
 	return &bl33_image_ep_info;
 }
 
+static int mmap_gic(const gicv3_driver_data_t *gic_data)
+{
+	size_t gicr_size;
+	int ret;
+
+	ret = mmap_add_dynamic_region(gic_data->gicd_base,
+				      gic_data->gicd_base,
+				      PAGE_SIZE_64KB,
+				      MT_DEVICE | MT_RW | MT_SECURE);
+	if (ret != 0) {
+		return ret;
+	}
+
+	gicr_size = gicv3_redist_size(0x0U);
+	ret = mmap_add_dynamic_region(gic_data->gicr_base,
+				      gic_data->gicr_base,
+				      gicr_size * gic_data->rdistif_num,
+				      MT_DEVICE | MT_RW | MT_SECURE);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
 void bl31_platform_setup(void)
 {
 	static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
@@ -52,8 +87,13 @@
 		.rdistif_base_addrs = rdistif_base_addrs,
 		.mpidr_to_core_pos = s32g2_mpidr_to_core_pos,
 	};
-
 	unsigned int pos = plat_my_core_pos();
+	int ret;
+
+	ret = mmap_gic(&plat_gic_data);
+	if (ret != 0) {
+		panic();
+	}
 
 	gicv3_driver_init(&plat_gic_data);
 	gicv3_distif_init();
diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c
index 542fa7b..e65e439 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_console.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_console.c
@@ -5,6 +5,7 @@
  */
 
 #include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <linflex.h>
 #include <plat_console.h>
 #include <platform_def.h>
@@ -17,6 +18,12 @@
 	};
 	int ret;
 
+	ret = mmap_add_dynamic_region(UART_BASE, UART_BASE, PAGE_SIZE,
+				      MT_DEVICE | MT_RW | MT_SECURE);
+	if (ret != 0) {
+		panic();
+	}
+
 	ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ,
 				       UART_BAUDRATE, &s32g2_console);
 	if (ret == 0) {
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 7d6e960..4ec7cd0 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -38,6 +38,9 @@
 ERRATA_SPECULATIVE_AT := 1
 ERRATA_S32_051700 := 1
 
+PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
 # Selecting Drivers for SoC
 $(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
 $(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM))
@@ -47,6 +50,8 @@
 BL_COMMON_SOURCES += \
 	${PLAT_S32G274ARDB2}/plat_console.c \
 	${PLAT_S32G274ARDB2}/plat_helpers.S \
+	${PLAT_S32G274ARDB2}/s32cc_bl_common.c \
+	${XLAT_TABLES_LIB_SRCS} \
 
 BL2_SOURCES += \
 	${BL_COMMON_SOURCES} \
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c
new file mode 100644
index 0000000..4664438
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <s32cc-bl-common.h>
+
+int s32cc_bl_mmu_setup(void)
+{
+	const unsigned long code_start = BL_CODE_BASE;
+	const unsigned long rw_start = BL_CODE_END;
+	unsigned long code_size;
+	unsigned long rw_size;
+
+	if (code_start > BL_CODE_END) {
+		return -EINVAL;
+	}
+
+	if (rw_start > BL_END) {
+		return -EINVAL;
+	}
+
+	code_size = BL_CODE_END - code_start;
+	rw_size = BL_END - rw_start;
+
+	mmap_add_region(code_start, code_start, code_size,
+			MT_RO | MT_MEMORY | MT_SECURE);
+	mmap_add_region(rw_start, rw_start, rw_size,
+			MT_RW | MT_MEMORY | MT_SECURE);
+
+	init_xlat_tables();
+	enable_mmu_el3(0);
+
+	return 0;
+}
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index c303ced..c1f14dc 100644
--- a/plat/nxp/soc-lx2160a/ddr_fip.mk
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -1,5 +1,6 @@
 #
 # Copyright 2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -67,7 +68,7 @@
 
 # Variables for use with Certificate Generation Tool
 CRTTOOLPATH	?=	tools/cert_create
-CRTTOOL		?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
+CRTTOOL		?=	${CRTTOOLPATH}/cert_create$(.exe)
 
 ifneq (${GENERATE_COT},0)
 ddr_certificates: ${DDR_CRT_DEPS} ${CRTTOOL}
@@ -82,7 +83,7 @@
 
 # Variables for use with Firmware Image Package
 FIPTOOLPATH	?=	tools/fiptool
-FIPTOOL		?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
+FIPTOOL		?=	${FIPTOOLPATH}/fiptool$(.exe)
 
 ${BUILD_PLAT}/${DDR_FIP_NAME}: ${DDR_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_DDR_FIP_CMD})
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index ed95bc6..5e3a61a 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -8,6 +8,7 @@
 include common/fdt_wrappers.mk
 
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/		\
+				-I${PLAT_QEMU_COMMON_PATH}/		\
 				-I${PLAT_QEMU_COMMON_PATH}/include	\
 				-I${PLAT_QEMU_PATH}/include		\
 				-Iinclude/common/tbbr
@@ -65,7 +66,8 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
 				common/desc_image_load.c		\
-				common/fdt_fixup.c
+				common/fdt_fixup.c			\
+				${FDT_WRAPPERS_SOURCES}
 
 BL31_SOURCES		+=	${QEMU_CPU_LIBS}				\
 				lib/semihosting/semihosting.c			\
@@ -147,9 +149,8 @@
 endif
 
 # Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
-CTX_INCLUDE_PAUTH_REGS	:=	1
 endif
 
 endif
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index c96e4b9..71f9cf7 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -22,9 +22,6 @@
 #include <lib/transfer_list.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
-#if ENABLE_RME
-#include <qemu_pas_def.h>
-#endif
 
 #include "qemu_private.h"
 
@@ -84,8 +81,9 @@
 #endif
 	int ret;
 	void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
+	void *dst = plat_qemu_dt_runtime_address();
 
-	ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
+	ret = fdt_open_into(fdt, dst, PLAT_QEMU_DT_MAX_SIZE);
 	if (ret < 0) {
 		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
 		return;
@@ -150,54 +148,6 @@
 #endif
 }
 
-#if ENABLE_RME
-static void bl2_plat_gpt_setup(void)
-{
-	/*
-	 * The GPT library might modify the gpt regions structure to optimize
-	 * the layout, so the array cannot be constant.
-	 */
-	pas_region_t pas_regions[] = {
-		QEMU_PAS_ROOT,
-		QEMU_PAS_SECURE,
-		QEMU_PAS_GPTS,
-		QEMU_PAS_NS0,
-		QEMU_PAS_REALM,
-		QEMU_PAS_NS1,
-	};
-
-	/*
-	 * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
-	 * covering 1GB (currently the only supported option), then covering
-	 * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
-	 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
-	 */
-	if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE,
-			       PLAT_QEMU_L0_GPT_SIZE +
-			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
-		ERROR("gpt_init_l0_tables() failed!\n");
-		panic();
-	}
-
-	/* Carve out defined PAS ranges. */
-	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
-				   PLAT_QEMU_L1_GPT_BASE,
-				   PLAT_QEMU_L1_GPT_SIZE,
-				   pas_regions,
-				   (unsigned int)(sizeof(pas_regions) /
-						  sizeof(pas_region_t))) < 0) {
-		ERROR("gpt_init_pas_l1_tables() failed!\n");
-		panic();
-	}
-
-	INFO("Enabling Granule Protection Checks\n");
-	if (gpt_enable() < 0) {
-		ERROR("gpt_enable() failed!\n");
-		panic();
-	}
-}
-#endif
-
 void bl2_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
@@ -220,9 +170,6 @@
 	/* BL2 runs in EL3 when RME enabled. */
 	assert(is_feat_rme_present());
 	enable_mmu_el3(0);
-
-	/* Initialise and enable granule protection after MMU. */
-	bl2_plat_gpt_setup();
 #else /* ENABLE_RME */
 
 #ifdef __aarch64__
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 0a70cc2..81ce102 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -11,6 +11,16 @@
 #include <lib/gpt_rme/gpt_rme.h>
 #include <lib/transfer_list.h>
 #include <plat/common/platform.h>
+#if ENABLE_RME
+#ifdef PLAT_qemu
+#include <qemu_pas_def.h>
+#elif PLAT_qemu_sbsa
+#include <qemu_sbsa_pas_def.h>
+#endif /* PLAT_qemu */
+#endif /* ENABLE_RME */
+#ifdef PLAT_qemu_sbsa
+#include <sbsa_platform.h>
+#endif
 
 #include "qemu_private.h"
 
@@ -58,12 +68,15 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	bool is64 = false;
+	uint64_t hval;
+
 	/* Initialize the console to provide early debug support */
 	qemu_console_init();
 
 /* Platform names have to be lowercase. */
 #ifdef PLAT_qemu_sbsa
-	sip_svc_init();
+	sbsa_platform_init();
 #endif
 
 	/*
@@ -82,6 +95,11 @@
 	 * They are stored in Secure RAM, in BL2's address space.
 	 */
 	while (bl_params) {
+#ifdef __aarch64__
+		if (bl_params->image_id == BL31_IMAGE_ID &&
+		    GET_RW(bl_params->ep_info->spsr) == MODE_RW_64)
+			is64 = true;
+#endif
 		if (bl_params->image_id == BL32_IMAGE_ID)
 			bl32_image_ep_info = *bl_params->ep_info;
 
@@ -103,12 +121,114 @@
 		panic();
 #endif
 
-	if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
-				      REGISTER_CONVENTION_VERSION_MASK) &&
-	    transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
-		bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+	if (!TRANSFER_LIST ||
+	    !transfer_list_check_header((void *)arg3))
+		return;
+
+	if (is64)
+		hval = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+	else
+		hval = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+
+	if (arg1 != hval)
+		return;
+
+	bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+}
+
+#if ENABLE_RME
+#if PLAT_qemu
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	QEMU_PAS_ROOT,
+	QEMU_PAS_SECURE,
+	QEMU_PAS_GPTS,
+	QEMU_PAS_NS0,
+	QEMU_PAS_REALM,
+	QEMU_PAS_NS1,
+};
+
+static inline void bl31_adjust_pas_regions(void) {}
+#elif PLAT_qemu_sbsa
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	QEMU_PAS_ROOT,
+	QEMU_PAS_SECURE,
+	QEMU_PAS_GPTS,
+	QEMU_PAS_REALM,
+	QEMU_PAS_NS0,
+};
+
+static void bl31_adjust_pas_regions(void)
+{
+	uint64_t base_addr = 0, total_size = 0;
+	struct platform_memory_data data;
+	uint32_t node;
+
+	/*
+	 * The amount of memory supported by the SBSA platform is dynamic
+	 * and dependent on user input.  Since the configuration of the GPT
+	 * needs to reflect the system memory, QEMU_PAS_NS0 needs to be set
+	 * based on the information found in the device tree.
+	 */
+
+	for (node = 0; node < sbsa_platform_num_memnodes(); node++) {
+		data = sbsa_platform_memory_node(node);
+
+		if (data.nodeid == 0) {
+			base_addr = data.addr_base;
+		}
+
+		total_size += data.addr_size;
+	}
+
+	 /* Index '4' correspond to QEMU_PAS_NS0, see pas_regions[] above */
+	pas_regions[4].base_pa = base_addr;
+	pas_regions[4].size = total_size;
+}
+#endif /* PLAT_qemu */
+
+static void bl31_plat_gpt_setup(void)
+{
+	/*
+	 * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
+	 * covering 1GB (currently the only supported option), then covering
+	 * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
+	 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
+	 */
+	if (gpt_init_l0_tables(PLATFORM_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
+			       PLAT_QEMU_L0_GPT_SIZE +
+			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
+		ERROR("gpt_init_l0_tables() failed!\n");
+		panic();
+	}
+
+	bl31_adjust_pas_regions();
+
+	/* Carve out defined PAS ranges. */
+	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
+				   PLAT_QEMU_L1_GPT_BASE,
+				   PLAT_QEMU_L1_GPT_SIZE,
+				   pas_regions,
+				   (unsigned int)(sizeof(pas_regions) /
+						  sizeof(pas_region_t))) < 0) {
+		ERROR("gpt_init_pas_l1_tables() failed!\n");
+		panic();
+	}
+
+	INFO("Enabling Granule Protection Checks\n");
+	if (gpt_enable() < 0) {
+		ERROR("gpt_enable() failed!\n");
+		panic();
 	}
 }
+#endif
 
 void bl31_plat_arch_setup(void)
 {
@@ -131,6 +251,9 @@
 	enable_mmu_el3(0);
 
 #if ENABLE_RME
+	/* Initialise and enable granule protection after MMU. */
+	bl31_plat_gpt_setup();
+
 	/*
 	 * Initialise Granule Protection library and enable GPC for the primary
 	 * processor. The tables have already been initialized by a previous BL
@@ -202,10 +325,12 @@
 #if TRANSFER_LIST
 	if (bl31_tl) {
 		/*
-		 * update the TL from S to NS memory before jump to BL33
+		 * Relocate the TL from S to NS memory before EL3 exit
 		 * to reflect all changes in TL done by BL32
 		 */
-		memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
+		if (!transfer_list_relocate(bl31_tl, (void *)FW_NS_HANDOFF_BASE,
+					    bl31_tl->max_size))
+			ERROR("Relocate TL to NS memory failed\n");
 	}
 #endif
 
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 068c69c..5dc39a1 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -16,6 +16,9 @@
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
 #endif
+#ifdef PLAT_qemu_sbsa
+#include <sbsa_platform.h>
+#endif
 
 #include <plat/common/platform.h>
 #include "qemu_private.h"
@@ -178,7 +181,7 @@
  */
 #define PLAT_SPMC_SHMEM_DATASTORE_SIZE 64 * 1024
 
-uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
+uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE] __aligned(2 * sizeof(long));
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
 {
@@ -198,16 +201,17 @@
 }
 #endif
 
-#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
-/*
- * A dummy implementation of the platform handler for Group0 secure interrupt.
- */
+#if defined(SPD_spmd)
 int plat_spmd_handle_group0_interrupt(uint32_t intid)
 {
+	/*
+	 * Currently, there are no sources of Group0 secure interrupt
+	 * enabled for QEMU.
+	 */
 	(void)intid;
 	return -1;
 }
-#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
+#endif /*defined(SPD_spmd)*/
 
 #if ENABLE_RME
 /*
@@ -223,12 +227,59 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
+#ifdef PLAT_qemu
+static uint32_t plat_get_num_memnodes(void)
+{
+	return 1;
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+	(void) index;
+	bank_ptr->base = NS_DRAM0_BASE;
+	bank_ptr->size = NS_DRAM0_SIZE;
+}
+#elif PLAT_qemu_sbsa
+static uint32_t plat_get_num_memnodes(void)
+{
+	return sbsa_platform_num_memnodes();
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+	struct platform_memory_data data = {0, 0, 0};
+
+	if (index < sbsa_platform_num_memnodes()) {
+		data = sbsa_platform_memory_node(index);
+	}
+
+	bank_ptr->base = data.addr_base;
+	bank_ptr->size = data.addr_size;
+}
+#endif /* PLAT_qemu */
+
+/*
+ * Calculate checksum of 64-bit words @buffer, of @size bytes
+ */
+static uint64_t checksum_calc(uint64_t *buffer, size_t size)
+{
+	uint64_t sum = 0UL;
+
+	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
+	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
+
+	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
+		sum += buffer[i];
+	}
+
+	return sum;
+}
+
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
+	int i, last;
 	uint64_t checksum;
-	uintptr_t base;
-	uint64_t size;
-	size_t num_banks = 1;
+	size_t num_banks = plat_get_num_memnodes();
 	size_t num_consoles = 1;
 	struct ns_dram_bank *bank_ptr;
 	struct console_info *console_ptr;
@@ -299,11 +350,30 @@
 	/* Calculate checksum of plat_dram structure */
 	checksum = num_banks + (uint64_t)bank_ptr;
 
-	base = NS_DRAM0_BASE;
-	size = NS_DRAM0_SIZE;
-	bank_ptr[0].base = base;
-	bank_ptr[0].size = size;
-	checksum += base + size;
+	/*
+	 * In the TF-A, NUMA nodes (if present) are stored in descending
+	 * order, i.e:
+	 *
+	 * INFO:    RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+	 * INFO:    RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+	 *
+	 * The RMM expects the memory banks to be presented in ascending order:
+	 *
+	 * INFO:    RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+	 * INFO:    RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+	 *
+	 * As such, go through the NUMA nodes one by one and fill out
+	 * @bank_ptr[] starting from the end.  When NUMA nodes are not present
+	 * there is only one memory bank and none of the above matters.
+	 */
+	last = num_banks - 1;
+	for (i = 0; i < num_banks; i++) {
+		plat_get_memory_node(i, &bank_ptr[last]);
+		last--;
+	}
+
+	checksum += checksum_calc((uint64_t *)bank_ptr,
+				  num_banks * sizeof(*bank_ptr));
 
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
@@ -322,8 +392,8 @@
 	strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
 
 	/* Update checksum */
-	checksum += console_ptr[0].base + console_ptr[0].map_pages +
-		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+	checksum += checksum_calc((uint64_t *)console_ptr,
+				  num_consoles * sizeof(*console_ptr));
 
 	/* Checksum must be 0 */
 	manifest->plat_console.checksum = ~checksum + 1UL;
@@ -331,3 +401,25 @@
 	return 0;
 }
 #endif  /* ENABLE_RME */
+
+/**
+ * plat_qemu_dt_runtime_address() - Get the final DT location in RAM
+ *
+ * When support is enabled on SBSA, the device tree is relocated from its
+ * original place at the beginning of the NS RAM to after the RMM.  This
+ * function returns the address of the final location in RAM of the device
+ * tree.  See function update_dt() in qemu_bl2_setup.c
+ *
+ * Return: The address of the final location in RAM of the device tree
+ */
+#if (ENABLE_RME && PLAT_qemu_sbsa)
+void *plat_qemu_dt_runtime_address(void)
+{
+	return (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
+}
+#else
+void *plat_qemu_dt_runtime_address(void)
+{
+	return (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
+}
+#endif /* (ENABLE_RME && PLAT_qemu_sbsa) */
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 25b14e2..046cb78 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -16,11 +16,9 @@
 			    uintptr_t load_addr);
 unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
 const mmap_region_t *plat_qemu_get_mmap(void);
+void *plat_qemu_dt_runtime_address(void);
 
 void qemu_console_init(void);
-#ifdef PLAT_qemu_sbsa
-void sip_svc_init(void);
-#endif
 
 void plat_qemu_gic_init(void);
 void qemu_pwr_gic_on_finish(void);
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index f78be90..0c85b1e 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -150,7 +150,7 @@
  * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
  * current BL3-1 debug size plus a little space for growth.
  */
-#define BL31_BASE			(BL31_LIMIT - 0x60000)
+#define BL31_BASE			(BL31_LIMIT - 0x70000)
 #define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE - FW_HANDOFF_SIZE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
 
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
index bcbea21..30934f0 100644
--- a/plat/qemu/qemu/include/qemu_pas_def.h
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -102,6 +102,9 @@
 							       QEMU_PAS_RMM_SHARED_SIZE, \
 							       GPT_GPI_REALM)
 
+/* Cover 1TB with L0GTP */
+#define PLATFORM_GPCCR_PPS		GPCCR_PPS_1TB
+
 /* GPT Configuration options */
 #define PLATFORM_L0GPTSZ		GPCCR_L0GPTSZ_30BITS
 
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index cf1b3a8..70e9faf 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -78,11 +78,11 @@
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY): | $(BUILD_PLAT)
+    $(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-    $(ROTPK_HASH): $(ROT_KEY)
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
@@ -115,8 +115,7 @@
     include drivers/auth/mbedtls/mbedtls_crypto.mk
 endif
 
-BL2_SOURCES		+=	${FDT_WRAPPERS_SOURCES}					\
-				common/uuid.c
+BL2_SOURCES		+=	common/uuid.c
 
 ifeq ($(add-lib-optee),yes)
 BL2_SOURCES		+=	lib/optee/optee_utils.c
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 76a4da1..54a4156 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -65,6 +65,14 @@
 
 	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
 
+	dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
+
+#if TRANSFER_LIST
+	if (!plat_handoff_mboot((void *)event_log_base, event_log_cur_size,
+				(void *)(uintptr_t)FW_HANDOFF_BASE))
+		return;
+#endif
+
 	rc = qemu_set_nt_fw_info(
 #ifdef SPD_opteed
 			    (uintptr_t)event_log_base,
@@ -101,7 +109,6 @@
 	}
 #endif /* defined(SPD_tspd) || defined(SPD_spmd) */
 
-	dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
 }
 
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index d230095..06e8abf 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -66,6 +66,9 @@
  */
 #define PLAT_MAX_MEM_NODES	128
 
+/* Where QEMU starts the NS RAM */
+#define PLAT_QEMU_DRAM0_BASE	0x10000000000ULL
+
 /*
  * Partition memory into secure ROM, non-secure DRAM, secure "SRAM",
  * and secure DRAM.
@@ -73,7 +76,12 @@
 #define SEC_ROM_BASE			0x00000000
 #define SEC_ROM_SIZE			0x00020000
 
-#define NS_DRAM0_BASE			0x10000000000ULL
+/*
+ * When the RME extension is enabled, the base of the NS RAM is shifted after
+ * RMM.
+ */
+#define NS_DRAM0_BASE			(PLAT_QEMU_DRAM0_BASE + \
+					NS_DRAM0_BASE_OFFSET)
 #define NS_DRAM0_SIZE			0x00020000000
 
 #define SEC_SRAM_BASE			0x20000000
@@ -121,7 +129,8 @@
 #define BL1_RO_BASE			SEC_ROM_BASE
 #define BL1_RO_LIMIT			(SEC_ROM_BASE + SEC_ROM_SIZE)
 #define BL1_RW_BASE			(BL1_RW_LIMIT - BL1_SIZE)
-#define BL1_RW_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
+#define BL1_RW_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE - \
+					 RME_GPT_DRAM_SIZE)
 
 /*
  * BL2 specific defines.
@@ -139,7 +148,7 @@
  * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
  * current BL3-1 debug size plus a little space for growth.
  */
-#define BL31_SIZE			0x300000
+#define BL31_SIZE			0x400000
 #define BL31_BASE			(BL31_LIMIT - BL31_SIZE)
 #define BL31_LIMIT			(BL1_RW_BASE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
@@ -154,8 +163,8 @@
 #define BL32_SRAM_LIMIT			BL2_BASE
 
 #define BL32_MEM_BASE			BL_RAM_BASE
-#define BL32_MEM_SIZE			(BL_RAM_SIZE - BL1_SIZE - \
-					BL2_SIZE - BL31_SIZE)
+#define BL32_MEM_SIZE			(BL_RAM_SIZE - RME_GPT_DRAM_SIZE - \
+					BL1_SIZE - BL2_SIZE - BL31_SIZE)
 #define BL32_BASE			BL32_SRAM_BASE
 #define BL32_LIMIT			BL32_SRAM_LIMIT
 
@@ -167,6 +176,9 @@
 #if SPM_MM
 #define MAX_MMAP_REGIONS		12
 #define MAX_XLAT_TABLES			12
+#elif ENABLE_RME
+#define MAX_MMAP_REGIONS		14
+#define MAX_XLAT_TABLES			14
 #else
 #define MAX_MMAP_REGIONS		11
 #define MAX_XLAT_TABLES			11
@@ -205,7 +217,7 @@
 #define QEMU_FLASH1_SIZE		0x10000000
 
 #define PLAT_QEMU_FIP_BASE		BL1_SIZE
-#define PLAT_QEMU_FIP_MAX_SIZE		0x00400000
+#define PLAT_QEMU_FIP_MAX_SIZE		(QEMU_FLASH0_SIZE - BL1_SIZE)
 
 /* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */
 #define DEVICE0_BASE			0x40000000
@@ -377,4 +389,105 @@
 #define QEMU_PRI_BITS		2
 #define PLAT_SP_PRI		0x20
 
+#if !ENABLE_RME
+#define RME_GPT_DRAM_SIZE	0
+#define NS_DRAM0_BASE_OFFSET	0
+#else /* !ENABLE_RME */
+/*
+ * SBSA RAM starts at 1TB and we support up to 1TB of RAM.  As such we
+ * have 2TB of physical address space to cover.  Since the GPT size can be
+ * 4GB, 64GB, 1TB, 4TB and so on, we need to select 4GB.  Note that it is
+ * possible to support more than 1TB of RAM but that will take more room in
+ * secure memory due to the L1 GPTES.  See PLAT_QEMU_L1_GPT_SIZE for details.
+ *
+ * 4TB / 1GB == 4096 GPTEs
+ * 4096 * 8 (bytes per GPTE) == 32768 i.e 8 pages
+ */
+#define PLAT_QEMU_L0_GPT_SIZE	(8 * PAGE_SIZE)
+#define PLAT_QEMU_L0_GPT_BASE	(PLAT_QEMU_L1_GPT_BASE - \
+				 (PLAT_QEMU_L0_GPT_SIZE + \
+				  PLAT_QEMU_GPT_BITLOCK_SIZE + \
+				  PLAT_QEMU_GPT_ALIGNMENT))
+
+#if RME_GPT_BITLOCK_BLOCK
+/*
+ * 4TB / (RME_GPT_BITLOCK_BLOCK * 512M * 8) == 1024
+ */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE	(1 * PAGE_SIZE)
+/*
+ * PLAT_QEMU_L0_GPT_SIZE is 8 pages and PLAT_QEMU_GPT_BITLOCK_SIZE
+ * is 1 page.  As such we need 7 pages to have an 8 page alignment.
+ */
+#define PLAT_QEMU_GPT_ALIGNMENT		(7 * PAGE_SIZE)
+#else /* RME_GPT_BITLOCK_BLOCK */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE	0
+#define PLAT_QEMU_GPT_ALIGNMENT		0
+#endif /* RME_GPT_BITLOCK_BLOCK */
+
+/*
+ * If we have 1TB of RAM and each L1GPT covers 1GB, we need 1024 L1GPTs. With
+ * one more L1GPT to cover the other physical address spaces (see pas_regions[]
+ * in qemu_bl31_setup.c), we need a total of 1025 L1GPTs.  Each L1GPT is 131072
+ * bytes, so we need 1025 * 131072 bytes = 0x8020000 of RAM to hold the L1GPTS.
+ */
+#define PLAT_QEMU_L1_GPT_SIZE	UL(0x08020000)
+#define PLAT_QEMU_L1_GPT_BASE	(BL_RAM_BASE + BL_RAM_SIZE - \
+				 PLAT_QEMU_L1_GPT_SIZE)
+#define PLAT_QEMU_L1_GPT_END	(PLAT_QEMU_L1_GPT_BASE + \
+				 PLAT_QEMU_L1_GPT_SIZE - 1U)
+
+#define RME_GPT_DRAM_BASE	PLAT_QEMU_L0_GPT_BASE
+#define RME_GPT_DRAM_SIZE	(PLAT_QEMU_L1_GPT_SIZE + \
+				 PLAT_QEMU_L0_GPT_SIZE + \
+				 PLAT_QEMU_GPT_BITLOCK_SIZE + \
+				 PLAT_QEMU_GPT_ALIGNMENT)
+
+#ifndef __ASSEMBLER__
+/* L0 table greater than 4KB must be naturally aligned */
+CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
+	assert_l0_gpt_naturally_aligned);
+#endif
+
+/* Reserved some DRAM space for RMM (1072MB) */
+#define REALM_DRAM_BASE			PLAT_QEMU_DRAM0_BASE
+#define REALM_DRAM_SIZE			0x43000000
+
+#define PLAT_QEMU_RMM_SIZE		(REALM_DRAM_SIZE - RMM_SHARED_SIZE)
+#define PLAT_QEMU_RMM_SHARED_SIZE	(PAGE_SIZE)	/* 4KB */
+
+#define RMM_BASE			(REALM_DRAM_BASE)
+#define RMM_LIMIT			(RMM_BASE + PLAT_QEMU_RMM_SIZE)
+#define RMM_SHARED_BASE			(RMM_LIMIT)
+#define RMM_SHARED_SIZE			PLAT_QEMU_RMM_SHARED_SIZE
+
+#define MAP_GPT_L0_REGION		MAP_REGION_FLAT(		\
+					PLAT_QEMU_L0_GPT_BASE,		\
+					(PLAT_QEMU_L0_GPT_SIZE +	\
+					 PLAT_QEMU_GPT_BITLOCK_SIZE +	\
+					 PLAT_QEMU_GPT_ALIGNMENT),	\
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_GPT_L1_REGION		MAP_REGION_FLAT(		\
+					PLAT_QEMU_L1_GPT_BASE,		\
+					PLAT_QEMU_L1_GPT_SIZE,		\
+					MT_MEMORY | MT_RW | EL3_PAS)
+/*
+ * We add the RMM_SHARED size to RMM mapping to map the region as a block.
+ * Else we end up requiring more pagetables in BL2 for ROMLIB build.
+ */
+#define MAP_RMM_DRAM			MAP_REGION_FLAT(		\
+					RMM_BASE,			\
+					(PLAT_QEMU_RMM_SIZE +		\
+					 RMM_SHARED_SIZE),		\
+					MT_MEMORY | MT_RW | MT_REALM)
+
+#define MAP_RMM_SHARED_MEM		MAP_REGION_FLAT(		\
+					RMM_SHARED_BASE,		\
+					RMM_SHARED_SIZE,		\
+					MT_MEMORY | MT_RW | MT_REALM)
+
+/* When RME is enabled, the base of NS DRAM is moved forward after the RMM */
+#define NS_DRAM0_BASE_OFFSET	REALM_DRAM_SIZE
+#endif /* !ENABLE_RME */
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h
new file mode 100644
index 0000000..c73a162
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QEMU_PAS_DEF_H
+#define QEMU_PAS_DEF_H
+
+#include <lib/gpt_rme/gpt_rme.h>
+#include "platform_def.h"
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/* EL3 SRAM */
+#define QEMU_PAS_ROOT_BASE	(BL32_MEM_BASE + BL32_MEM_SIZE)
+#define QEMU_PAS_ROOT_SIZE	(BL_RAM_SIZE - \
+				 (BL32_MEM_SIZE + RME_GPT_DRAM_SIZE))
+
+/* Secure DRAM */
+#define QEMU_PAS_SEC_BASE	BL32_MEM_BASE /* BL32_SRAM_BASE */
+#define QEMU_PAS_SEC_SIZE	BL32_MEM_SIZE
+
+/* GPTs */
+#define QEMU_PAS_GPT_BASE	RME_GPT_DRAM_BASE /* PLAT_QEMU_L0_GPT_BASE */
+#define QEMU_PAS_GPT_SIZE	RME_GPT_DRAM_SIZE
+
+/* RMM */
+#define QEMU_PAS_RMM_BASE	RMM_BASE
+#define QEMU_PAS_RMM_SIZE	PLAT_QEMU_RMM_SIZE
+
+/* Shared area between EL3 and RMM */
+#define QEMU_PAS_RMM_SHARED_BASE	RMM_SHARED_BASE
+#define QEMU_PAS_RMM_SHARED_SIZE	RMM_SHARED_SIZE
+
+#define QEMU_PAS_ROOT		GPT_MAP_REGION_GRANULE(QEMU_PAS_ROOT_BASE, \
+						       QEMU_PAS_ROOT_SIZE, \
+						       GPT_GPI_ROOT)
+
+#define QEMU_PAS_SECURE		GPT_MAP_REGION_GRANULE(QEMU_PAS_SEC_BASE, \
+						       QEMU_PAS_SEC_SIZE, \
+						       GPT_GPI_SECURE)
+
+#define QEMU_PAS_GPTS		GPT_MAP_REGION_GRANULE(QEMU_PAS_GPT_BASE, \
+						       QEMU_PAS_GPT_SIZE, \
+						       GPT_GPI_ROOT)
+
+/*
+ * NS0 base address and size are fetched from the DT at runtime.
+ * See bl31_adjust_pas_regions() for details
+ */
+#define QEMU_PAS_NS0		GPT_MAP_REGION_GRANULE(0, 0, GPT_GPI_NS)
+
+#define QEMU_PAS_REALM		GPT_MAP_REGION_GRANULE(QEMU_PAS_RMM_BASE, \
+					       QEMU_PAS_RMM_SIZE + \
+					       QEMU_PAS_RMM_SHARED_SIZE, \
+					       GPT_GPI_REALM)
+
+/* Cover 4TB with L0GTP */
+#define PLATFORM_GPCCR_PPS	GPCCR_PPS_4TB
+
+/* GPT Configuration options */
+#define PLATFORM_L0GPTSZ	GPCCR_L0GPTSZ_30BITS
+
+#endif /* QEMU_PAS_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/include/sbsa_platform.h b/plat/qemu/qemu_sbsa/include/sbsa_platform.h
new file mode 100644
index 0000000..a3b3ea1
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/include/sbsa_platform.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_PLATFORM_H
+#define SBSA_PLATFORM_H
+
+#include <stdint.h>
+
+#include <platform_def.h>
+
+struct platform_cpu_data {
+	uint32_t nodeid;
+	uint32_t mpidr;
+};
+
+struct platform_memory_data {
+	uint32_t nodeid;
+	uint64_t addr_base;
+	uint64_t addr_size;
+};
+
+/*
+ * sockets: the number of sockets on sbsa-ref platform.
+ * clusters: the number of clusters in one socket.
+ * cores: the number of cores in one cluster.
+ * threads: the number of threads in one core.
+ */
+struct platform_cpu_topology {
+	uint32_t sockets;
+	uint32_t clusters;
+	uint32_t cores;
+	uint32_t threads;
+};
+
+struct qemu_platform_info {
+	uint32_t num_cpus;
+	uint32_t num_memnodes;
+	struct platform_cpu_data cpu[PLATFORM_CORE_COUNT];
+	struct platform_cpu_topology cpu_topo;
+	struct platform_memory_data memory[PLAT_MAX_MEM_NODES];
+};
+
+void sbsa_platform_init(void);
+int sbsa_platform_version_major(void);
+int sbsa_platform_version_minor(void);
+uint32_t sbsa_platform_num_cpus(void);
+uint32_t sbsa_platform_num_memnodes(void);
+uint64_t sbsa_platform_gic_its_addr(void);
+struct platform_cpu_data sbsa_platform_cpu_node(uint64_t index);
+struct platform_memory_data sbsa_platform_memory_node(uint64_t index);
+struct platform_cpu_topology sbsa_platform_cpu_topology(void);
+
+#endif /* SBSA_PLATFORM_H */
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 528e093..8ec3a82 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -29,8 +29,6 @@
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
 
-BL2_SOURCES		+=	$(LIBFDT_SRCS)
-
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
@@ -38,6 +36,7 @@
 				plat/common/plat_gicv3.c
 
 BL31_SOURCES		+=	${PLAT_QEMU_PATH}/sbsa_gic.c 			\
+				${PLAT_QEMU_PATH}/sbsa_platform.c		\
 				${PLAT_QEMU_PATH}/sbsa_pm.c			\
 				${PLAT_QEMU_PATH}/sbsa_sip_svc.c		\
 				${PLAT_QEMU_PATH}/sbsa_topology.c
@@ -61,5 +60,5 @@
 $(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 
-ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
+ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DRAM0_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
diff --git a/plat/qemu/qemu_sbsa/sbsa_platform.c b/plat/qemu/qemu_sbsa/sbsa_platform.c
new file mode 100644
index 0000000..8c8d632
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_platform.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+
+#include <sbsa_platform.h>
+
+#include "qemu_private.h"
+
+/* default platform version is 0.0 */
+static int platform_version_major;
+static int platform_version_minor;
+
+static uint64_t gic_its_addr;
+static struct qemu_platform_info dynamic_platform_info;
+
+void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
+
+/*
+ * QEMU provides us with minimal information about hardware platform using
+ * minimalistic DeviceTree. This is not a Linux DeviceTree. It is not even
+ * a firmware DeviceTree.
+ *
+ * It is information passed from QEMU to describe the information a hardware
+ * platform would have other mechanisms to discover at runtime, that are
+ * affected by the QEMU command line.
+ *
+ * Ultimately this device tree will be replaced by IPC calls to an emulated SCP.
+ * And when we do that, we won't then have to rewrite Normal world firmware to
+ * cope.
+ */
+
+static void read_cpu_topology_from_dt(void *dtb)
+{
+	int node;
+
+	/*
+	 * QEMU gives us this DeviceTree node when we config:
+	 * -smp 16,sockets=2,clusters=2,cores=2,threads=2
+	 *
+	 * topology {
+	 *	threads = <0x02>;
+	 *	cores = <0x02>;
+	 *	clusters = <0x02>;
+	 *	sockets = <0x02>;
+	 * };
+	 */
+
+	node = fdt_path_offset(dtb, "/cpus/topology");
+	if (node > 0) {
+		dynamic_platform_info.cpu_topo.sockets =
+			fdt_read_uint32_default(dtb, node, "sockets", 0);
+		dynamic_platform_info.cpu_topo.clusters =
+			fdt_read_uint32_default(dtb, node, "clusters", 0);
+		dynamic_platform_info.cpu_topo.cores =
+			fdt_read_uint32_default(dtb, node, "cores", 0);
+		dynamic_platform_info.cpu_topo.threads =
+			fdt_read_uint32_default(dtb, node, "threads", 0);
+	}
+
+	INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
+		dynamic_platform_info.cpu_topo.sockets,
+		dynamic_platform_info.cpu_topo.clusters,
+		dynamic_platform_info.cpu_topo.cores,
+		dynamic_platform_info.cpu_topo.threads);
+}
+
+static void read_cpuinfo_from_dt(void *dtb)
+{
+	int node;
+	int prev;
+	int cpu = 0;
+	uintptr_t mpidr;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 * numa-node-id entries are only when NUMA config is used
+	 *
+	 *  cpus {
+	 *	#size-cells = <0x00>;
+	 *	#address-cells = <0x02>;
+	 *
+	 *	cpu@0 {
+	 *		numa-node-id = <0x00>;
+	 *		reg = <0x00 0x00>;
+	 *	};
+	 *
+	 *	cpu@1 {
+	 *		numa-node-id = <0x03>;
+	 *		reg = <0x00 0x01>;
+	 *	};
+	 *  };
+	 */
+	node = fdt_path_offset(dtb, "/cpus");
+	if (node < 0) {
+		ERROR("No information about cpus in DeviceTree.\n");
+		panic();
+	}
+
+	/*
+	 * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we
+	 * cannot use fdt_first_subnode() here
+	 */
+	node = fdt_path_offset(dtb, "/cpus/cpu@0");
+
+	while (node > 0) {
+		if (fdt_getprop(dtb, node, "reg", NULL)) {
+			fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
+		} else {
+			ERROR("Incomplete information for cpu %d in DeviceTree.\n", cpu);
+			panic();
+		}
+
+		dynamic_platform_info.cpu[cpu].mpidr = mpidr;
+		dynamic_platform_info.cpu[cpu].nodeid =
+			fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
+				dynamic_platform_info.cpu[cpu].nodeid, mpidr);
+
+		cpu++;
+
+		prev = node;
+		node = fdt_next_subnode(dtb, prev);
+	}
+
+	dynamic_platform_info.num_cpus = cpu;
+	INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
+
+	read_cpu_topology_from_dt(dtb);
+}
+
+static void read_meminfo_from_dt(void *dtb)
+{
+	const fdt32_t *prop;
+	const char *type;
+	int prev, node;
+	int len;
+	uint32_t memnode = 0;
+	uint32_t higher_value, lower_value;
+	uint64_t cur_base, cur_size;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 *
+	 *	memory@100c0000000 {
+	 *		numa-node-id = <0x01>;
+	 *		reg = <0x100 0xc0000000 0x00 0x40000000>;
+	 *		device_type = "memory";
+	 *	};
+	 *
+	 *	memory@10000000000 {
+	 *		numa-node-id = <0x00>;
+	 *		reg = <0x100 0x00 0x00 0xc0000000>;
+	 *		device_type = "memory";
+	 *	}
+	 */
+
+	for (prev = 0;; prev = node) {
+		node = fdt_next_node(dtb, prev, NULL);
+		if (node < 0) {
+			break;
+		}
+
+		type = fdt_getprop(dtb, node, "device_type", &len);
+		if (type && strncmp(type, "memory", len) == 0) {
+			dynamic_platform_info.memory[memnode].nodeid =
+				fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+			/*
+			 * Get the 'reg' property of this node and
+			 * assume two 8 bytes for base and size.
+			 */
+			prop = fdt_getprop(dtb, node, "reg", &len);
+			if (prop != 0 && len == (2 * sizeof(int64_t))) {
+				higher_value = fdt32_to_cpu(*prop);
+				lower_value = fdt32_to_cpu(*(prop + 1));
+				cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+				higher_value = fdt32_to_cpu(*(prop + 2));
+				lower_value = fdt32_to_cpu(*(prop + 3));
+				cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+				dynamic_platform_info.memory[memnode].addr_base = cur_base;
+				dynamic_platform_info.memory[memnode].addr_size = cur_size;
+
+				INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
+					memnode,
+					dynamic_platform_info.memory[memnode].nodeid,
+					dynamic_platform_info.memory[memnode].addr_base,
+					dynamic_platform_info.memory[memnode].addr_base +
+					dynamic_platform_info.memory[memnode].addr_size - 1);
+			}
+
+			memnode++;
+		}
+	}
+
+	dynamic_platform_info.num_memnodes = memnode;
+}
+
+static void read_platform_config_from_dt(void *dtb)
+{
+	int node;
+	const fdt64_t *data;
+	int err;
+	uintptr_t gicd_base;
+	uintptr_t gicr_base;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 *
+	 * intc {
+	 *	 reg = < 0x00 0x40060000 0x00 0x10000
+	 *		 0x00 0x40080000 0x00 0x4000000>;
+	 *       its {
+	 *               reg = <0x00 0x44081000 0x00 0x20000>;
+	 *       };
+	 * };
+	 */
+	node = fdt_path_offset(dtb, "/intc");
+	if (node < 0) {
+		return;
+	}
+
+	data = fdt_getprop(dtb, node, "reg", NULL);
+	if (data == NULL) {
+		return;
+	}
+
+	err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICD reg property of GIC node\n");
+		return;
+	}
+	INFO("GICD base = 0x%lx\n", gicd_base);
+
+	err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICR reg property of GIC node\n");
+		return;
+	}
+	INFO("GICR base = 0x%lx\n", gicr_base);
+
+	sbsa_set_gic_bases(gicd_base, gicr_base);
+
+	node = fdt_path_offset(dtb, "/intc/its");
+	if (node < 0) {
+		return;
+	}
+
+	err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICI reg property of GIC node\n");
+		return;
+	}
+	INFO("GICI base = 0x%lx\n", gic_its_addr);
+}
+
+static void read_platform_version(void *dtb)
+{
+	int node;
+
+	node = fdt_path_offset(dtb, "/");
+	if (node >= 0) {
+		platform_version_major =
+			fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
+		platform_version_minor =
+			fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
+	}
+}
+
+#if !ENABLE_RME
+static int set_system_memory_base(void *dtb, uintptr_t new_base)
+{
+	(void)dtb;
+	(void)new_base;
+
+	return 0;
+}
+#else /* !ENABLE_RME */
+static int set_system_memory_base(void *dtb, uintptr_t new_base)
+{
+	uint64_t cur_base, cur_size, new_size, delta;
+	int len, prev, node, ret;
+	const fdt32_t *prop;
+	uint32_t node_id;
+	const char *type;
+	fdt64_t new[2];
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 *
+	 *	memory@100c0000000 {
+	 *		numa-node-id = <0x01>;
+	 *		reg = <0x100 0xc0000000 0x00 0x40000000>;
+	 *		device_type = "memory";
+	 *	};
+	 *
+	 *	memory@10000000000 {
+	 *		numa-node-id = <0x00>;
+	 *		reg = <0x100 0x00 0x00 0xc0000000>;
+	 *		device_type = "memory";
+	 *	}
+	 */
+
+	for (prev = 0;; prev = node) {
+		node = fdt_next_node(dtb, prev, NULL);
+		if (node < 0) {
+			return node;
+		}
+
+		type = fdt_getprop(dtb, node, "device_type", &len);
+		if (type && strncmp(type, "memory", len) == 0) {
+
+			/*
+			 * We are looking for numa node 0, i.e the start of the
+			 * system memory.  If a "numa-node-id" doesn't exists we
+			 * take the first one.
+			 */
+			node_id = fdt_read_uint32_default(dtb, node,
+							  "numa-node-id", 0);
+
+			if (node_id == 0) {
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Get the 'reg' property of this node and
+	 * assume two 8 bytes for base and size.
+	 */
+	prop = fdt_getprop(dtb, node, "reg", &len);
+	if (!prop || len < 0) {
+		return len;
+	}
+
+	if (len != (2 * sizeof(uint64_t))) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	ret = fdt_get_reg_props_by_index(dtb, node, 0, &cur_base, &cur_size);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * @cur_base is the base of the NS RAM given to us by QEMU, we can't
+	 * go lower than that.
+	 */
+	if (new_base < cur_base) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	if (new_base == cur_base) {
+		return 0;
+	}
+
+	/*
+	 * The new base is higher than the base set by QEMU, i.e we are moving
+	 * the base memory up and shrinking the size.
+	 */
+	delta = (size_t)(new_base - cur_base);
+
+	/*
+	 * Make sure the new base is still within the base memory node, i.e
+	 * the base memory node is big enough for the RMM.
+	 */
+	if (delta >= cur_size) {
+		ERROR("Not enough space in base memory node for RMM\n");
+		return -FDT_ERR_BADVALUE;
+	}
+
+	new_size = cur_size - delta;
+
+	new[0] = cpu_to_fdt64(new_base);
+	new[1] = cpu_to_fdt64(new_size);
+
+	ret = fdt_setprop(dtb, node, "reg", new, len);
+	if (ret < 0) {
+		return ret;
+	}
+
+	return fdt_pack(dtb);
+}
+#endif /* !ENABLE_RME */
+
+void sbsa_platform_init(void)
+{
+	/* Read DeviceTree data before MMU is enabled */
+
+	void *dtb = plat_qemu_dt_runtime_address();
+	int err;
+
+	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 = fdt_check_header(dtb);
+	if (err < 0) {
+		ERROR("Invalid DTB file passed\n");
+		return;
+	}
+
+	read_platform_version(dtb);
+	INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
+
+	if (set_system_memory_base(dtb, NS_DRAM0_BASE)) {
+		ERROR("Failed to set system memory in Device Tree\n");
+		return;
+	}
+
+	read_platform_config_from_dt(dtb);
+	read_cpuinfo_from_dt(dtb);
+	read_meminfo_from_dt(dtb);
+}
+
+int sbsa_platform_version_major(void)
+{
+	return platform_version_major;
+}
+
+int sbsa_platform_version_minor(void)
+{
+	return platform_version_minor;
+}
+
+uint32_t sbsa_platform_num_cpus(void)
+{
+	return dynamic_platform_info.num_cpus;
+}
+
+uint32_t sbsa_platform_num_memnodes(void)
+{
+	return dynamic_platform_info.num_memnodes;
+}
+
+uint64_t sbsa_platform_gic_its_addr(void)
+{
+	return gic_its_addr;
+}
+
+struct platform_cpu_data sbsa_platform_cpu_node(uint64_t index)
+{
+	return dynamic_platform_info.cpu[index];
+}
+
+struct platform_memory_data sbsa_platform_memory_node(uint64_t index)
+{
+	return dynamic_platform_info.memory[index];
+}
+
+struct platform_cpu_topology sbsa_platform_cpu_topology(void)
+{
+	return dynamic_platform_info.cpu_topo;
+}
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 83e66f3..839bb1c 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -6,14 +6,10 @@
 
 #include <assert.h>
 
-#include <common/fdt_wrappers.h>
 #include <common/runtime_svc.h>
-#include <libfdt.h>
 #include <smccc_helpers.h>
 
-/* default platform version is 0.0 */
-static int platform_version_major;
-static int platform_version_minor;
+#include <sbsa_platform.h>
 
 #define SMC_FASTCALL       0x80000000
 #define SMC64_FUNCTION     (SMC_FASTCALL   | 0x40000000)
@@ -34,326 +30,10 @@
 #define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
 #define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
 
-static uint64_t gic_its_addr;
-
-typedef struct {
-	uint32_t nodeid;
-	uint32_t mpidr;
-} cpu_data;
-
-typedef struct{
-	uint32_t nodeid;
-	uint64_t addr_base;
-	uint64_t addr_size;
-} memory_data;
-
-/*
- * sockets: the number of sockets on sbsa-ref platform.
- * clusters: the number of clusters in one socket.
- * cores: the number of cores in one cluster.
- * threads: the number of threads in one core.
- */
-typedef struct {
-	uint32_t sockets;
-	uint32_t clusters;
-	uint32_t cores;
-	uint32_t threads;
-} cpu_topology;
-
-static struct {
-	uint32_t num_cpus;
-	uint32_t num_memnodes;
-	cpu_data cpu[PLATFORM_CORE_COUNT];
-	cpu_topology cpu_topo;
-	memory_data memory[PLAT_MAX_MEM_NODES];
-} dynamic_platform_info;
-
-void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
 uintptr_t sbsa_get_gicd(void);
 uintptr_t sbsa_get_gicr(void);
 
 /*
- * QEMU provides us with minimal information about hardware platform using
- * minimalistic DeviceTree. This is not a Linux DeviceTree. It is not even
- * a firmware DeviceTree.
- *
- * It is information passed from QEMU to describe the information a hardware
- * platform would have other mechanisms to discover at runtime, that are
- * affected by the QEMU command line.
- *
- * Ultimately this device tree will be replaced by IPC calls to an emulated SCP.
- * And when we do that, we won't then have to rewrite Normal world firmware to
- * cope.
- */
-
-static void read_cpu_topology_from_dt(void *dtb)
-{
-	int node;
-
-	/*
-	 * QEMU gives us this DeviceTree node when we config:
-	 * -smp 16,sockets=2,clusters=2,cores=2,threads=2
-	 *
-	 * topology {
-	 *	threads = <0x02>;
-	 *	cores = <0x02>;
-	 *	clusters = <0x02>;
-	 *	sockets = <0x02>;
-	 * };
-	 */
-
-	node = fdt_path_offset(dtb, "/cpus/topology");
-	if (node > 0) {
-		dynamic_platform_info.cpu_topo.sockets =
-			fdt_read_uint32_default(dtb, node, "sockets", 0);
-		dynamic_platform_info.cpu_topo.clusters =
-			fdt_read_uint32_default(dtb, node, "clusters", 0);
-		dynamic_platform_info.cpu_topo.cores =
-			fdt_read_uint32_default(dtb, node, "cores", 0);
-		dynamic_platform_info.cpu_topo.threads =
-			fdt_read_uint32_default(dtb, node, "threads", 0);
-	}
-
-	INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
-		dynamic_platform_info.cpu_topo.sockets,
-		dynamic_platform_info.cpu_topo.clusters,
-		dynamic_platform_info.cpu_topo.cores,
-		dynamic_platform_info.cpu_topo.threads);
-}
-
-void read_cpuinfo_from_dt(void *dtb)
-{
-	int node;
-	int prev;
-	int cpu = 0;
-	uintptr_t mpidr;
-
-	/*
-	 * QEMU gives us this DeviceTree node:
-	 * numa-node-id entries are only when NUMA config is used
-	 *
-	 *  cpus {
-	 *  	#size-cells = <0x00>;
-	 *  	#address-cells = <0x02>;
-	 *
-	 *  	cpu@0 {
-	 *  	        numa-node-id = <0x00>;
-	 *  		reg = <0x00 0x00>;
-	 *  	};
-	 *
-	 *  	cpu@1 {
-	 *  	        numa-node-id = <0x03>;
-	 *  		reg = <0x00 0x01>;
-	 *  	};
-	 *  };
-	 */
-	node = fdt_path_offset(dtb, "/cpus");
-	if (node < 0) {
-		ERROR("No information about cpus in DeviceTree.\n");
-		panic();
-	}
-
-	/*
-	 * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we
-	 * cannot use fdt_first_subnode() here
-	 */
-	node = fdt_path_offset(dtb, "/cpus/cpu@0");
-
-	while (node > 0) {
-		if (fdt_getprop(dtb, node, "reg", NULL)) {
-			fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
-		} else {
-			ERROR("Incomplete information for cpu %d in DeviceTree.\n", cpu);
-			panic();
-		}
-
-		dynamic_platform_info.cpu[cpu].mpidr = mpidr;
-		dynamic_platform_info.cpu[cpu].nodeid =
-			fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
-
-		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
-				dynamic_platform_info.cpu[cpu].nodeid, mpidr);
-
-		cpu++;
-
-		prev = node;
-		node = fdt_next_subnode(dtb, prev);
-	}
-
-	dynamic_platform_info.num_cpus = cpu;
-	INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
-
-	read_cpu_topology_from_dt(dtb);
-}
-
-void read_meminfo_from_dt(void *dtb)
-{
-	const fdt32_t *prop;
-	const char *type;
-	int prev, node;
-	int len;
-	uint32_t memnode = 0;
-	uint32_t higher_value, lower_value;
-	uint64_t cur_base, cur_size;
-
-	/*
-	 * QEMU gives us this DeviceTree node:
-	 *
-	 *	memory@100c0000000 {
-	 *		numa-node-id = <0x01>;
-	 *		reg = <0x100 0xc0000000 0x00 0x40000000>;
-	 *		device_type = "memory";
-	 *	};
-	 *
-	 *	memory@10000000000 {
-	 *		numa-node-id = <0x00>;
-	 *		reg = <0x100 0x00 0x00 0xc0000000>;
-	 *		device_type = "memory";
-	 *	}
-	 */
-
-	for (prev = 0;; prev = node) {
-		node = fdt_next_node(dtb, prev, NULL);
-		if (node < 0) {
-			break;
-		}
-
-		type = fdt_getprop(dtb, node, "device_type", &len);
-		if (type && strncmp(type, "memory", len) == 0) {
-			dynamic_platform_info.memory[memnode].nodeid =
-				fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
-
-			/*
-			 * Get the 'reg' property of this node and
-			 * assume two 8 bytes for base and size.
-			 */
-			prop = fdt_getprop(dtb, node, "reg", &len);
-			if (prop != 0 && len == (2 * sizeof(int64_t))) {
-				higher_value = fdt32_to_cpu(*prop);
-				lower_value = fdt32_to_cpu(*(prop + 1));
-				cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
-
-				higher_value = fdt32_to_cpu(*(prop + 2));
-				lower_value = fdt32_to_cpu(*(prop + 3));
-				cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
-
-				dynamic_platform_info.memory[memnode].addr_base = cur_base;
-				dynamic_platform_info.memory[memnode].addr_size = cur_size;
-
-				INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
-					memnode,
-					dynamic_platform_info.memory[memnode].nodeid,
-					dynamic_platform_info.memory[memnode].addr_base,
-					dynamic_platform_info.memory[memnode].addr_base +
-					dynamic_platform_info.memory[memnode].addr_size - 1);
-			}
-
-			memnode++;
-		}
-	}
-
-	dynamic_platform_info.num_memnodes = memnode;
-}
-
-void read_platform_config_from_dt(void *dtb)
-{
-	int node;
-	const fdt64_t *data;
-	int err;
-	uintptr_t gicd_base;
-	uintptr_t gicr_base;
-
-	/*
-	 * QEMU gives us this DeviceTree node:
-	 *
-	 * intc {
-	 *	 reg = < 0x00 0x40060000 0x00 0x10000
-	 *		 0x00 0x40080000 0x00 0x4000000>;
-	 *       its {
-	 *               reg = <0x00 0x44081000 0x00 0x20000>;
-	 *       };
-	 * };
-	 */
-	node = fdt_path_offset(dtb, "/intc");
-	if (node < 0) {
-		return;
-	}
-
-	data = fdt_getprop(dtb, node, "reg", NULL);
-	if (data == NULL) {
-		return;
-	}
-
-	err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL);
-	if (err < 0) {
-		ERROR("Failed to read GICD reg property of GIC node\n");
-		return;
-	}
-	INFO("GICD base = 0x%lx\n", gicd_base);
-
-	err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL);
-	if (err < 0) {
-		ERROR("Failed to read GICR reg property of GIC node\n");
-		return;
-	}
-	INFO("GICR base = 0x%lx\n", gicr_base);
-
-	sbsa_set_gic_bases(gicd_base, gicr_base);
-
-	node = fdt_path_offset(dtb, "/intc/its");
-	if (node < 0) {
-		return;
-	}
-
-	err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
-	if (err < 0) {
-		ERROR("Failed to read GICI reg property of GIC node\n");
-		return;
-	}
-	INFO("GICI base = 0x%lx\n", gic_its_addr);
-}
-
-void read_platform_version(void *dtb)
-{
-	int node;
-
-	node = fdt_path_offset(dtb, "/");
-	if (node >= 0) {
-		platform_version_major =
-			fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
-		platform_version_minor =
-			fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
-	}
-}
-
-void sip_svc_init(void)
-{
-	/* Read DeviceTree data before MMU is enabled */
-
-	void *dtb = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
-	int err;
-
-	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 = fdt_check_header(dtb);
-	if (err < 0) {
-		ERROR("Invalid DTB file passed\n");
-		return;
-	}
-
-	read_platform_version(dtb);
-	INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
-
-	read_platform_config_from_dt(dtb);
-	read_cpuinfo_from_dt(dtb);
-	read_meminfo_from_dt(dtb);
-}
-
-/*
  * This function is responsible for handling all SiP calls from the NS world
  */
 uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
@@ -378,49 +58,56 @@
 	switch (smc_fid) {
 	case SIP_SVC_VERSION:
 		INFO("Platform version requested\n");
-		SMC_RET3(handle, NULL, platform_version_major, platform_version_minor);
+		SMC_RET3(handle, NULL, sbsa_platform_version_major(),
+			 sbsa_platform_version_minor());
 
 	case SIP_SVC_GET_GIC:
 		SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr());
 
 	case SIP_SVC_GET_GIC_ITS:
-		SMC_RET2(handle, NULL, gic_its_addr);
+		SMC_RET2(handle, NULL, sbsa_platform_gic_its_addr());
 
 	case SIP_SVC_GET_CPU_COUNT:
-		SMC_RET2(handle, NULL, dynamic_platform_info.num_cpus);
+		SMC_RET2(handle, NULL, sbsa_platform_num_cpus());
 
 	case SIP_SVC_GET_CPU_NODE:
 		index = x1;
 		if (index < PLATFORM_CORE_COUNT) {
-			SMC_RET3(handle, NULL,
-				dynamic_platform_info.cpu[index].nodeid,
-				dynamic_platform_info.cpu[index].mpidr);
+			struct platform_cpu_data data;
+
+			data = sbsa_platform_cpu_node(index);
+
+			SMC_RET3(handle, NULL, data.nodeid, data.mpidr);
 		} else {
 			SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
 		}
 
 	case SIP_SVC_GET_CPU_TOPOLOGY:
-		if (dynamic_platform_info.cpu_topo.cores > 0) {
-			SMC_RET5(handle, NULL,
-			dynamic_platform_info.cpu_topo.sockets,
-			dynamic_platform_info.cpu_topo.clusters,
-			dynamic_platform_info.cpu_topo.cores,
-			dynamic_platform_info.cpu_topo.threads);
+		struct platform_cpu_topology topology;
+
+		topology = sbsa_platform_cpu_topology();
+
+		if (topology.cores > 0) {
+			SMC_RET5(handle, NULL, topology.sockets,
+				 topology.clusters, topology.cores,
+				 topology.threads);
 		} else {
 			/* we do not know topology so we report SMC as unknown */
 			SMC_RET1(handle, SMC_UNK);
 		}
 
 	case SIP_SVC_GET_MEMORY_NODE_COUNT:
-		SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
+		SMC_RET2(handle, NULL, sbsa_platform_num_memnodes());
 
 	case SIP_SVC_GET_MEMORY_NODE:
 		index = x1;
 		if (index < PLAT_MAX_MEM_NODES) {
-			SMC_RET4(handle, NULL,
-				dynamic_platform_info.memory[index].nodeid,
-				dynamic_platform_info.memory[index].addr_base,
-				dynamic_platform_info.memory[index].addr_size);
+			struct platform_memory_data data;
+
+			data = sbsa_platform_memory_node(index);
+
+			SMC_RET4(handle, NULL, data.nodeid,
+				 data.addr_base, data.addr_size);
 		} else {
 			SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
 		}
diff --git a/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk b/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk
new file mode 100644
index 0000000..07ccac0
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qemu/common/trp/trp-qemu-common.mk
+
diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c
index f00267a..746c6f1 100644
--- a/plat/qti/common/src/qti_gic_v3.c
+++ b/plat/qti/common/src/qti_gic_v3.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,24 +54,36 @@
 		       INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
 #endif
+#ifdef QTISECLIB_INT_ID_A2_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
 		       INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_CONFIG_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR,
 		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_DC_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
 		       INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_MEM_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
 		       INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_SYSTEM_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR,
 		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_MMSS_NOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
 		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
 		       GIC_INTR_CFG_EDGE),
+#endif
 #ifdef QTISECLIB_INT_ID_LPASS_AGNOC_ERROR
 	INTR_PROP_DESC(QTISECLIB_INT_ID_LPASS_AGNOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
 		       INTR_GROUP0,
diff --git a/plat/qti/qcs615/inc/platform_def.h b/plat/qti/qcs615/inc/platform_def.h
new file mode 100644
index 0000000..5b8ff7d
--- /dev/null
+++ b/plat/qti/qcs615/inc/platform_def.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Enable the dynamic translation tables library. */
+#define PLAT_XLAT_TABLES_DYNAMIC 1
+
+#include <common_def.h>
+
+#include <qti_board_def.h>
+#include <qtiseclib_defs_plat.h>
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*
+ * MPIDR_PRIMARY_CPU
+ * You just need to have the correct core_affinity_val i.e. [7:0]
+ * and cluster_affinity_val i.e. [15:8]
+ * the other bits will be ignored
+ */
+/*----------------------------------------------------------------------------*/
+#define MPIDR_PRIMARY_CPU  0x0000
+/*----------------------------------------------------------------------------*/
+
+#define QTI_PWR_LVL0    MPIDR_AFFLVL0
+#define QTI_PWR_LVL1    MPIDR_AFFLVL1
+#define QTI_PWR_LVL2    MPIDR_AFFLVL2
+#define QTI_PWR_LVL3    MPIDR_AFFLVL3
+
+/*
+ *  Macros for local power states encoded by State-ID field
+ *  within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define QTI_LOCAL_STATE_RUN   0
+/*
+ * Local power state for clock-gating. Valid only for CPU and not cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_STB   1
+/*
+ * Local power state for retention. Valid for CPU and cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_RET   2
+/*
+ * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_OFF   3
+/*
+ * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_DEEPOFF  4
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE QTI_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE QTI_LOCAL_STATE_DEEPOFF
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Platform specific page table and MMU setup constants.
+ */
+#define MAX_MMAP_REGIONS   (PLAT_QTI_MMAP_ENTRIES)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE    (1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE   (1ull << 36)
+
+#define ARM_CACHE_WRITEBACK_SHIFT   6
+
+/*
+ * Some data must be 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.
+ */
+#define CACHE_WRITEBACK_GRANULE     (1 << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE   (1 * CACHE_WRITEBACK_GRANULE)
+
+/*----------------------------------------------------------------------------*/
+/* PSCI power domain topology definitions */
+/*----------------------------------------------------------------------------*/
+/* One domain each to represent RSC and PDC level */
+#define PLAT_PDC_COUNT        1
+#define PLAT_RSC_COUNT        1
+
+/* There is one top-level FCM cluster */
+#define PLAT_CLUSTER_COUNT    1
+
+/* No. of cores in the FCM cluster */
+#define PLAT_CLUSTER0_CORE_COUNT 8
+
+#define PLATFORM_CORE_COUNT      (PLAT_CLUSTER0_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS     (PLAT_PDC_COUNT +\
+									PLAT_RSC_COUNT   +\
+									PLAT_CLUSTER_COUNT  +\
+									PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL      3
+
+/*****************************************************************************/
+/* Memory mapped Generic timer interfaces  */
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* GIC-600 constants */
+/*----------------------------------------------------------------------------*/
+#define BASE_GICD_BASE     0x17A00000
+#define BASE_GICR_BASE     0x17A60000
+#define BASE_GICC_BASE     0x0
+#define BASE_GICH_BASE     0x0
+#define BASE_GICV_BASE     0x0
+
+#define QTI_GICD_BASE      BASE_GICD_BASE
+#define QTI_GICR_BASE      BASE_GICR_BASE
+#define QTI_GICC_BASE      BASE_GICC_BASE
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UART related constants. */
+/*----------------------------------------------------------------------------*/
+/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
+#define GENI4_CFG          0x0
+#define GENI4_IMAGE_REGS   0x100
+#define GENI4_DATA         0x600
+
+/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
+#define GENI_STATUS_REG                      (GENI4_CFG + 0x00000040)
+#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK   (0x1)
+#define UART_TX_TRANS_LEN_REG                (GENI4_IMAGE_REGS + 0x00000170)
+/* MASTER/TX ENGINE REGISTERS */
+#define GENI_M_CMD0_REG                      (GENI4_DATA + 0x00000000)
+/* FIFO, STATUS REGISTERS AND MASKS */
+#define GENI_TX_FIFOn_REG                    (GENI4_DATA + 0x00000100)
+
+#define GENI_M_CMD_TX                        (0x08000000)
+
+/*----------------------------------------------------------------------------*/
+/* Device address space for mapping. Excluding starting 4K */
+/*----------------------------------------------------------------------------*/
+#define QTI_DEVICE_BASE          0x1000
+#define QTI_DEVICE_SIZE          (0x80000000 - QTI_DEVICE_BASE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define BL31_LIMIT            (BL31_BASE + BL31_SIZE)
+
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG             0x0C264000
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB  address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE         0x85F20000
+#define QTI_AOP_CMD_DB_SIZE         0x00020000
+/*----------------------------------------------------------------------------*/
+/* SOC hw version register */
+/*----------------------------------------------------------------------------*/
+#define QTI_SOC_VERSION_MASK        U(0xFFFF)
+#define QTI_SOC_REVISION_REG        0x1FC8000
+#define QTI_SOC_REVISION_MASK       U(0xFFFF)
+/*----------------------------------------------------------------------------*/
+/* LC PON register offsets */
+/*----------------------------------------------------------------------------*/
+#define PON_PS_HOLD_RESET_CTL       0x85a
+#define PON_PS_HOLD_RESET_CTL2      0x85b
+/*----------------------------------------------------------------------------*/
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/qcs615/inc/qti_map_chipinfo.h b/plat/qti/qcs615/inc/qti_map_chipinfo.h
new file mode 100644
index 0000000..6092ea0
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_map_chipinfo.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_MAP_CHIPINFO_H
+#define QTI_MAP_CHIPINFO_H
+
+#include <stdint.h>
+
+#include <qti_plat.h>
+
+#define QTI_JTAG_ID_REG                         0x786130
+#define QTI_JTAG_ID_SHIFT                       12
+#define QTI_JTAG_ID_QCS615                      U(0x02E9)
+#define QTI_JTAG_ID_SA6155P                     U(0x00EE)
+#define QTI_CHIPINFO_ID_QCS615                  U(0x01E7)
+#define QTI_CHIPINFO_ID_SA6155P                 U(0x0179)
+#define QTI_DEFAULT_CHIPINFO_ID                 U(0xFFFF)
+
+static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
+	{QTI_JTAG_ID_QCS615,  QTI_CHIPINFO_ID_QCS615},
+	{QTI_JTAG_ID_SA6155P, QTI_CHIPINFO_ID_SA6155P},
+};
+
+#endif /* QTI_MAP_CHIPINFO_H */
diff --git a/plat/qti/qcs615/inc/qti_rng_io.h b/plat/qti/qcs615/inc/qti_rng_io.h
new file mode 100644
index 0000000..b5e521e
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_rng_io.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef QTI_RNG_IO_H
+#define QTI_RNG_IO_H
+
+#define SEC_PRNG_STATUS			            0x791004
+#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK	0x1
+#define SEC_PRNG_DATA_OUT		            0x791000
+
+#endif /* QTI_RNG_IO_H */
+
diff --git a/plat/qti/qcs615/inc/qti_secure_io_cfg.h b/plat/qti/qcs615/inc/qti_secure_io_cfg.h
new file mode 100644
index 0000000..a78583e
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_secure_io_cfg.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_SECURE_IO_CFG_H
+#define QTI_SECURE_IO_CFG_H
+
+#include <stdint.h>
+
+/*
+ * List of peripheral/IO memory areas that are protected from
+ * non-secure world but not required to be secure.
+ */
+#define APPS_SMMU_TBU_PWR_STATUS             0x15002204
+#define APPS_SMMU_CUSTOM_CFG                 0x15002300
+#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK     0x150025DC
+#define APPS_SMMU_SAFE_SEC_CFG               0x15002644
+#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002648
+
+static const uintptr_t qti_secure_io_allowed_regs[] = {
+	APPS_SMMU_TBU_PWR_STATUS,
+	APPS_SMMU_CUSTOM_CFG,
+	APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
+	APPS_SMMU_SAFE_SEC_CFG,
+	APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+static const uintptr_t qti_secure_io_debug_allowed_regs[] = {
+};
+
+
+#endif /* QTI_SECURE_IO_CFG_H */
diff --git a/plat/qti/qcs615/platform.mk b/plat/qti/qcs615/platform.mk
new file mode 100644
index 0000000..a3136cb
--- /dev/null
+++ b/plat/qti/qcs615/platform.mk
@@ -0,0 +1,142 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, The Linux Foundation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Makefile for QCS615 QTI platform.
+
+QTI_PLAT_PATH	:=	plat/qti
+CHIPSET			:=	${PLAT}
+
+# Turn On Separate code & data.
+SEPARATE_CODE_AND_RODATA		:=	1
+USE_COHERENT_MEM					:=	0
+WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
+HW_ASSISTED_COHERENCY			:=	1
+
+# Enable errata configs for cortex_a76 and cortex_a55
+# QCS615 CPU core revisions are r1p0
+ERRATA_A55_1221012				:=	1
+ERRATA_A55_1530923				:=	1
+ERRATA_A76_1073348				:=	1
+ERRATA_A76_1130799				:=	1
+ERRATA_A76_1220197				:=	1
+ERRATA_A76_1257314				:=	1
+ERRATA_A76_1262606				:=	1
+ERRATA_A76_1262888				:=	1
+ERRATA_A76_1275112				:=	1
+ERRATA_A76_1791580				:=	1
+ERRATA_A76_1165522				:=	1
+ERRATA_A76_1868343				:=	1
+ERRATA_A76_1946160				:=	1
+ERRATA_A76_2743102				:=	1
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT				:=	0
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID			:=	1
+ARM_RECOM_STATE_ID_ENC			:=	1
+PSCI_OS_INIT_MODE					:=	1
+
+COLD_BOOT_SINGLE_CPU				:=	1
+PROGRAMMABLE_RESET_ADDRESS		:=	1
+
+RESET_TO_BL31						:=	0
+
+QTI_SDI_BUILD						:=	0
+$(eval $(call assert_boolean,QTI_SDI_BUILD))
+$(eval $(call add_define,QTI_SDI_BUILD))
+
+#disable CTX_INCLUDE_AARCH32_REGS to support QCS615 gold cores
+override CTX_INCLUDE_AARCH32_REGS	:=	0
+
+# Set dynamic CVE_2018_3639 explicitly as it defaults to 0.
+# Others which are applicable: CVE_2017_5715 & CVE_2022_23960 default to 1
+DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
+
+# Enable stack protector.
+ENABLE_STACK_PROTECTOR				:=	strong
+
+
+QTI_EXTERNAL_INCLUDES	:=	-I${QTI_PLAT_PATH}/${CHIPSET}/inc			\
+				-I${QTI_PLAT_PATH}/common/inc				\
+				-I${QTI_PLAT_PATH}/common/inc/$(ARCH)			\
+				-I${QTI_PLAT_PATH}/qtiseclib/inc			\
+				-I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET}			\
+
+QTI_BL31_SOURCES	:=	$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S	\
+				$(QTI_PLAT_PATH)/common/src/pm_ps_hold.c			\
+				$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c	\
+				$(QTI_PLAT_PATH)/common/src/qti_common.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_gic_v3.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_syscall.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_topology.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_pm.c			\
+				$(QTI_PLAT_PATH)/common/src/qti_rng.c			\
+				$(QTI_PLAT_PATH)/common/src/spmi_arb.c			\
+				$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c	\
+
+
+PLAT_INCLUDES		:=	-Iinclude/plat/common/					\
+						${QTI_EXTERNAL_INCLUDES}
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}						\
+							plat/common/aarch64/crash_console_helpers.S	\
+							common/desc_image_load.c					\
+							lib/bl_aux_params/bl_aux_params.c			\
+
+include lib/coreboot/coreboot.mk
+
+#PSCI Sources.
+PSCI_SOURCES		:=	plat/common/plat_psci_common.c				\
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600	:=	1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+#Timer sources
+TIMER_SOURCES		:=	drivers/delay_timer/generic_delay_timer.c	\
+						drivers/delay_timer/delay_timer.c		\
+
+#GIC sources.
+GIC_SOURCES		:=	plat/common/plat_gicv3.c			\
+					${GICV3_SOURCES}				\
+
+CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a76.S			\
+					lib/cpus/aarch64/cortex_a55.S			\
+
+BL31_SOURCES		+=	${QTI_BL31_SOURCES}				\
+				${PSCI_SOURCES}					\
+				${GIC_SOURCES}					\
+				${TIMER_SOURCES}				\
+				${CPU_SOURCES}					\
+
+LIB_QTI_PATH	:=	${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
+
+
+# Override this on the command line to point to the qtiseclib library which
+# will be available in coreboot.org
+QTISECLIB_PATH ?=
+
+ifeq ($(QTISECLIB_PATH),)
+# if No lib then use stub implementation for qtiseclib interface
+$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
+		Please refer docs/plat/qti.rst for more details \
+		THIS FIRMWARE WILL NOT BOOT!)
+BL31_SOURCES	+=	plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+else
+# use library provided by QTISECLIB_PATH
+LDFLAGS += -L $(dir $(QTISECLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
+endif
+
diff --git a/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h
new file mode 100644
index 0000000..2dbcc83
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __QTISECLIB_DEFS_PLAT_H__
+#define __QTISECLIB_DEFS_PLAT_H__
+
+#define QTISECLIB_PLAT_CLUSTER_COUNT   1
+#define QTISECLIB_PLAT_CORE_COUNT      8
+
+#define BL31_BASE                0x86200000
+#define BL31_SIZE                0x00100000
+
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB  address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE         0x85F20000
+#define QTI_AOP_CMD_DB_SIZE         0x00020000
+
+/* Chipset specific secure interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_SEC_WDOG_BARK          (0x204)
+#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE      (0x21)
+
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC     (0xE6)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC  (0xE7)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC     (0xE8)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC  (0xE9)
+
+#define QTISECLIB_INT_ID_XPU_SEC                (0xE3)
+#define QTISECLIB_INT_ID_XPU_NON_SEC            (0xE4)
+
+//NOC INterrupt
+#define QTISECLIB_INT_ID_A1_NOC_ERROR        (0x18B)
+#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR    (0xE2)
+#define QTISECLIB_INT_ID_DC_NOC_ERROR        (0x122)
+#define QTISECLIB_INT_ID_MEM_NOC_ERROR       (0x6C) //GEM_NOC
+#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR    (0xC6)
+#define QTISECLIB_INT_ID_MMSS_NOC_ERROR      (0xBA)
+
+#endif /* __QTISECLIB_DEFS_PLAT_H__ */
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 4813949..c19eb36 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -148,6 +148,13 @@
 endif
 $(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
 
+# Support A/B switching with RPC HYPERFLASH access by default
+# Use together with https://github.com/marex/abloader .
+ifndef RCAR_RPC_HYPERFLASH_ABLOADER
+RCAR_RPC_HYPERFLASH_ABLOADER := 0
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_ABLOADER))
+
 # Process RCAR_SECURE_BOOT flag
 ifndef RCAR_SECURE_BOOT
 RCAR_SECURE_BOOT := 1
diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h
index 022bb02..84f9421 100644
--- a/plat/rockchip/common/drivers/pmu/pmu_com.h
+++ b/plat/rockchip/common/drivers/pmu/pmu_com.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,8 +32,6 @@
 };
 
 #pragma weak plat_ic_get_pending_interrupt_id
-#pragma weak pmu_power_domain_ctr
-#pragma weak check_cpu_wfie
 
 static inline uint32_t pmu_power_domain_st(uint32_t pd)
 {
diff --git a/plat/rockchip/common/include/plat_macros.S b/plat/rockchip/common/include/plat_macros.S
index 691beeb..548e3d9 100644
--- a/plat/rockchip/common/include/plat_macros.S
+++ b/plat/rockchip/common/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +23,8 @@
 
 /* Registers common to both GICv2 and GICv3 */
 gicd_pend_reg:
-	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
-		" Offset:\t\t\tvalue\n"
+	.ascii "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
+		" Offset:\t\t\tvalue\n\0"
 newline:
 	.asciz "\n"
 spacer:
diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c
index 8770b2e..0d8e8b6 100644
--- a/plat/rockchip/px30/drivers/pmu/pmu.c
+++ b/plat/rockchip/px30/drivers/pmu/pmu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -867,18 +867,6 @@
 		ERROR("Can't wait pll:%d lock\n", pll_id);
 }
 
-static inline void pll_pwr_ctr(uint32_t pll_base, uint32_t pll_id, uint32_t pd)
-{
-	mmio_write_32(pll_base + PLL_CON(1),
-		      BITS_WITH_WMASK(1, 1U, 15));
-	if (pd)
-		mmio_write_32(pll_base + PLL_CON(1),
-			      BITS_WITH_WMASK(1, 1, 14));
-	else
-		mmio_write_32(pll_base + PLL_CON(1),
-			      BITS_WITH_WMASK(0, 1, 14));
-}
-
 static inline void pll_set_mode(uint32_t pll_id, uint32_t mode)
 {
 	uint32_t val = BITS_WITH_WMASK(mode, 0x3, PLL_MODE_SHIFT(pll_id));
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.c b/plat/rockchip/rk3288/drivers/pmu/pmu.c
index 085976c..9e17cff 100644
--- a/plat/rockchip/rk3288/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,90 +36,6 @@
 	ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
 };
 
-static inline int rk3288_pmu_bus_idle(uint32_t req, uint32_t idle)
-{
-	uint32_t mask = BIT(req);
-	uint32_t idle_mask = 0;
-	uint32_t idle_target = 0;
-	uint32_t val;
-	uint32_t wait_cnt = 0;
-
-	switch (req) {
-	case bus_ide_req_gpu:
-		idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
-		idle_target = (idle << pmu_idle_ack_gpu) |
-			      (idle << pmu_idle_gpu);
-		break;
-	case bus_ide_req_core:
-		idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
-		idle_target = (idle << pmu_idle_ack_core) |
-			      (idle << pmu_idle_core);
-		break;
-	case bus_ide_req_cpup:
-		idle_mask = BIT(pmu_idle_ack_cpup) | BIT(pmu_idle_cpup);
-		idle_target = (idle << pmu_idle_ack_cpup) |
-			      (idle << pmu_idle_cpup);
-		break;
-	case bus_ide_req_bus:
-		idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
-		idle_target = (idle << pmu_idle_ack_bus) |
-			      (idle << pmu_idle_bus);
-		break;
-	case bus_ide_req_dma:
-		idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
-		idle_target = (idle << pmu_idle_ack_dma) |
-			      (idle << pmu_idle_dma);
-		break;
-	case bus_ide_req_peri:
-		idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
-		idle_target = (idle << pmu_idle_ack_peri) |
-			      (idle << pmu_idle_peri);
-		break;
-	case bus_ide_req_video:
-		idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
-		idle_target = (idle << pmu_idle_ack_video) |
-			      (idle << pmu_idle_video);
-		break;
-	case bus_ide_req_hevc:
-		idle_mask = BIT(pmu_idle_ack_hevc) | BIT(pmu_idle_hevc);
-		idle_target = (idle << pmu_idle_ack_hevc) |
-			      (idle << pmu_idle_hevc);
-		break;
-	case bus_ide_req_vio:
-		idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
-		idle_target = (pmu_idle_ack_vio) |
-			      (idle << pmu_idle_vio);
-		break;
-	case bus_ide_req_alive:
-		idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
-		idle_target = (idle << pmu_idle_ack_alive) |
-			      (idle << pmu_idle_alive);
-		break;
-	default:
-		ERROR("%s: Unsupported the idle request\n", __func__);
-		break;
-	}
-
-	val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
-	if (idle)
-		val |= mask;
-	else
-		val &= ~mask;
-
-	mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
-
-	while ((mmio_read_32(PMU_BASE +
-	       PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
-		wait_cnt++;
-		if (!(wait_cnt % MAX_WAIT_CONUT))
-			WARN("%s:st=%x(%x)\n", __func__,
-			     mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
-			     idle_mask);
-	}
-
-	return 0;
-}
-
 static bool rk3288_sleep_disable_osc(void)
 {
 	static const uint32_t reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
diff --git a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
index 3cdb7a2..49faba8 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
+++ b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -778,7 +778,7 @@
 	else if (twr_tmp <= 8)
 		twr_tmp = 8;
 	else if (twr_tmp <= 12)
-		twr_tmp = twr_tmp;
+		; /* do nothing */
 	else if (twr_tmp <= 14)
 		twr_tmp = 14;
 	else
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 32446ef..2bc87ae 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -5,20 +5,16 @@
 #
 
 include ../../../../../make_helpers/common.mk
+include ../../../../../make_helpers/build_macros.mk
 include ../../../../../make_helpers/toolchain.mk
 
-# Cross Compile
-M0_CROSS_COMPILE ?= arm-none-eabi-
-
 # Build architecture
-ARCH		:= cortex-m0
+ARCH		:= rk3399-m0
 
 # Build platform
 PLAT_M0		?= rk3399m0
 PLAT_M0_PMU	?= rk3399m0pmu
 
-.SUFFIXES:
-
 INCLUDES		+= -Iinclude/ \
 			   -I../../include/shared/
 
@@ -29,10 +25,13 @@
 C_SOURCES_PMU		:= src/suspend.c
 
 # Flags definition
-COMMON_FLAGS		:= -g -mcpu=$(ARCH) -mthumb -Wall -O3 -nostdlib -mfloat-abi=soft
+COMMON_FLAGS		:= -g -mcpu=cortex-m0 -mthumb -Wall -O3 -nostdlib -mfloat-abi=soft
 CFLAGS			:= -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-common
-ASFLAGS			:= -Wa,--gdwarf-2
-LDFLAGS			:= -Wl,--gc-sections -Wl,--build-id=none
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
+CFLAGS			+= $(call cc_option, --param=min-pagesize=0)
+ASFLAGS			:= -Wa,--gdwarf-2 -Wa,--fatal-warnings
+LDFLAGS			:= -Wl,--gc-sections -Wl,--build-id=none -Wl,--fatal-warnings -z noexecstack
+LDFLAGS			+= $(call ld_option,-Xlinker --no-warn-rwx-segments)
 
 # NOTE: The line continuation '\' is required in the next define otherwise we
 # end up with a line-feed characer at the end of the last c filename.
@@ -64,7 +63,7 @@
 
 $(OBJ) : $(2)
 	$(s)echo "  CC      $$<"
-	$$(q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
+	$$(q)$($(ARCH)-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
 endef
 
 define MAKE_S
@@ -72,7 +71,7 @@
 
 $(OBJ) : $(2)
 	$(s)echo "  AS      $$<"
-	$$(q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
 endef
 
 define MAKE_OBJS
@@ -93,20 +92,20 @@
 .DEFAULT_GOAL := all
 
 $(LINKERFILE): $(LINKERFILE_SRC)
-	$(rk3399-m0-cc) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
+	$(q)$($(ARCH)-cc) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
 -include $(LINKERFILE).d
 
 $(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
 	$(s)echo "  LD      $@"
-	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
+	$(q)$($(ARCH)-ld) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
 
 %.bin : %.elf
 	$(s)echo "  BIN     $@"
-	$(q)$(rk3399-m0-oc) -O binary $< $@
+	$(q)$($(ARCH)-oc) -O binary $< $@
 
 $(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
 	$(s)echo "  LD      $@"
-	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
+	$(q)$($(ARCH)-ld) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
 
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_COMMON),$(1)))
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1)))
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
index f693dbd..a4128b2 100644
--- a/plat/rockchip/rk3588/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
@@ -760,10 +760,10 @@
 			  "mrs	x0, S3_0_C15_C2_7\n"
 			  "orr	x0, x0, #0x1\n"
 			  "msr	S3_0_C15_C2_7, x0\n"
-			  "wfi_loop:\n"
+			  "1:\n"
 			  "isb\n"
 			  "wfi\n"
-			  "b wfi_loop\n");
+			  "b 1b\n");
 }
 
 static void nonboot_cpus_off(void)
diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h
index 8562c3d..d22fc64 100644
--- a/plat/rpi/common/include/rpi_shared.h
+++ b/plat/rpi/common/include/rpi_shared.h
@@ -52,4 +52,4 @@
 
 void plat_rpi_bl31_custom_setup(void);
 
-#endif /* RPI3_PRIVATE_H */
+#endif /* RPI3_SHARED_H */
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index 8976496..4e3c9f2 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -14,6 +14,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
 
 #include <rpi_hw.h>
 #include <rpi_shared.h>
@@ -225,3 +226,10 @@
 	/* Secure interrupts are signalled on the FIQ line always. */
 	return  __builtin_ctz(SCR_FIQ_BIT);
 }
+
+#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/rpi/common/rpi3_trusted_boot.c b/plat/rpi/common/rpi3_trusted_boot.c
index f6c669f..86a70d6 100644
--- a/plat/rpi/common/rpi3_trusted_boot.c
+++ b/plat/rpi/common/rpi3_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, 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/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index e139b49..fc51bec 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -213,11 +213,11 @@
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY): | $(BUILD_PLAT)
+    $(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-    $(ROTPK_HASH): $(ROT_KEY)
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index a5ab4f7..7a5a03c 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -25,6 +25,14 @@
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
 PLAT_PATH		:=	plat/socionext/synquacer
 PLAT_INCLUDES		:=	-I$(PLAT_PATH)/include		\
 				-I$(PLAT_PATH)/drivers/scpi	\
@@ -71,11 +79,11 @@
 $(BUILD_PLAT)/bl2/sq_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index ebb9b8c..21d95cf 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -105,11 +105,11 @@
 $(BUILD_PLAT)/bl2/uniphier_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
+$(ROT_KEY): | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
 	$(s)echo "  OPENSSL $@"
 	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index 7395a36..dc753a0 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -76,7 +77,7 @@
 
 # Variables for use with stm32image
 STM32IMAGEPATH			?=	tools/stm32image
-STM32IMAGE			?=	${STM32IMAGEPATH}/stm32image${BIN_EXT}
+STM32IMAGE			?=	${STM32IMAGEPATH}/stm32image$(.exe)
 STM32IMAGE_SRC			:=	${STM32IMAGEPATH}/stm32image.c
 STM32_DEPS			+=	${STM32IMAGE}
 
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index fba7783..690507e 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -1,12 +1,11 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # Compilation rules
 .PHONY: check_dtc_version stm32image clean_stm32image check_boot_device
-.SUFFIXES:
 
 all: check_dtc_version stm32image ${STM32_TF_STM32}
 
@@ -58,9 +57,9 @@
 tf-a-%.elf: $(PLAT)-%.o ${STM32_TF_LINKERFILE}
 	$(s)echo "  LDS     $<"
 ifeq ($($(ARCH)-ld-id),gnu-gcc)
-	$(q)$($(ARCH)-ld) -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
+	$(q)$($(ARCH)-ld) -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -no-pie -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
 else
-	$(q)$($(ARCH)-ld) -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
+	$(q)$($(ARCH)-ld) -o $@ ${STM32_TF_ELF_LDFLAGS} -no-pie -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
 endif
 
 tf-a-%.bin: tf-a-%.elf
diff --git a/plat/st/common/include/stm32mp_svc_setup.h b/plat/st/common/include/stm32mp_svc_setup.h
new file mode 100644
index 0000000..e0e0d7f
--- /dev/null
+++ b/plat/st/common/include/stm32mp_svc_setup.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_SVC_SETUP_H
+#define STM32MP_SVC_SETUP_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* Common SMC function IDs for STM32 Service queries across STM32MP paltforms */
+#define STM32_SIP_SVC_CALL_COUNT	0x8200ff00
+#define STM32_SIP_SVC_UID		0x8200ff01
+/*					0x8200ff02 is reserved */
+#define STM32_SIP_SVC_VERSION		0x8200ff03
+
+/* STM32 SiP Service Calls version numbers */
+#define STM32_SIP_SVC_VERSION_MAJOR	0x0
+#define STM32_SIP_SVC_VERSION_MINOR	0x1
+
+/* SMC error codes */
+#define STM32_SMC_OK			0x00000000U
+#define STM32_SMC_NOT_SUPPORTED		0xFFFFFFFFU
+#define STM32_SMC_FAILED		0xFFFFFFFEU
+#define STM32_SMC_INVALID_PARAMS	0xFFFFFFFDU
+
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+			  u_register_t x2, u_register_t x3,
+			  u_register_t x4, uint32_t *ret1,
+			  uint32_t *ret2, bool *ret2_enabled,
+			  u_register_t flags);
+
+#endif /* STM32MP_SVC_SETUP_H */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 1aecece..644275e 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -77,7 +77,7 @@
 #define DEFAULT_UUID_NUMBER	U(7)
 
 #ifdef __aarch64__
-#define BL31_UUID_NUMBER	U(1)
+#define BL31_UUID_NUMBER	U(2)
 #else
 #define BL31_UUID_NUMBER	U(0)
 #endif
@@ -115,6 +115,7 @@
 	{FW_CONFIG_ID, "fw_cfg_uuid"},
 #ifdef __aarch64__
 	{BL31_IMAGE_ID, "bl31_uuid"},
+	{SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
 #endif
 	{BL32_IMAGE_ID, "bl32_uuid"},
 	{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
diff --git a/plat/st/common/stm32mp_svc_setup.c b/plat/st/common/stm32mp_svc_setup.c
new file mode 100644
index 0000000..7fce896
--- /dev/null
+++ b/plat/st/common/stm32mp_svc_setup.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+#include <tools_share/uuid.h>
+
+#include <stm32mp_svc_setup.h>
+
+/* STM32 SiP Service UUID */
+DEFINE_SVC_UUID2(stm32_sip_svc_uid,
+		 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
+		 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
+
+/* Setup STM32MP Standard Services */
+static int32_t stm32mp_svc_setup(void)
+{
+	/*
+	 * PSCI is the only specification implemented as a Standard Service.
+	 * Invoke PSCI setup from here.
+	 */
+	return 0;
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will dispatch the SMC
+ * to the correct feature handler or default call a platform handler
+ */
+static uintptr_t stm32mp_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+					 u_register_t x2, u_register_t x3,
+					 u_register_t x4, void *cookie,
+					 void *handle, u_register_t flags)
+{
+	uint32_t ret1 = 0U, ret2 = 0U;
+	bool ret_uid = false, ret2_enabled = false;
+
+	switch (smc_fid) {
+	case STM32_SIP_SVC_UID:
+		/* Return UUID to the caller */
+		ret_uid = true;
+		break;
+
+	case STM32_SIP_SVC_VERSION:
+		/* Return the version of current implementation */
+		ret1 = STM32_SIP_SVC_VERSION_MAJOR;
+		ret2 = STM32_SIP_SVC_VERSION_MINOR;
+		ret2_enabled = true;
+		break;
+	default:
+		plat_svc_smc_handler(smc_fid, x1, x2, x3, x4, &ret1, &ret2, &ret2_enabled, flags);
+		break;
+	}
+
+	if (ret_uid) {
+		SMC_UUID_RET(handle, stm32_sip_svc_uid);
+	}
+
+	if (ret2_enabled) {
+		SMC_RET2(handle, ret1, ret2);
+	}
+
+	SMC_RET1(handle, ret1);
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(stm32mp_sip_svc,
+	       OEN_SIP_START,
+	       OEN_SIP_END,
+	       SMC_TYPE_FAST,
+	       stm32mp_svc_setup,
+	       stm32mp_svc_smc_handler
+);
diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h
index 52088de..ca4c88d 100644
--- a/plat/st/stm32mp1/include/stm32mp1_smc.h
+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,16 +39,6 @@
 #define STM32_SIP_SMC_SCMI_AGENT0	0x82002000
 #define STM32_SIP_SMC_SCMI_AGENT1	0x82002001
 
-/* SMC function IDs for SiP Service queries */
-#define STM32_SIP_SVC_CALL_COUNT	0x8200ff00
-#define STM32_SIP_SVC_UID		0x8200ff01
-/*					0x8200ff02 is reserved */
-#define STM32_SIP_SVC_VERSION		0x8200ff03
-
-/* STM32 SiP Service Calls version numbers */
-#define STM32_SIP_SVC_VERSION_MAJOR	0x0
-#define STM32_SIP_SVC_VERSION_MINOR	0x1
-
 /* Number of STM32 SiP Calls implemented */
 #define STM32_COMMON_SIP_NUM_CALLS	3
 
@@ -58,10 +48,4 @@
 #define STM32_SMC_WRITE_SHADOW		0x03
 #define STM32_SMC_READ_OTP		0x04
 
-/* SMC error codes */
-#define STM32_SMC_OK			0x00000000U
-#define STM32_SMC_NOT_SUPPORTED		0xFFFFFFFFU
-#define STM32_SMC_FAILED		0xFFFFFFFEU
-#define STM32_SMC_INVALID_PARAMS	0xFFFFFFFDU
-
 #endif /* STM32MP1_SMC_H */
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
index 7cc0013..418a2e5 100644
--- a/plat/st/stm32mp1/services/bsec_svc.c
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -11,6 +11,7 @@
 
 #include <platform_def.h>
 #include <stm32mp1_smc.h>
+#include <stm32mp_svc_setup.h>
 
 #include "bsec_svc.h"
 
diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
index ed8a448..6e5544d 100644
--- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2014-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,56 +14,27 @@
 #include <tools_share/uuid.h>
 
 #include <stm32mp1_smc.h>
+#include <stm32mp_svc_setup.h>
 
 #include "bsec_svc.h"
 
-/* STM32 SiP Service UUID */
-DEFINE_SVC_UUID2(stm32_sip_svc_uid,
-		 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
-		 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
-
-/* Setup STM32MP1 Standard Services */
-static int32_t stm32mp1_svc_setup(void)
-{
-	/*
-	 * PSCI is the only specification implemented as a Standard Service.
-	 * Invoke PSCI setup from here.
-	 */
-	return 0;
-}
-
 /*
- * Top-level Standard Service SMC handler. This handler will in turn dispatch
- * calls to PSCI SMC handler.
+ * Platform Standard Service SMC handler. This handler will dispatch
+ * calls to features handlers.
  */
-static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
-					  u_register_t x2, u_register_t x3,
-					  u_register_t x4, void *cookie,
-					  void *handle, u_register_t flags)
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+			  u_register_t x2, u_register_t x3,
+			  u_register_t x4, uint32_t *ret1,
+			  uint32_t *ret2, bool *ret2_enabled,
+			  u_register_t flags)
 {
-	uint32_t ret1 = 0U, ret2 = 0U;
-	bool ret_uid = false, ret2_enabled = false;
-
 	switch (smc_fid) {
 	case STM32_SIP_SVC_CALL_COUNT:
-		ret1 = STM32_COMMON_SIP_NUM_CALLS;
+		*ret1 = STM32_COMMON_SIP_NUM_CALLS;
 		break;
-
-	case STM32_SIP_SVC_UID:
-		/* Return UUID to the caller */
-		ret_uid = true;
-		break;
-
-	case STM32_SIP_SVC_VERSION:
-		/* Return the version of current implementation */
-		ret1 = STM32_SIP_SVC_VERSION_MAJOR;
-		ret2 = STM32_SIP_SVC_VERSION_MINOR;
-		ret2_enabled = true;
-		break;
-
 	case STM32_SMC_BSEC:
-		ret1 = bsec_main(x1, x2, x3, &ret2);
-		ret2_enabled = true;
+		*ret1 = bsec_main(x1, x2, x3, ret2);
+		*ret2_enabled = true;
 		break;
 
 	case STM32_SIP_SMC_SCMI_AGENT0:
@@ -75,26 +46,7 @@
 
 	default:
 		WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
-		ret1 = STM32_SMC_NOT_SUPPORTED;
+		*ret1 = STM32_SMC_NOT_SUPPORTED;
 		break;
 	}
-
-	if (ret_uid) {
-		SMC_UUID_RET(handle, stm32_sip_svc_uid);
-	}
-
-	if (ret2_enabled) {
-		SMC_RET2(handle, ret1, ret2);
-	}
-
-	SMC_RET1(handle, ret1);
 }
-
-/* Register Standard Service Calls as runtime service */
-DECLARE_RT_SVC(stm32mp1_sip_svc,
-	       OEN_SIP_START,
-	       OEN_SIP_END,
-	       SMC_TYPE_FAST,
-	       stm32mp1_svc_setup,
-	       stm32mp1_svc_smc_handler
-);
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 9695c9b..0e34848 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -45,6 +45,7 @@
 				drivers/scmi-msg/smt.c
 
 # stm32mp1 specific services
-BL32_SOURCES		+=	plat/st/stm32mp1/services/bsec_svc.c		\
+BL32_SOURCES		+=	plat/st/common/stm32mp_svc_setup.c		\
+				plat/st/stm32mp1/services/bsec_svc.c		\
 				plat/st/stm32mp1/services/stm32mp1_svc_setup.c	\
 				plat/st/stm32mp1/stm32mp1_scmi.c
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 345850b..621b784 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -280,6 +280,7 @@
 	unsigned int i;
 	const unsigned int image_ids[] = {
 		BL31_IMAGE_ID,
+		SOC_FW_CONFIG_ID,
 		BL32_IMAGE_ID,
 		BL33_IMAGE_ID,
 		HW_CONFIG_ID,
@@ -345,6 +346,7 @@
 				break;
 
 			case HW_CONFIG_ID:
+			case SOC_FW_CONFIG_ID:
 				break;
 
 			default:
@@ -383,6 +385,11 @@
 		break;
 
 	case BL33_IMAGE_ID:
+#if PSA_FWU_SUPPORT
+		stm32_fwu_set_boot_idx();
+#endif /* PSA_FWU_SUPPORT */
+		break;
+
 	default:
 		/* Do nothing in default case */
 		break;
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
index dbf1371..a7a3721 100644
--- a/plat/st/stm32mp2/bl31_plat_setup.c
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -8,12 +8,16 @@
 #include <stdint.h>
 
 #include <common/bl_common.h>
+#include <drivers/generic_delay_timer.h>
 #include <drivers/st/stm32_console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
 #include <platform_def.h>
 
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
@@ -31,6 +35,12 @@
 			BL_CODE_END - BL_CODE_BASE,
 			MT_CODE | MT_SECURE);
 
+	/*
+	 * Map soc_fw_config device tree with secure property, i.e. default region.
+	 * DDR region definitions will be finalized at BL32 level.
+	 */
+	mmap_add_region(arg1, arg1, STM32MP_SOC_FW_CONFIG_MAX_SIZE, MT_RO_DATA | MT_SECURE);
+
 #if USE_COHERENT_MEM
 	/* Map coherent memory */
 	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
@@ -40,6 +50,22 @@
 
 	configure_mmu();
 
+	ret = dt_open_and_check(arg1);
+	if (ret < 0) {
+		EARLY_ERROR("%s: failed to open DT (%d)\n", __func__, ret);
+		panic();
+	}
+
+	ret = stm32mp2_clk_init();
+	if (ret < 0) {
+		EARLY_ERROR("%s: failed init clocks (%d)\n", __func__, ret);
+		panic();
+	}
+
+	generic_delay_timer_init();
+
+	(void)stm32mp_uart_console_setup();
+
 	/*
 	 * Map upper SYSRAM where bl_params_t are stored in BL2
 	 */
@@ -60,6 +86,31 @@
 	bl_params_node_t *bl_params = params_from_bl2->head;
 
 	while (bl_params != NULL) {
+		/*
+		 * Copy BL33 entry point information.
+		 * They are stored in Secure RAM, in BL2's address space.
+		 */
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			bl33_image_ep_info = *bl_params->ep_info;
+			/*
+			 *  Check if hw_configuration is given to BL32 and
+			 *  share it to BL33
+			 */
+			if (arg2 != 0U) {
+				bl33_image_ep_info.args.arg0 = 0U;
+				bl33_image_ep_info.args.arg1 = 0U;
+				bl33_image_ep_info.args.arg2 = arg2;
+			}
+		}
+
+		if (bl_params->image_id == BL32_IMAGE_ID) {
+			bl32_image_ep_info = *bl_params->ep_info;
+
+			if (arg2 != 0U) {
+				bl32_image_ep_info.args.arg3 = arg2;
+			}
+		}
+
 		bl_params = bl_params->next_params_info;
 	}
 
@@ -73,6 +124,7 @@
 
 void bl31_plat_arch_setup(void)
 {
+	stm32mp_gic_init();
 }
 
 void bl31_platform_setup(void)
@@ -81,5 +133,27 @@
 
 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
 {
-	return NULL;
+	entry_point_info_t *next_image_info = NULL;
+
+	assert(sec_state_is_valid(type));
+
+	switch (type) {
+	case NON_SECURE:
+		next_image_info = &bl33_image_ep_info;
+		break;
+
+	case SECURE:
+		next_image_info = &bl32_image_ep_info;
+		break;
+
+	default:
+		break;
+	}
+
+	/* None of the next images on ST platforms can have 0x0 as the entrypoint */
+	if ((next_image_info == NULL) || (next_image_info->pc == 0UL)) {
+		return NULL;
+	}
+
+	return next_image_info;
 }
diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h
index b98b56d..e720c02 100644
--- a/plat/st/stm32mp2/include/platform_def.h
+++ b/plat/st/stm32mp2/include/platform_def.h
@@ -33,7 +33,7 @@
 #define PLATFORM_CORE_COUNT		U(2)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
 
-#define PLAT_MAX_PWR_LVL		U(3)
+#define PLAT_MAX_PWR_LVL		U(1)
 #define PLAT_MIN_SUSPEND_PWR_LVL	U(2)
 #define PLAT_NUM_PWR_DOMAINS		U(6)
 
diff --git a/plat/st/stm32mp2/include/stm32mp2_smc.h b/plat/st/stm32mp2/include/stm32mp2_smc.h
new file mode 100644
index 0000000..3bf6a84
--- /dev/null
+++ b/plat/st/stm32mp2/include/stm32mp2_smc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_SMC_H
+#define STM32MP2_SMC_H
+
+#define STM32_COMMON_SIP_NUM_CALLS			1U
+
+/*
+ * STM32_SIP_SMC_STGEN_SET_RATE call API
+ * This service is opened to secure world only.
+ *
+ * Argument a0: (input) SMCC ID
+ *		(output) status return code
+ * Argument a1: (input) Frequency to set (given by sender)
+ */
+#define STM32_SIP_SMC_STGEN_SET_RATE                    0x82000000
+
+#endif /* STM32MP2_SMC_H */
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index ecad0b4..8ca582e 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -10,6 +10,12 @@
 
 #include <platform_def.h>
 
+#if STM32MP_BL33_EL1
+#define BL33_MODE MODE_EL1
+#else
+#define BL33_MODE MODE_EL2
+#endif
+
 /*******************************************************************************
  * Following descriptor provides BL image/ep information that gets used
  * by BL2 to load the images and also subset of this information is
@@ -70,6 +76,21 @@
 		.next_handoff_image_id = BL32_IMAGE_ID,
 	},
 
+	/* Fill SoC FW config related information */
+	{
+		.image_id = SOC_FW_CONFIG_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
 	/* Fill BL32 related information */
 	{
 		.image_id = BL32_IMAGE_ID,
@@ -123,7 +144,7 @@
 				      VERSION_2, entry_point_info_t,
 				      NON_SECURE | EXECUTABLE),
 
-		.ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+		.ep_info.spsr = SPSR_64(BL33_MODE, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
 
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 				      VERSION_2, image_info_t,
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index c12e512..a9f8d8f 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -15,6 +15,15 @@
 PROGRAMMABLE_RESET_ADDRESS	:=	1
 BL2_IN_XIP_MEM			:=	1
 
+STM32MP_BL33_EL1		?=	1
+ifeq ($(STM32MP_BL33_EL1),1)
+INIT_UNUSED_NS_EL2		:=	1
+endif
+
+# Disable features unsupported in ARMv8.0
+ENABLE_SPE_FOR_NS		:=	0
+ENABLE_SVE_FOR_NS		:=	0
+
 # Default Device tree
 DTB_FILE_NAME			?=	stm32mp257f-ev1.dtb
 
@@ -48,6 +57,8 @@
 # Device tree
 BL2_DTSI			:=	stm32mp25-bl2.dtsi
 FDT_SOURCES			:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+BL31_DTSI			:=	stm32mp25-bl31.dtsi
+FDT_SOURCES			+=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dts,$(DTB_FILE_NAME)))
 
 # Macros and rules to build TF binary
 STM32_TF_STM32			:=	$(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
@@ -56,14 +67,20 @@
 
 STM32MP_FW_CONFIG_NAME		:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
 STM32MP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+STM32MP_SOC_FW_CONFIG		:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dtb,$(DTB_FILE_NAME)))
 ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
 STM32MP_DDR_FW_PATH		?=	drivers/st/ddr/phy/firmware/bin/stm32mp2
 STM32MP_DDR_FW_NAME		:=	${DDR_TYPE}_pmu_train.bin
 STM32MP_DDR_FW			:=	${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME}
 endif
 FDT_SOURCES			+=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
+
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+
+# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG_PAYLOAD,STM32MP_SOC_FW_CONFIG,$(STM32MP_SOC_FW_CONFIG),--soc-fw-config,$(patsubst %.dtb,%.dts,$(STM32MP_SOC_FW_CONFIG))))
+
 ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
 # Add the FW_DDR to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
@@ -78,6 +95,7 @@
 		STM32MP_DDR4_TYPE \
 		STM32MP_LPDDR4_TYPE \
 		STM32MP25 \
+		STM32MP_BL33_EL1 \
 )))
 
 $(eval $(call assert_numerics,\
@@ -100,6 +118,7 @@
 		STM32MP_DDR4_TYPE \
 		STM32MP_LPDDR4_TYPE \
 		STM32MP25 \
+		STM32MP_BL33_EL1 \
 )))
 
 # STM32MP2x is based on Cortex-A35, which is Armv8.0, and does not support BTI
@@ -183,10 +202,15 @@
 # Generic PSCI
 BL31_SOURCES			+=	plat/common/plat_psci_common.c
 
+BL31_SOURCES			+=	plat/st/common/stm32mp_svc_setup.c			\
+					plat/st/stm32mp2/services/stgen_svc.c			\
+					plat/st/stm32mp2/services/stm32mp2_svc_setup.c
+
+# Arm Archtecture services
+BL31_SOURCES			+=	services/arm_arch_svc/arm_arch_svc_setup.c
+
 # Compilation rules
 .PHONY: check_ddr_type
-.SUFFIXES:
-
 bl2: check_ddr_type
 
 check_ddr_type:
@@ -198,4 +222,9 @@
 		false; \
 	fi
 
+# Create DTB file for BL31
+${BUILD_PLAT}/fdts/%-bl31.dts: fdts/%.dts fdts/${BL31_DTSI} | $$(@D)/
+	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	@echo '#include "${BL31_DTSI}"' >> $@
+
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/services/stgen_svc.c b/plat/st/stm32mp2/services/stgen_svc.c
new file mode 100644
index 0000000..dada315
--- /dev/null
+++ b/plat/st/stm32mp2/services/stgen_svc.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "stgen_svc.h"
+#include <stm32mp2_smc.h>
+#include <stm32mp_common.h>
+#include <stm32mp_svc_setup.h>
+
+/*
+ * This function reads and applies the STGEN frequency value in the STGENC base frequency register,
+ * which is the frequency the system base counter use for our platforms.
+ */
+uint32_t stgen_svc_handler(void)
+{
+	unsigned long freq_to_set = mmio_read_32(STGEN_BASE + CNTFID_OFF);
+
+	VERBOSE("STGEN frequency set to %lu\n", freq_to_set);
+
+	/*
+	 * Update the system counter frequency according to STGEN's base
+	 * counter frequency register
+	 */
+	write_cntfrq_el0((u_register_t)freq_to_set);
+
+	/* Need to update timer with new frequency */
+	generic_delay_timer_init();
+
+	return STM32_SMC_OK;
+}
diff --git a/plat/st/stm32mp2/services/stgen_svc.h b/plat/st/stm32mp2/services/stgen_svc.h
new file mode 100644
index 0000000..98c2304
--- /dev/null
+++ b/plat/st/stm32mp2/services/stgen_svc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STGEN_SVC_H
+#define STGEN_SVC_H
+
+uint32_t stgen_svc_handler(void);
+
+#endif /* STGEN_SVC_H */
diff --git a/plat/st/stm32mp2/services/stm32mp2_svc_setup.c b/plat/st/stm32mp2/services/stm32mp2_svc_setup.c
new file mode 100644
index 0000000..1162757
--- /dev/null
+++ b/plat/st/stm32mp2/services/stm32mp2_svc_setup.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include <stm32mp2_smc.h>
+#include <stm32mp_svc_setup.h>
+
+#include "stgen_svc.h"
+
+/*
+ * Platform-level Standard Service SIP SMC handler. This handler will dispatch
+ * the SMC to the correct feature handler.
+ */
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+			  u_register_t x2, u_register_t x3,
+			  u_register_t x4, uint32_t *ret1,
+			  uint32_t *ret2, bool *ret2_enabled,
+			  u_register_t flags)
+{
+	switch (smc_fid) {
+	case STM32_SIP_SVC_CALL_COUNT:
+		*ret1 = STM32_COMMON_SIP_NUM_CALLS;
+		break;
+	case STM32_SIP_SMC_STGEN_SET_RATE:
+		if (!is_caller_secure(flags)) {
+			*ret1 = STM32_SMC_FAILED;
+			break;
+		}
+
+		*ret1 = stgen_svc_handler();
+		break;
+	default:
+		WARN("Unimplemented STM32MP2 Service Call: 0x%x\n", smc_fid);
+		*ret1 = STM32_SMC_NOT_SUPPORTED;
+		break;
+	}
+}
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 73116db..b441502 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -138,7 +138,11 @@
  * MAX_MMAP_REGIONS is usually:
  * BL stm32mp2_mmap size + mmap regions in *_plat_arch_setup
  */
+#if defined(IMAGE_BL31)
+#define MAX_MMAP_REGIONS			7
+#else
 #define MAX_MMAP_REGIONS			6
+#endif
 
 /* DTB initialization value */
 #define STM32MP_BL2_DTB_SIZE			U(0x00006000)	/* 24 KB for DTB */
@@ -166,6 +170,7 @@
 #define STM32MP_HW_CONFIG_BASE			(STM32MP_BL33_BASE + \
 						STM32MP_BL33_MAX_SIZE)
 #define STM32MP_HW_CONFIG_MAX_SIZE		U(0x40000)
+#define STM32MP_SOC_FW_CONFIG_MAX_SIZE		U(0x10000) /* 64kB for BL31 DT */
 
 /*******************************************************************************
  * STM32MP2 device/io map related constants (used for MMU)
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 7ad974f..ea9d2fc 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -10,6 +10,7 @@
 
 #include <platform_def.h>
 
+#define BKPR_FWU_INFO	48U
 #define BKPR_BOOT_MODE	96U
 
 #if defined(IMAGE_BL31)
@@ -117,6 +118,33 @@
 	return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
 }
 
+#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
+/*
+ * UART Management
+ */
+static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
+	USART1_BASE,
+	USART2_BASE,
+	USART3_BASE,
+	UART4_BASE,
+	UART5_BASE,
+	USART6_BASE,
+	UART7_BASE,
+	UART8_BASE,
+	UART9_BASE,
+};
+
+uintptr_t get_uart_address(uint32_t instance_nb)
+{
+	if ((instance_nb == 0U) ||
+	    (instance_nb > STM32MP_NB_OF_UART)) {
+		return 0U;
+	}
+
+	return stm32mp2_uart_addresses[instance_nb - 1U];
+}
+#endif
+
 uint32_t stm32mp_get_chip_version(void)
 {
 	static uint32_t rev;
@@ -301,6 +329,13 @@
 	return tamp_bkpr(BKPR_BOOT_MODE);
 }
 
+#if PSA_FWU_SUPPORT
+uintptr_t stm32_get_bkpr_fwu_info_addr(void)
+{
+	return tamp_bkpr(BKPR_FWU_INFO);
+}
+#endif /* PSA_FWU_SUPPORT */
+
 uintptr_t stm32_ddrdbg_get_base(void)
 {
 	return DDRDBG_BASE;
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 8b77050..5c6ba6b 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -1740,3 +1740,41 @@
 
 	return 0;
 }
+
+/**
+ * ti_sci_lpm_get_next_sys_mode() - Get next LPM system mode
+ *
+ * @next_mode:	pointer to a variable that will store the next mode
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode)
+{
+	struct ti_sci_msg_req_lpm_get_next_sys_mode req;
+	struct ti_sci_msg_resp_lpm_get_next_sys_mode resp;
+	struct ti_sci_xfer xfer;
+	int ret;
+
+	if (next_mode == NULL) {
+		return -EINVAL;
+	}
+
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE, 0,
+				    &req, sizeof(req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret != 0) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0) {
+		ERROR("Transfer send failed (%d)\n", ret);
+		return ret;
+	}
+
+	*next_mode = resp.mode;
+
+	return 0;
+}
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 acaca4d..06d1f8d 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -252,6 +252,11 @@
  *		@mode: Low power mode to enter.
  *		@core_resume_addr: Address that core should be resumed from
  *				   after low power transition.
+ * - ti_sci_lpm_get_next_sys_mode - Get next LPM system mode
+ *
+ * @next_mode:	pointer to a variable that will store the next mode
+ *
+ * Return: 0 if all goes well, else appropriate error message
  *
  * NOTE: for all these functions, the following are generic in nature:
  * Returns 0 for successful request, else returns corresponding error message.
@@ -259,5 +264,6 @@
 int ti_sci_enter_sleep(uint8_t proc_id,
 		       uint8_t mode,
 		       uint64_t core_resume_addr);
+int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode);
 
 #endif /* TI_SCI_H */
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 7f1c368..cc71eac 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
@@ -31,6 +31,7 @@
 
 /* Low Power Mode Requests */
 #define TI_SCI_MSG_ENTER_SLEEP		0x0301
+#define TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE 0x030d
 
 /* Clock requests */
 #define TI_SCI_MSG_SET_CLOCK_STATE	0x0100
@@ -133,6 +134,7 @@
  *		MSG_FLAG_CAPS_LPM_MCU_ONLY: MCU only LPM
  *		MSG_FLAG_CAPS_LPM_STANDBY: Standby LPM
  *		MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
+ *		MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
  *
  * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
  * providing currently available SOC/firmware capabilities. SoC that don't
@@ -145,6 +147,7 @@
 #define MSG_FLAG_CAPS_LPM_MCU_ONLY	TI_SCI_MSG_FLAG(2)
 #define MSG_FLAG_CAPS_LPM_STANDBY	TI_SCI_MSG_FLAG(3)
 #define MSG_FLAG_CAPS_LPM_PARTIAL_IO	TI_SCI_MSG_FLAG(4)
+#define MSG_FLAG_CAPS_LPM_DM_MANAGED	TI_SCI_MSG_FLAG(5)
 	uint64_t fw_caps;
 } __packed;
 
@@ -764,10 +767,35 @@
  */
 struct ti_sci_msg_req_enter_sleep {
 	struct ti_sci_msg_hdr hdr;
+#define MSG_VALUE_SLEEP_MODE_DEEP_SLEEP 0x0
 	uint8_t mode;
 	uint8_t processor_id;
 	uint32_t core_resume_lo;
 	uint32_t core_resume_hi;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_lpm_get_next_sys_mode - Request for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
+ *
+ * @hdr Generic Header
+ *
+ * This message is used to enquire DM for selected system wide low power mode.
+ */
+struct ti_sci_msg_req_lpm_get_next_sys_mode {
+	struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_lpm_get_next_sys_mode - Response for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
+ *
+ * @hdr Generic Header
+ * @mode The selected system wide low power mode.
+ *
+ * Note: If the mode selection is not yet locked, this API returns "not selected" mode.
+ */
+struct ti_sci_msg_resp_lpm_get_next_sys_mode {
+	struct ti_sci_msg_hdr hdr;
+	uint8_t mode;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index e8d73db..df49f48 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,7 +234,7 @@
 	return PSCI_E_SUCCESS;
 }
 
-static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+static void k3_pwr_domain_suspend_to_mode(const psci_power_state_t *target_state, uint8_t mode)
 {
 	unsigned int core, proc_id;
 
@@ -247,7 +247,25 @@
 
 	k3_pwr_domain_off(target_state);
 
-	ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
+	ti_sci_enter_sleep(proc_id, mode, k3_sec_entrypoint);
+}
+
+static void k3_pwr_domain_suspend_dm_managed(const psci_power_state_t *target_state)
+{
+	uint8_t mode = MSG_VALUE_SLEEP_MODE_DEEP_SLEEP;
+	int ret;
+
+	ret = ti_sci_lpm_get_next_sys_mode(&mode);
+	if (ret != 0) {
+		ERROR("Failed to fetch next system mode\n");
+	}
+
+	k3_pwr_domain_suspend_to_mode(target_state, mode);
+}
+
+static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	k3_pwr_domain_suspend_to_mode(target_state, MSG_VALUE_SLEEP_MODE_DEEP_SLEEP);
 }
 
 static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -301,6 +319,8 @@
 		k3_plat_psci_ops.pwr_domain_suspend = NULL;
 		k3_plat_psci_ops.pwr_domain_suspend_finish = NULL;
 		k3_plat_psci_ops.get_sys_suspend_power_state = NULL;
+	} else if (fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
+		k3_plat_psci_ops.pwr_domain_suspend = k3_pwr_domain_suspend_dm_managed;
 	}
 
 	*psci_ops = &k3_plat_psci_ops;
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
index 1d62f3e..d792710 100644
--- a/plat/xilinx/common/include/ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -29,7 +29,7 @@
  ********************************************************************/
 #define IPI_SECURE_MASK  (0x1U)
 #define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
-			   IPI_SECURE_MASK) ? 1 : 0)
+			   IPI_SECURE_MASK) ? true : false)
 
 /*********************************************************************
  * Struct definitions
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e..fa6021d 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -8,18 +8,30 @@
 #define PLAT_DT_UART_H
 
 #define DT_UART_DCC_COMPAT	"arm,dcc"
+#define DT_UART_CAD_COMPAT	"xlnx,zynqmp-uart"
+#define DT_UART_PL011_COMPAT	"arm,pl011"
 
-#if defined(PLAT_zynqmp)
-#define DT_UART_COMPAT	"xlnx,zynqmp-uart"
-#else
-#define DT_UART_COMPAT	"arm,pl011"
-#endif
+/* Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ */
+#define CONSOLE_NONE	0
+#define CONSOLE_CDNS	1
+#define CONSOLE_PL011   2
+#define CONSOLE_DCC	3
+
+typedef struct console_hd {
+	uint32_t clk;
+	uint32_t baud_rate;
+	uintptr_t base;
+	uint32_t console_scope;
+	uint8_t console_type;
+} console_holder;
 
 typedef struct dt_uart_info_s {
 	char compatible[30];
 	uintptr_t base;
 	uint32_t baud_rate;
-	int32_t status;
+	uint8_t console_type;
 } dt_uart_info_t;
 
 void setup_console(void);
diff --git a/plat/xilinx/common/include/plat_xfer_list.h b/plat/xilinx/common/include/plat_xfer_list.h
new file mode 100644
index 0000000..cc79a2c
--- /dev/null
+++ b/plat/xilinx/common/include/plat_xfer_list.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_XFER_LIST_H
+#define PLAT_XFER_LIST_H
+
+#include <lib/transfer_list.h>
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+				       entry_point_info_t *bl33);
+
+#endif /* PLAT_XFER_LIST_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 399d283..cc4b04d 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -70,7 +70,7 @@
 {
 	int ret = 1;
 
-	if (remote >= ipi_total || local >= ipi_total) {
+	if ((remote >= ipi_total) || (local >= ipi_total)) {
 		ret = 0;
 	}
 
@@ -90,11 +90,11 @@
 {
 	int ret = 0;
 
-	if (!is_ipi_mb_within_range(local, remote)) {
+	if (is_ipi_mb_within_range(local, remote) == 0) {
 		ret = -EINVAL;
-	} else if (IPI_IS_SECURE(local) && !is_secure) {
+	} else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
 		ret = -EPERM;
-	} else if (IPI_IS_SECURE(remote) && !is_secure) {
+	} else if (IPI_IS_SECURE(remote) && (is_secure == 0U)) {
 		ret = -EPERM;
 	} else {
 		/* To fix the misra 15.7 warning */
@@ -111,9 +111,12 @@
  */
 void ipi_mb_open(uint32_t local, uint32_t remote)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+
+	mmio_write_32(idr_offset,
 		      IPI_BIT_MASK(remote));
-	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+	mmio_write_32(isr_offset,
 		      IPI_BIT_MASK(remote));
 }
 
@@ -125,7 +128,9 @@
  */
 void ipi_mb_release(uint32_t local, uint32_t remote)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+
+	mmio_write_32(idr_offset,
 		      IPI_BIT_MASK(remote));
 }
 
@@ -142,13 +147,15 @@
 {
 	int ret = 0U;
 	uint32_t status;
+	uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
+	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
 
-	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
-	if (status & IPI_BIT_MASK(remote)) {
+	status = mmio_read_32(obr_offset);
+	if ((status & IPI_BIT_MASK(remote)) != 0U) {
 		ret |= IPI_MB_STATUS_SEND_PENDING;
 	}
-	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
-	if (status & IPI_BIT_MASK(remote)) {
+	status = mmio_read_32(isr_offset);
+	if ((status & IPI_BIT_MASK(remote)) != 0U) {
 		ret |= IPI_MB_STATUS_RECV_PENDING;
 	}
 
@@ -167,14 +174,15 @@
 void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
 {
 	uint32_t status;
+	uint64_t trig_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_TRIG_OFFSET);
+	uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
 
-	mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
+	mmio_write_32(trig_offset,
 		      IPI_BIT_MASK(remote));
-	if (is_blocking) {
+	if (is_blocking != 0U) {
 		do {
-			status = mmio_read_32(IPI_REG_BASE(local) +
-					      IPI_OBR_OFFSET);
-		} while (status & IPI_BIT_MASK(remote));
+			status = mmio_read_32(obr_offset);
+		} while ((status & IPI_BIT_MASK(remote)) != 0U);
 	}
 }
 
@@ -188,7 +196,9 @@
  */
 void ipi_mb_ack(uint32_t local, uint32_t remote)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+
+	mmio_write_32(isr_offset,
 		      IPI_BIT_MASK(remote));
 }
 
@@ -202,7 +212,9 @@
  */
 void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+
+	mmio_write_32(idr_offset,
 		      IPI_BIT_MASK(remote));
 }
 
@@ -216,6 +228,8 @@
  */
 void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
+	uint64_t ier_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IER_OFFSET);
+
+	mmio_write_32(ier_offset,
 		      IPI_BIT_MASK(remote));
 }
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 6265928..cdff3c8 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -78,8 +78,8 @@
 	uint32_t ipi_remote_id;
 	uint32_t is_secure;
 
-	ipi_local_id = x1 & UNSIGNED32_MASK;
-	ipi_remote_id = x2 & UNSIGNED32_MASK;
+	ipi_local_id = (uint32_t)(x1 & UNSIGNED32_MASK);
+	ipi_remote_id = (uint32_t)(x2 & UNSIGNED32_MASK);
 
 	/* OEN Number 48 to 63 is for Trusted App and OS
 	 * GET_SMC_OEN limits the return value of OEN number to 63 by bitwise
@@ -94,7 +94,7 @@
 
 	/* Validate IPI mailbox access */
 	ret = ipi_mb_validate(ipi_local_id, ipi_remote_id, is_secure);
-	if (ret)
+	if (ret != 0)
 		SMC_RET1(handle, ret);
 
 	switch (GET_SMC_NUM(smc_fid)) {
@@ -106,11 +106,11 @@
 		SMC_RET1(handle, 0);
 	case IPI_MAILBOX_STATUS_ENQUIRY:
 	{
-		int32_t disable_irq;
+		bool disable_interrupt;
 
-		disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
+		disable_interrupt = ((x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) != 0U);
 		ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
-		if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_irq)
+		if ((((uint32_t)ret & IPI_MB_STATUS_RECV_PENDING) > 0U) && disable_interrupt)
 			ipi_mb_disable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, ret);
 	}
@@ -118,17 +118,17 @@
 	{
 		uint32_t is_blocking;
 
-		is_blocking = (x3 & IPI_SMC_NOTIFY_BLOCK_MASK) ? 1 : 0;
+		is_blocking = ((x3 & IPI_SMC_NOTIFY_BLOCK_MASK) != 0U);
 		ipi_mb_notify(ipi_local_id, ipi_remote_id, is_blocking);
 		SMC_RET1(handle, 0);
 	}
 	case IPI_MAILBOX_ACK:
 	{
-		int32_t enable_irq;
+		bool enable_interrupt;
 
-		enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
+		enable_interrupt = ((x3 & IPI_SMC_ACK_EIRQ_MASK) != 0U);
 		ipi_mb_ack(ipi_local_id, ipi_remote_id);
-		if (enable_irq)
+		if (enable_interrupt != 0)
 			ipi_mb_enable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, 0);
 	}
diff --git a/plat/xilinx/common/plat_clkfunc.c b/plat/xilinx/common/plat_clkfunc.c
index 8a8ea7e..f7910de 100644
--- a/plat/xilinx/common/plat_clkfunc.c
+++ b/plat/xilinx/common/plat_clkfunc.c
@@ -8,6 +8,7 @@
 #include <plat/common/platform.h>
 
 #include <platform_def.h>
+#include <plat_clkfunc.h>
 #include <plat_private.h>
 
 uint32_t plat_get_syscnt_freq2(void)
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index b84912a..681226f 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -23,9 +23,64 @@
 #include <platform_def.h>
 #include <plat_private.h>
 
-static console_t console;
+#if !(CONSOLE_IS(none))
+static console_t boot_console;
+static console_holder boot_hd_console;
+#if defined(CONSOLE_RUNTIME)
+static console_t runtime_console;
+static console_holder rt_hd_console;
+#endif
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+static dt_uart_info_t dt_uart_info;
+#endif
+
+/**
+ * register_console() - Registers the uart with console list.
+ * @consoleh: Console holder structure with UART base address,
+ *  UART clock, UART buad rate, flags & console type
+ * @console: Pointer to the console information structure.
+ */
+static void register_console(const console_holder *consoleh, console_t *console)
+{
+	int32_t rc = 0;
+
+	switch (consoleh->console_type) {
+#if defined(PLAT_zynqmp)
+	case CONSOLE_CDNS:
+		rc = console_cdns_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#else
+	case CONSOLE_PL011:
+		rc = console_pl011_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#endif
+	case CONSOLE_DCC:
+		rc = console_dcc_register(console);
+		break;
+	default:
+		INFO("Invalid console type\n");
+		break;
+	}
+
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(console, consoleh->console_scope);
+}
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
 /**
  * get_baudrate() - Get the baudrate form DTB.
  * @dtb: Address of the Device Tree Blob (DTB).
@@ -103,35 +158,57 @@
  * @node: Node address in the device tree.
  * @dtb: Address of the Device Tree Blob(DTB).
  *
- * Return: On success, it returns 1; on failure, it returns an 0.
+ * Return: On success, it returns 0; on failure, it returns -1 or -FDT_ERR_NOTFOUND.
  */
-static uint32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
+static int32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
 {
 	uintptr_t base_addr;
 	const char *com;
 	int32_t ret = 0;
+	uint32_t status;
 
 	com = fdt_getprop(dtb, node, "compatible", NULL);
 	if (com != NULL) {
 		strlcpy(info->compatible, com, sizeof(info->compatible));
 	} else {
 		ERROR("Compatible property not found in DTB node\n");
-		ret  = -FDT_ERR_NOTFOUND;
+		ret = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
-	ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
-	if (ret >= 0) {
-		info->base = base_addr;
+	status = get_node_status(dtb, node);
+	if (status == 0) {
+		ERROR("Uart node is disabled in DTB\n");
+		ret = -FDT_ERR_NOTFOUND;
+		goto error;
+	}
+
+	if (strncmp(info->compatible, DT_UART_DCC_COMPAT, strlen(DT_UART_DCC_COMPAT)) != 0) {
+		ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
+		if (ret >= 0) {
+			info->base = base_addr;
+		} else {
+			ERROR("Failed to retrieve base address. Error code: %d\n", ret);
+			ret = -FDT_ERR_NOTFOUND;
+			goto error;
+		}
+
+		info->baud_rate = get_baudrate(dtb);
+
+		if (strncmp(info->compatible, DT_UART_CAD_COMPAT,
+					strlen(DT_UART_CAD_COMPAT)) == 0) {
+			info->console_type = CONSOLE_CDNS;
+		} else if (strncmp(info->compatible, DT_UART_PL011_COMPAT,
+					strlen(DT_UART_PL011_COMPAT)) == 0) {
+			info->console_type = CONSOLE_PL011;
+		} else {
+			ERROR("Incompatible uart node in DTB\n");
+			ret = -FDT_ERR_NOTFOUND;
+		}
 	} else {
-		ERROR("Failed to retrieve base address. Error code: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
-		goto error;
+		info->console_type = CONSOLE_DCC;
 	}
 
-	info->status = get_node_status(dtb, node);
-	info->baud_rate = get_baudrate(dtb);
-
 error:
 	return ret;
 }
@@ -150,194 +227,87 @@
 	ret = is_valid_dtb(dtb);
 	if (ret < 0) {
 		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	node = fdt_get_stdout_node_offset(dtb);
 	if (node < 0) {
 		ERROR("DT get stdout node failed : %d\n", node);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	ret = fdt_add_uart_info(info, node, dtb);
 	if (ret < 0) {
 		ERROR("Failed to add DT UART info: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 error:
 	return ret;
 }
-
-/**
- * check_fdt_uart_info() - Check early uart info with DTB uart info.
- * @info: Pointer to the UART information structure.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason.
- */
-static int32_t check_fdt_uart_info(dt_uart_info_t *info)
-{
-	int32_t ret = 0;
-
-	if (info->status == 0) {
-		ret = -ENODEV;
-		goto error;
-	}
-
-	if ((info->base == console.base) &&
-	   (info->baud_rate == UART_BAUDRATE) && !CONSOLE_IS(dcc)) {
-		ret = -ENODEV;
-		goto error;
-	}
-
-error:
-	return ret;
-}
-
-/**
- * console_boot_end() - Unregister the console_t instance form the console list.
- * @boot_console: Pointer to the console information structure.
- */
-static void console_boot_end(console_t *boot_console)
-{
-	if (CONSOLE_IS(dcc)) {
-		console_dcc_unregister();
-	} else {
-		console_flush();
-		(void)console_unregister(boot_console);
-	}
-}
-
-/**
- * setup_runtime_console() - Registers the runtime uart with console list.
- * @clock: UART clock.
- * @info: Pointer to the UART information structure.
- */
-static void setup_runtime_console(uint32_t clock, dt_uart_info_t *info)
-{
-	static console_t bl31_runtime_console;
-	int32_t rc;
-
-#if defined(PLAT_zynqmp)
-	rc = console_cdns_register(info->base,
-				   clock,
-				   info->baud_rate,
-				   &bl31_runtime_console);
-#else
-	rc = console_pl011_register(info->base,
-				    clock,
-				    info->baud_rate,
-				    &bl31_runtime_console);
-#endif
-	if (rc == 0) {
-		panic();
-	}
-
-	console_set_scope(&bl31_runtime_console,
-			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME |
-			  CONSOLE_FLAG_CRASH);
-}
-
-
-/**
- * runtime_console_init() - Initializes the run time console information.
- * @uart_info: Pointer to the UART information structure.
- * @bl31_boot_console: Pointer to the console information structure.
- * @clock: UART clock.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason;
- */
-static int32_t runtime_console_init(dt_uart_info_t *uart_info,
-			  console_t *bl31_boot_console,
-			  uint32_t clock)
-{
-	int32_t rc = 0;
-
-	/* Parse UART information from Device Tree Blob (DTB) */
-	rc = fdt_get_uart_info(uart_info);
-	if (rc < 0) {
-		rc = -FDT_ERR_NOTFOUND;
-		goto error;
-	}
-
-	if (strncmp(uart_info->compatible, DT_UART_COMPAT,
-		   strlen(DT_UART_COMPAT)) == 0) {
-
-		if (check_fdt_uart_info(uart_info) == 0) {
-			setup_runtime_console(clock, uart_info);
-			console_boot_end(bl31_boot_console);
-			INFO("Runtime console setup\n");
-		} else {
-			INFO("Early console and DTB console are same\n");
-		}
-	} else if (strncmp(uart_info->compatible, DT_UART_DCC_COMPAT,
-			  strlen(DT_UART_DCC_COMPAT)) == 0) {
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-		console_boot_end(bl31_boot_console);
-	} else {
-		WARN("BL31: No console device found in DT.\n");
-	}
-
-error:
-	return rc;
-}
 #endif
 
 void setup_console(void)
 {
-	int32_t rc;
-	uint32_t uart_clk = get_uart_clk();
+	/* This is hardcoded console setup just in case that DTB console fails */
+	boot_hd_console.base = (uintptr_t)UART_BASE;
+	boot_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	boot_hd_console.clk = get_uart_clk();
+	boot_hd_console.console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH;
+	boot_hd_console.console_type = UART_TYPE;
 
-#if defined(PLAT_zynqmp)
-	if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) {
-		rc = console_cdns_register(UART_BASE,
-					   uart_clk,
-					   UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
+	/* For DT code decoding uncomment console registration below */
+	/* register_console(&boot_hd_console, &boot_console); */
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+	/* Parse DTB console for UART information  */
+	if (fdt_get_uart_info(&dt_uart_info) == 0) {
+		if (CONSOLE_IS(dtb)) {
+			boot_hd_console.base = dt_uart_info.base;
+			boot_hd_console.baud_rate = dt_uart_info.baud_rate;
+			boot_hd_console.console_type = dt_uart_info.console_type;
 		}
-
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
-#else
-	if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) {
-		/* Initialize the console to provide early debug support */
-		rc = console_pl011_register((uint32_t)UART_BASE,
-					   uart_clk,
-					   (uint32_t)UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
-		}
-
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	} else {
+		ERROR("Failed to initialize DT console or console node is disabled\n");
 	}
 #endif
-	if (CONSOLE_IS(dcc)) {
-		/* Initialize the dcc console for debug */
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-	}
+
+	/* Initialize the boot console */
+	register_console(&boot_hd_console, &boot_console);
+
 	INFO("BL31: Early console setup\n");
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
-	static dt_uart_info_t uart_info = {0};
+#ifdef CONSOLE_RUNTIME
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	       (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+					!IS_TFA_IN_OCM(BL31_BASE)))
+	rt_hd_console.base = dt_uart_info.base;
+	rt_hd_console.baud_rate = dt_uart_info.baud_rate;
+	rt_hd_console.console_type = dt_uart_info.console_type;
+#else
+	rt_hd_console.base = (uintptr_t)RT_UART_BASE;
+	rt_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	rt_hd_console.console_type = RT_UART_TYPE;
+#endif
 
-	/* Initialize the runtime console using UART information from the DTB */
-	rc = runtime_console_init(&uart_info, &console, uart_clk);
-	if (rc < 0) {
-		ERROR("Failed to initialize runtime console: %d\n", rc);
+	if ((rt_hd_console.console_type == boot_hd_console.console_type) &&
+			(rt_hd_console.base == boot_hd_console.base)) {
+		console_set_scope(&boot_console,
+				CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | CONSOLE_FLAG_RUNTIME);
+		INFO("Successfully initialized runtime console\n");
+	} else {
+		rt_hd_console.clk = get_uart_clk();
+		rt_hd_console.console_scope = CONSOLE_FLAG_RUNTIME;
+
+		register_console(&rt_hd_console, &runtime_console);
+		INFO("Successfully initialized new runtime console\n");
 	}
 #endif
 }
+#else
+void setup_console(void)
+{
+}
+#endif
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 5beb765..9f829c9 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -72,11 +72,13 @@
  * Return: XBL_FLAGS_A53_0, XBL_FLAGS_A53_1, XBL_FLAGS_A53_2 or XBL_FLAGS_A53_3.
  *
  */
-static int32_t get_xbl_cpu(const struct xbl_partition *partition)
+static uint32_t get_xbl_cpu(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_CPU_MASK;
 
-	return flags >> XBL_FLAGS_CPU_SHIFT;
+	flags >>= XBL_FLAGS_CPU_SHIFT;
+
+	return (uint32_t)flags;
 }
 
 /**
@@ -86,11 +88,13 @@
  * Return: XBL_FLAGS_EL0, XBL_FLAGS_EL1, XBL_FLAGS_EL2 or XBL_FLAGS_EL3.
  *
  */
-static int32_t get_xbl_el(const struct xbl_partition *partition)
+static uint32_t get_xbl_el(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_EL_MASK;
 
-	return flags >> XBL_FLAGS_EL_SHIFT;
+	flags >>= XBL_FLAGS_EL_SHIFT;
+
+	return (uint32_t)flags;
 }
 
 /**
@@ -100,11 +104,13 @@
  * Return: XBL_FLAGS_NON_SECURE or XBL_FLAGS_SECURE.
  *
  */
-static int32_t get_xbl_ss(const struct xbl_partition *partition)
+static uint32_t get_xbl_ss(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_TZ_MASK;
 
-	return flags >> XBL_FLAGS_TZ_SHIFT;
+	flags >>= XBL_FLAGS_TZ_SHIFT;
+
+	return (uint32_t)flags;
 }
 
 /**
@@ -114,7 +120,7 @@
  * Return: SPSR_E_LITTLE or SPSR_E_BIG.
  *
  */
-static int32_t get_xbl_endian(const struct xbl_partition *partition)
+static uint32_t get_xbl_endian(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_ENDIAN_MASK;
 
@@ -134,11 +140,13 @@
  * Return: XBL_FLAGS_ESTATE_A32 or XBL_FLAGS_ESTATE_A64.
  *
  */
-static int32_t get_xbl_estate(const struct xbl_partition *partition)
+static uint32_t get_xbl_estate(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_ESTATE_MASK;
 
-	return flags >> XBL_FLAGS_ESTATE_SHIFT;
+	flags >>= XBL_FLAGS_ESTATE_SHIFT;
+
+	return flags;
 }
 
 #if defined(PLAT_versal_net)
@@ -148,11 +156,11 @@
  *
  * Return: cluster number for the partition.
  */
-static int32_t get_xbl_cluster(const struct xbl_partition *partition)
+static uint32_t get_xbl_cluster(const struct xbl_partition *partition)
 {
 	uint64_t flags = partition->flags & XBL_FLAGS_CLUSTER_MASK;
 
-	return (int32_t)(flags >> XBL_FLAGS_CLUSTER_SHIFT);
+	return (flags >> XBL_FLAGS_CLUSTER_SHIFT);
 }
 #endif /* PLAT_versal_net */
 
@@ -175,16 +183,16 @@
 {
 	const struct xbl_handoff_params *HandoffParams;
 
-	if (!handoff_addr) {
+	if (handoff_addr == 0U) {
 		WARN("BL31: No handoff structure passed\n");
 		return XBL_HANDOFF_NO_STRUCT;
 	}
 
 	HandoffParams = (struct xbl_handoff_params *)handoff_addr;
-	if ((HandoffParams->magic[0] != 'X') ||
-	    (HandoffParams->magic[1] != 'L') ||
-	    (HandoffParams->magic[2] != 'N') ||
-	    (HandoffParams->magic[3] != 'X')) {
+	if ((HandoffParams->magic[0] != (uint8_t)'X') ||
+	    (HandoffParams->magic[1] != (uint8_t)'L') ||
+	    (HandoffParams->magic[2] != (uint8_t)'N') ||
+	    (HandoffParams->magic[3] != (uint8_t)'X')) {
 		ERROR("BL31: invalid handoff structure at %" PRIx64 "\n", handoff_addr);
 		return XBL_HANDOFF_INVAL_STRUCT;
 	}
@@ -204,7 +212,7 @@
 	 */
 	for (size_t i = 0; i < HandoffParams->num_entries; i++) {
 		entry_point_info_t *image;
-		int32_t target_estate, target_secure, target_cpu;
+		uint32_t target_estate, target_secure, target_cpu;
 		uint32_t target_endianness, target_el;
 
 		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
@@ -237,8 +245,8 @@
 		}
 
 		target_secure = get_xbl_ss(&HandoffParams->partition[i]);
-		if (target_secure == XBL_FLAGS_SECURE &&
-		    target_el == XBL_FLAGS_EL2) {
+		if ((target_secure == XBL_FLAGS_SECURE) &&
+		    (target_el == XBL_FLAGS_EL2)) {
 			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
 			     target_secure, target_el);
 			continue;
@@ -251,8 +259,8 @@
 			image = bl32;
 
 			if (target_estate == XBL_FLAGS_ESTATE_A32) {
-				bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
-							 target_endianness,
+				bl32->spsr = (uint32_t)SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+							 (uint64_t)target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
 			} else {
 				bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
@@ -268,8 +276,8 @@
 					target_el = MODE32_sys;
 				}
 
-				bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
-							 target_endianness,
+				bl33->spsr = (uint32_t)SPSR_MODE32((uint64_t)target_el, SPSR_T_ARM,
+							 (uint64_t)target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
 			} else {
 				if (target_el == XBL_FLAGS_EL2) {
@@ -278,13 +286,13 @@
 					target_el = MODE_EL1;
 				}
 
-				bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
+				bl33->spsr = (uint32_t)SPSR_64((uint64_t)target_el, MODE_SP_ELX,
 						     DISABLE_ALL_EXCEPTIONS);
 			}
 		}
 
 		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
-			target_secure == XBL_FLAGS_SECURE ? "BL32" : "BL33",
+			(target_secure == XBL_FLAGS_SECURE) ? "BL32" : "BL33",
 			HandoffParams->partition[i].entry_point,
 			target_el);
 		image->pc = HandoffParams->partition[i].entry_point;
diff --git a/plat/xilinx/common/plat_xfer_list.c b/plat/xilinx/common/plat_xfer_list.c
new file mode 100644
index 0000000..eae7ce4
--- /dev/null
+++ b/plat/xilinx/common/plat_xfer_list.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/transfer_list.h>
+
+/*
+ * FIXME: This address should come from firmware before TF-A runs
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE		U(0x1200000)
+#define FW_HANDOFF_SIZE		U(0x600000)
+
+static struct transfer_list_header *tl_hdr;
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+				       entry_point_info_t *bl33)
+{
+	struct transfer_list_entry *te = NULL;
+	struct entry_point_info *ep;
+	int32_t ret;
+
+	tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
+	ret = transfer_list_check_header(tl_hdr);
+	if ((ret == TL_OPS_ALL) || (ret == TL_OPS_RO)) {
+		transfer_list_dump(tl_hdr);
+		while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
+			ep = transfer_list_entry_data(te);
+			if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
+				switch (GET_SECURITY_STATE(ep->h.attr)) {
+				case NON_SECURE:
+					*bl33 = *ep;
+					continue;
+				case SECURE:
+					*bl32 = *ep;
+					continue;
+				default:
+					ERROR("Unrecognized Image Security State %lu\n",
+					      GET_SECURITY_STATE(ep->h.attr));
+					ret = TL_OPS_NON;
+				}
+			}
+		}
+	}
+	return ret;
+}
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index e9c5f13..627266d 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -56,7 +56,8 @@
 
 	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
+		isenabler1 += (reg_num << 2);
+		uint32_t reg = mmio_read_32((uint64_t)isenabler1);
 
 		if (reg == 0U) {
 			continue;
@@ -117,7 +118,7 @@
 	module_id = (x0 & MODULE_ID_MASK) >> 8U;
 
 	//default module id is for LIBPM
-	if (module_id == 0) {
+	if (module_id == 0U) {
 		module_id = LIBPM_MODULE_ID;
 	}
 
@@ -218,7 +219,7 @@
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
 			 latency, state);
-	if (ack == IPI_BLOCKING) {
+	if (ack == (uint32_t)IPI_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 	} else {
 		return pm_ipi_send(primary_proc, payload);
@@ -273,7 +274,7 @@
 {
 	enum pm_ret_status ret = PM_RET_SUCCESS;
 	/* Return if interrupt is not from PMU */
-	if (pm_ipi_irq_status(primary_proc) == 0) {
+	if (pm_ipi_irq_status(primary_proc) == 0U) {
 		return ret;
 	}
 
@@ -306,7 +307,7 @@
 	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
 			 target, ack);
 
-	if (ack == IPI_BLOCKING) {
+	if (ack == (uint32_t)IPI_BLOCKING) {
 		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 	} else {
 		return pm_ipi_send(primary_proc, payload);
@@ -431,7 +432,7 @@
 	 * 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)) {
+	if ((module_id > 0U) && (module_id != LIBPM_MODULE_ID)) {
 		return PM_RET_SUCCESS;
 	}
 
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 425fdcb..e12e74d 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -217,6 +217,7 @@
 enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
 	size_t i;
+	size_t local_count = count;
 #if IPI_CRC_CHECK
 	uint32_t crc;
 #endif
@@ -225,8 +226,8 @@
 				IPI_BUFFER_REQ_OFFSET;
 	enum pm_ret_status ret = PM_RET_SUCCESS;
 
-	if (count > IPI_BUFFER_MAX_WORDS) {
-		count = IPI_BUFFER_MAX_WORDS;
+	if (local_count > (uint32_t)IPI_BUFFER_MAX_WORDS) {
+		local_count = IPI_BUFFER_MAX_WORDS;
 	}
 
 	for (i = 0; i < count; i++) {
@@ -240,7 +241,7 @@
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(value, 0, count);
+		memset(value, 0, local_count);
 	}
 #endif
 	return ret;
@@ -272,7 +273,7 @@
 		goto unlock;
 	}
 
-	ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
+	ret = ERROR_CODE_MASK & (uint32_t)(pm_ipi_buff_read(proc, value, count));
 
 unlock:
 	pm_ipi_lock_release();
@@ -296,7 +297,7 @@
 
 	ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
 				    proc->ipi->remote_ipi_id);
-	if (ret & IPI_MB_STATUS_RECV_PENDING) {
+	if (((uint32_t)ret & IPI_MB_STATUS_RECV_PENDING) != 0U) {
 		return 1;
 	} else {
 		return 0;
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 861c5b3..f1484d0 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -112,8 +112,9 @@
 	VERBOSE("CPU power down request received\n");
 
 	/* Send powerdown request to online secondary core(s) */
-	ret = psci_stop_other_cores(PWRDWN_WAIT_TIMEOUT, raise_pwr_down_interrupt);
-	if (ret != PSCI_E_SUCCESS) {
+	ret = psci_stop_other_cores(plat_my_core_pos(), PWRDWN_WAIT_TIMEOUT,
+				    raise_pwr_down_interrupt);
+	if (ret != (uint32_t)PSCI_E_SUCCESS) {
 		ERROR("Failed to powerdown secondary core(s)\n");
 	}
 
@@ -140,11 +141,11 @@
 	(void)plat_ic_acknowledge_interrupt();
 
 	/* Check status register for each IPI except PMC */
-	for (i = IPI_ID_APU; i <= IPI_ID_5; i++) {
+	for (i = (int32_t)IPI_ID_APU; i <= IPI_ID_5; i++) {
 		ipi_status = ipi_mb_enquire_status(IPI_ID_APU, i);
 
 		/* If any agent other than PMC has generated IPI FIQ then send SGI to mbox driver */
-		if (ipi_status & IPI_MB_STATUS_RECV_PENDING) {
+		if ((uint32_t)ipi_status & IPI_MB_STATUS_RECV_PENDING) {
 			plat_ic_raise_ns_sgi(MBOX_SGI_SHARED_IPI, read_mpidr_el1());
 			break;
 		}
@@ -152,7 +153,7 @@
 
 	/* If PMC has not generated interrupt then end ISR */
 	ipi_status = ipi_mb_enquire_status(IPI_ID_APU, IPI_ID_PMC);
-	if ((ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0) {
+	if (((uint32_t)ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0U) {
 		plat_ic_end_of_interrupt(id);
 		return 0;
 	}
@@ -160,7 +161,7 @@
 	/* Handle PMC case */
 	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
 	if (ret != PM_RET_SUCCESS) {
-		payload[0] = ret;
+		payload[0] = (uint32_t)ret;
 	}
 
 	switch (payload[0]) {
@@ -278,7 +279,7 @@
 	gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
 
 	/* Register for idle callback during force power down/restart */
-	ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+	ret = (int32_t)pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
 				   0x0U, 0x1U, SECURE_FLAG);
 	if (ret != 0) {
 		WARN("BL31: registering idle callback for restart/force power down failed\n");
@@ -428,7 +429,7 @@
 
 		ret = pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
 		if (ret != 0) {
-			result[0] = ret;
+			result[0] = (uint32_t)ret;
 		}
 
 		SMC_RET2(handle,
@@ -478,9 +479,9 @@
 	 * than other eemi calls.
 	 */
 	if (api_id == (uint32_t)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) {
+		if (((pm_arg[0] == (uint32_t)XPM_QID_CLOCK_GET_NAME) ||
+		    (pm_arg[0] == (uint32_t)XPM_QID_PINCTRL_GET_FUNCTION_NAME)) &&
+		    (ret == PM_RET_SUCCESS)) {
 			SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32U),
 				(uint64_t)buf[2] | ((uint64_t)buf[3] << 32U));
 		}
@@ -559,7 +560,7 @@
 	uint32_t security_flag = NON_SECURE_FLAG;
 	uint32_t api_id;
 	bool status = false, status_tmp = false;
-	uint64_t x[4] = {x1, x2, x3, x4};
+	const uint64_t x[4] = {x1, x2, x3, x4};
 
 	/* Handle case where PM wasn't initialized properly */
 	if (pm_up == false) {
diff --git a/plat/xilinx/common/versal.c b/plat/xilinx/common/versal.c
index 3ea022c..7c29bae 100644
--- a/plat/xilinx/common/versal.c
+++ b/plat/xilinx/common/versal.c
@@ -7,6 +7,7 @@
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
+#include <plat/common/platform.h>
 #include <services/arm_arch_svc.h>
 
 #include <plat_private.h>
@@ -59,5 +60,5 @@
  */
 int32_t plat_get_soc_revision(void)
 {
-	return (platform_id & SOC_ID_REV_MASK);
+	return (int32_t)(platform_id & SOC_ID_REV_MASK);
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 58589ad..54badf5 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -76,7 +76,7 @@
 	uint64_t tfa_handoff_addr;
 	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
-	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
+	const uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
@@ -117,7 +117,7 @@
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
-	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1U, PM_LOAD_GET_HANDOFF_PARAMS,
 			(uintptr_t)addr >> 32U, (uintptr_t)addr, max_size);
 	ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 	if (ret_status == PM_RET_SUCCESS) {
@@ -131,7 +131,7 @@
 	enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 						  &bl33_image_ep_info,
 						  tfa_handoff_addr);
-	if (ret == XBL_HANDOFF_NO_STRUCT || ret == XBL_HANDOFF_INVAL_STRUCT) {
+	if ((ret == XBL_HANDOFF_NO_STRUCT) || (ret == XBL_HANDOFF_INVAL_STRUCT)) {
 		bl31_set_default_config();
 	} else if (ret == XBL_HANDOFF_TOO_MANY_PARTS) {
 		ERROR("BL31: Error too many partitions %u\n", ret);
@@ -153,7 +153,7 @@
 	uint32_t i;
 
 	/* Validate 'handler' and 'id' parameters */
-	if (handler == NULL || index >= MAX_INTR_EL3) {
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
 		return -EINVAL;
 	}
 
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 4b2b6cf..658dc9e 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -34,6 +34,8 @@
 void plat_versal_gic_pcpu_init(void);
 void plat_versal_gic_save(void);
 void plat_versal_gic_resume(void);
+void plat_versal_gic_redistif_on(void);
+void plat_versal_gic_redistif_off(void);
 
 uint32_t versal_calc_core_pos(u_register_t mpidr);
 /*
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index c50df7e..f7149c7 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -16,15 +16,26 @@
 #define PLATFORM_VERSION_MASK          GENMASK(31U, 28U)
 
 /* number of interrupt handlers. increase as required */
-#define MAX_INTR_EL3			2
+#define MAX_INTR_EL3			2U
 /* List all consoles */
+#define VERSAL_CONSOLE_ID_none		0
 #define VERSAL_CONSOLE_ID_pl011	1
 #define VERSAL_CONSOLE_ID_pl011_0	1
 #define VERSAL_CONSOLE_ID_pl011_1	2
 #define VERSAL_CONSOLE_ID_dcc		3
+#define VERSAL_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011	1
+#define RT_CONSOLE_ID_pl011_0	1
+#define RT_CONSOLE_ID_pl011_1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
+
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* List of platforms */
 #define VERSAL_SILICON              U(0)
 #define VERSAL_SPP                  U(1)
@@ -63,14 +74,37 @@
 #define VERSAL_UART0_BASE		0xFF000000
 #define VERSAL_UART1_BASE		0xFF010000
 
-#if CONSOLE_IS(pl011) || CONSOLE_IS(dcc)
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
 # define UART_BASE	VERSAL_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
 #elif CONSOLE_IS(pl011_1)
 # define UART_BASE	VERSAL_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid VERSAL_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /*******************************************************************************
  * Platform related constants
  ******************************************************************************/
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 74c5bf3..f160563 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -77,7 +77,7 @@
 		plat_versal_gic_save();
 	}
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMC to suspend this core */
@@ -126,7 +126,7 @@
 	plat_versal_gic_cpuif_enable();
 }
 
-void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	/* Enable the gic cpu interface */
 	plat_versal_gic_pcpu_init();
@@ -146,7 +146,7 @@
 	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
 				 pm_get_shutdown_scope(), SECURE_FLAG);
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -185,7 +185,7 @@
 
 	(void)psci_cpu_off();
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -197,7 +197,7 @@
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret, fw_api_version, version_type[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -221,9 +221,9 @@
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
+	if (ret == (uint32_t)PM_RET_SUCCESS) {
+		fw_api_version = version_type[0] & 0xFFFFU;
 		if (fw_api_version >= 3U) {
 			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
 					      SECURE_FLAG);
@@ -250,7 +250,7 @@
 
 	uint32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index e65800e..7c15be0 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -85,13 +85,27 @@
 				${XLAT_TABLES_LIB_SRCS}
 
 VERSAL_CONSOLE	?=	pl011
-ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error "Please define VERSAL_CONSOLE")
 endif
 
 $(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				lib/cpus/aarch64/cortex_a72.S			\
 				common/fdt_wrappers.c                           \
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 3e44153..de2cac8 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -26,7 +26,7 @@
 #include "pm_defs.h"
 #include <versal_def.h>
 
-#define UNDEFINED_CPUID		(~0)
+#define UNDEFINED_CPUID		(~0U)
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
@@ -232,12 +232,16 @@
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
-	for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
+	uint32_t ret = UNDEFINED_CPUID;
+	uint32_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
 		if (pm_procs_all[i].node_id == nid) {
-			return i;
+			ret = i;
+			break;
 		}
 	}
-	return UNDEFINED_CPUID;
+	return ret;
 }
 
 /**
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 3c0bd63..3027946 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -68,19 +68,19 @@
  *
  * Return: Unused.
  */
-uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
-			     u_register_t x1,
-			     u_register_t x2,
-			     u_register_t x3,
-			     u_register_t x4,
-			     void *cookie,
-			     void *handle,
-			     u_register_t flags)
+static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
+				u_register_t x1,
+				u_register_t x2,
+				u_register_t x3,
+				u_register_t x4,
+				void *cookie,
+				void *handle,
+				u_register_t flags)
 {
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index 55c4198..0dd0194 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -60,11 +60,11 @@
 
 void board_detection(void)
 {
-	uint32_t version;
+	uint32_t version_type;
 
-	version = mmio_read_32(PMC_TAP_VERSION);
-	platform_id = FIELD_GET(PLATFORM_MASK, version);
-	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+	version_type = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version_type);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version_type);
 
 	if (platform_id == VERSAL_NET_QEMU_COSIM) {
 		platform_id = VERSAL_NET_QEMU;
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index ebde49f..faeeda0 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -55,7 +55,7 @@
 	bl32_image_ep_info.pc = BL32_BASE;
 	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
-	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+	bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
 					DISABLE_ALL_EXCEPTIONS);
 }
 
@@ -140,7 +140,7 @@
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 #if !(TFA_NO_PM)
-	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1U, PM_LOAD_GET_HANDOFF_PARAMS,
 			 (uintptr_t)buff >> 32U, (uintptr_t)buff, max_size);
 
 	ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
@@ -179,7 +179,7 @@
 	uint32_t i;
 
 	/* Validate 'handler' and 'id' parameters */
-	if (handler == NULL || index >= MAX_INTR_EL3) {
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
 		return -EINVAL;
 	}
 
@@ -214,7 +214,7 @@
 	}
 
 	if (handler != NULL) {
-		handler(intr_id, flags, handle, cookie);
+		(void)handler(intr_id, flags, handle, cookie);
 	}
 
 	return 0;
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index e7d234b..54f9cc9 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -12,16 +12,27 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
-#define MAX_INTR_EL3			2
+#define MAX_INTR_EL3			2U
 
 /* List all consoles */
+#define VERSAL_NET_CONSOLE_ID_none	U(0)
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
 #define VERSAL_NET_CONSOLE_ID_dcc	U(3)
+#define VERSAL_NET_CONSOLE_ID_dtb	U(4)
 
 #define CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011    1
+#define RT_CONSOLE_ID_pl011_0  1
+#define RT_CONSOLE_ID_pl011_1  2
+#define RT_CONSOLE_ID_dcc      3
+#define RT_CONSOLE_ID_dtb      4
+
+#define RT_CONSOLE_IS(con)     (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* List all platforms */
 #define VERSAL_NET_SILICON		U(0)
 #define VERSAL_NET_SPP			U(1)
@@ -138,11 +149,35 @@
 
 #define UART_BAUDRATE	115200
 
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE		VERSAL_NET_UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE		VERSAL_NET_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE            VERSAL_NET_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
-/* Default console is UART0 */
-#define UART_BASE            VERSAL_NET_UART0_BASE
+# error "invalid VERSAL_NET_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_NET_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_NET_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
 #endif
 
 /* Processor core device IDs */
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index fb2005d..9f95574 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -27,7 +27,7 @@
 
 static int32_t versal_net_pwr_domain_on(u_register_t mpidr)
 {
-	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+	int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
 	const struct pm_proc *proc;
 
 	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x\n",
@@ -42,7 +42,7 @@
 		return PSCI_E_INTERN_FAIL;
 	}
 
-	pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
+	(void)pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
 		      versal_net_sec_entry >> 32, 0, 0);
 
 	/* Clear power down request */
@@ -59,7 +59,7 @@
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret, fw_api_version, version_type[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -83,9 +83,9 @@
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
+	if (ret == (uint32_t)PM_RET_SUCCESS) {
+		fw_api_version = version_type[0] & 0xFFFFU;
 		if (fw_api_version >= 3U) {
 			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
 					      SECURE_FLAG);
@@ -130,7 +130,7 @@
 
 	(void)psci_cpu_off();
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -162,11 +162,11 @@
 		plat_arm_gic_save();
 	}
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMC to suspend this core */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_net_sec_entry,
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_net_sec_entry,
 			SECURE_FLAG);
 
 	/* TODO: disable coherency */
@@ -223,10 +223,10 @@
 static void __dead2 versal_net_system_off(void)
 {
 	/* Send the power down request to the PMC */
-	pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
+	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
 			  pm_get_shutdown_scope(), SECURE_FLAG);
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -245,9 +245,9 @@
 {
 	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
 
-	int32_t pstate = psci_get_pstate_type(power_state);
+	uint32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
@@ -257,7 +257,7 @@
 	}
 
 	/* We expect the 'state id' to be zero */
-	if (psci_get_pstate_id(power_state)) {
+	if (psci_get_pstate_id(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
diff --git a/plat/xilinx/versal_net/plat_topology.c b/plat/xilinx/versal_net/plat_topology.c
index ee756c4..4e2d36e 100644
--- a/plat/xilinx/versal_net/plat_topology.c
+++ b/plat/xilinx/versal_net/plat_topology.c
@@ -44,8 +44,8 @@
 
 	mpidr &= MPIDR_AFFINITY_MASK;
 
-	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
-	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+	cluster_id = (uint32_t)MPIDR_AFFLVL2_VAL(mpidr);
+	cpu_id = (uint32_t)MPIDR_AFFLVL1_VAL(mpidr);
 
 	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
 		return -3;
@@ -59,5 +59,5 @@
 		return -1;
 	}
 
-	return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+	return (int32_t)(cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
 }
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 40e9206..9534118 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -60,7 +60,7 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error Please define VERSAL_NET_CONSOLE)
 endif
@@ -71,6 +71,20 @@
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
 endif
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # enable assert() for release/debug builds
 ENABLE_ASSERTIONS := 1
 
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index cff400c..9b2ca6f 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -26,7 +26,7 @@
 #include "pm_client.h"
 #include <versal_net_def.h>
 
-#define UNDEFINED_CPUID		(~0)
+#define UNDEFINED_CPUID		(~0U)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
 
@@ -340,12 +340,16 @@
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
-	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
+	uint32_t ret = UNDEFINED_CPUID;
+	uint32_t i;
+
+	for (i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
 		if (pm_procs_all[i].node_id == nid) {
-			return i;
+			ret = i;
+			break;
 		}
 	}
-	return UNDEFINED_CPUID;
+	return ret;
 }
 
 /**
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index c974810..bf06e2c 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -69,7 +69,7 @@
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index b0bd8a1..1361eda 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -14,6 +14,7 @@
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
+#include <plat_arm.h>
 #include <services/arm_arch_svc.h>
 
 #include <plat_ipi.h>
@@ -41,9 +42,9 @@
 
 static uint32_t zynqmp_get_silicon_ver(void)
 {
-	static unsigned int ver;
+	static uint32_t ver;
 
-	if (!ver) {
+	if (ver == 0U) {
 		ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
 				   ZYNQMP_CSU_VERSION_OFFSET);
 		ver &= ZYNQMP_SILICON_VER_MASK;
@@ -244,8 +245,8 @@
 	ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-		if (zynqmp_devices[i].id == id &&
-		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
+		if ((zynqmp_devices[i].id == id) &&
+		    (zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))) {
 			break;
 		}
 	}
@@ -269,7 +270,7 @@
 		return zynqmp_devices[i].name;
 	}
 
-	len = strlen(zynqmp_devices[i].name) - 2;
+	len = strlen(zynqmp_devices[i].name) - 2U;
 	for (j = 0; j < strlen(name); j++) {
 		zynqmp_devices[i].name[len] = name[j];
 		len++;
@@ -299,8 +300,8 @@
 	tmp = id;
 	tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
 	       ZYNQMP_CSU_IDCODE_FAMILY_MASK;
-	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
-		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
+	maskid = (ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT) |
+		 (ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT);
 	if (tmp != maskid) {
 		ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
 		return "UNKN";
@@ -325,13 +326,14 @@
 {
 	uint32_t chip_id = zynqmp_get_silicon_ver();
 	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+	uint32_t result = (manfid | (chip_id & 0xFFFFU));
 
-	return (int32_t)(manfid | (chip_id & 0xFFFF));
+	return (int32_t)result;
 }
 
 int32_t plat_get_soc_revision(void)
 {
-	return mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
+	return (int32_t)mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
 }
 
 static uint32_t zynqmp_get_ps_ver(void)
@@ -348,7 +350,7 @@
 {
 	uint32_t ver = zynqmp_get_silicon_ver();
 	uint32_t rtl = zynqmp_get_rtl_ver();
-	char *label = "Unknown";
+	const char *label = "Unknown";
 
 	switch (ver) {
 	case ZYNQMP_CSU_VERSION_QEMU:
@@ -365,7 +367,7 @@
 	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);
+	       zynqmp_get_ps_ver(), (rtl & 0xf0U) >> 4U, rtl & 0xfU);
 }
 #else
 static inline void zynqmp_print_platform_name(void) { }
@@ -374,7 +376,7 @@
 uint32_t zynqmp_get_bootmode(void)
 {
 	uint32_t r;
-	unsigned int ret;
+	enum pm_ret_status ret;
 
 	ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
 
@@ -410,6 +412,6 @@
 	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
 		return 65000000;
 	} else {
-		return mmio_read_32(IOU_SCNTRS_BASEFREQ);
+		return mmio_read_32((uint64_t)IOU_SCNTRS_BASEFREQ);
 	}
 }
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index ede3a21..77fbb58 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -59,7 +59,7 @@
 	bl32_image_ep_info.pc = BL32_BASE;
 	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
-	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+	bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
 					  DISABLE_ALL_EXCEPTIONS);
 }
 
@@ -96,7 +96,7 @@
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
-	tfa_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
+	tfa_handoff_addr = (uint64_t)mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
 
 	if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) {
 		bl31_set_default_config();
@@ -109,10 +109,10 @@
 			panic();
 		}
 	}
-	if (bl32_image_ep_info.pc != 0) {
+	if (bl32_image_ep_info.pc != 0U) {
 		NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
 	}
-	if (bl33_image_ep_info.pc != 0) {
+	if (bl33_image_ep_info.pc != 0U) {
 		NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
 	}
 
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
index c61c92c..c39e4be 100644
--- a/plat/xilinx/zynqmp/custom_sip_svc.c
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -8,6 +8,8 @@
 #include <common/debug.h>
 #include <smccc_helpers.h>
 
+#include <custom_svc.h>
+
 uint64_t custom_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)
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2..cd3bbbc 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -10,13 +10,24 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
+#define ZYNQMP_CONSOLE_ID_none		0
 #define ZYNQMP_CONSOLE_ID_cadence	1
 #define ZYNQMP_CONSOLE_ID_cadence0	1
 #define ZYNQMP_CONSOLE_ID_cadence1	2
 #define ZYNQMP_CONSOLE_ID_dcc		3
+#define ZYNQMP_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence	1
+#define RT_CONSOLE_ID_cadence0	1
+#define RT_CONSOLE_ID_cadence1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
+
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* Default counter frequency */
 #define ZYNQMP_DEFAULT_COUNTER_FREQ	0U
 
@@ -49,9 +60,9 @@
 
 /* CRL registers and bitfields */
 #define CRL_APB_BASE			U(0xFF5E0000)
-#define CRL_APB_BOOT_MODE_USER		(CRL_APB_BASE + 0x200)
-#define CRL_APB_RESET_CTRL		(CRL_APB_BASE + 0x218)
-#define CRL_APB_RST_LPD_TOP		(CRL_APB_BASE + 0x23C)
+#define CRL_APB_BOOT_MODE_USER		(CRL_APB_BASE + U(0x200))
+#define CRL_APB_RESET_CTRL		(CRL_APB_BASE + U(0x218))
+#define CRL_APB_RST_LPD_TOP		(CRL_APB_BASE + U(0x23C))
 #define CRL_APB_BOOT_PIN_CTRL		(CRL_APB_BASE + U(0x250))
 #define CRL_APB_CLK_BASE		U(0xFF5E0020)
 
@@ -64,18 +75,15 @@
 #define CRL_APB_BOOT_PIN_MASK		(U(0xf0f) << 0)
 #define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT	U(9)
 #define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT	U(1)
-#define CRL_APB_BOOT_ENABLE_PIN_1	(U(0x1) << \
-					CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
-#define CRL_APB_BOOT_DRIVE_PIN_1	(U(0x1) << \
-					CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_ENABLE_PIN_1	(U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_DRIVE_PIN_1	(U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
 #define ZYNQMP_BOOTMODE_JTAG		U(0)
-#define ZYNQMP_ULPI_RESET_VAL_HIGH	(CRL_APB_BOOT_ENABLE_PIN_1 | \
-					 CRL_APB_BOOT_DRIVE_PIN_1)
+#define ZYNQMP_ULPI_RESET_VAL_HIGH	(CRL_APB_BOOT_ENABLE_PIN_1 | CRL_APB_BOOT_DRIVE_PIN_1)
 #define ZYNQMP_ULPI_RESET_VAL_LOW	CRL_APB_BOOT_ENABLE_PIN_1
 
 /* system counter registers and bitfields */
 #define IOU_SCNTRS_BASE			U(0xFF260000)
-#define IOU_SCNTRS_BASEFREQ		(IOU_SCNTRS_BASE + 0x20)
+#define IOU_SCNTRS_BASEFREQ		(IOU_SCNTRS_BASE + U(0x20))
 
 /* APU registers and bitfields */
 #define APU_BASE		U(0xFD5C0000)
@@ -93,11 +101,11 @@
 /* PMU registers and bitfields */
 #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)
-#define PMU_GLOBAL_REQ_PWRUP_EN		(PMU_GLOBAL_BASE + 0x118)
-#define PMU_GLOBAL_REQ_PWRUP_DIS	(PMU_GLOBAL_BASE + 0x11c)
-#define PMU_GLOBAL_REQ_PWRUP_TRIG	(PMU_GLOBAL_BASE + 0x120)
+#define PMU_GLOBAL_GEN_STORAGE6		(PMU_GLOBAL_BASE + U(0x48))
+#define PMU_GLOBAL_REQ_PWRUP_STATUS	(PMU_GLOBAL_BASE + U(0x110))
+#define PMU_GLOBAL_REQ_PWRUP_EN		(PMU_GLOBAL_BASE + U(0x118))
+#define PMU_GLOBAL_REQ_PWRUP_DIS	(PMU_GLOBAL_BASE + U(0x11c))
+#define PMU_GLOBAL_REQ_PWRUP_TRIG	(PMU_GLOBAL_BASE + U(0x120))
 
 #define PMU_GLOBAL_CNTRL_FW_IS_PRESENT	(1 << 4)
 
@@ -144,22 +152,46 @@
 #define ZYNQMP_UART0_BASE		U(0xFF000000)
 #define ZYNQMP_UART1_BASE		U(0xFF010000)
 
-#if CONSOLE_IS(cadence) || CONSOLE_IS(dcc)
+/* Boot console */
+#if CONSOLE_IS(cadence) || CONSOLE_IS(dtb)
 # define UART_BASE	ZYNQMP_UART0_BASE
+# define UART_TYPE	CONSOLE_CDNS
 #elif CONSOLE_IS(cadence1)
 # define UART_BASE	ZYNQMP_UART1_BASE
+# define UART_TYPE	CONSOLE_CDNS
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid ZYNQMP_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE	ZYNQMP_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE	ZYNQMP_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /* Must be non zero */
 #define UART_BAUDRATE		115200
 
 /* Silicon version detection */
-#define ZYNQMP_SILICON_VER_MASK		0xF000
+#define ZYNQMP_SILICON_VER_MASK		U(0xF000)
 #define ZYNQMP_SILICON_VER_SHIFT	12
 #define ZYNQMP_CSU_VERSION_SILICON	0
-#define ZYNQMP_CSU_VERSION_QEMU		3
+#define ZYNQMP_CSU_VERSION_QEMU		U(3)
 
 #define ZYNQMP_RTL_VER_MASK		0xFF0U
 #define ZYNQMP_RTL_VER_SHIFT		4
@@ -168,38 +200,32 @@
 #define ZYNQMP_PS_VER_SHIFT		0
 
 #define ZYNQMP_CSU_BASEADDR		U(0xFFCA0000)
-#define ZYNQMP_CSU_IDCODE_OFFSET	0x40U
+#define ZYNQMP_CSU_IDCODE_OFFSET	U(0x40)
 
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT	0U
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK	(0xFFFU << \
-					ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
-#define ZYNQMP_CSU_IDCODE_XILINX_ID		0x093
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT	U(0)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK	(U(0xFFF) << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID		U(0x093)
 
-#define ZYNQMP_CSU_IDCODE_SVD_SHIFT		12U
-#define ZYNQMP_CSU_IDCODE_SVD_MASK		(0x7U << \
-						 ZYNQMP_CSU_IDCODE_SVD_SHIFT)
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT	15U
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK	(0xFU << \
-					ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT	19U
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK	(0x3U << \
-					ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT		21U
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK		(0x7FU << \
-					ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY		0x23
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT		U(12)
+#define ZYNQMP_CSU_IDCODE_SVD_MASK		(0x7U << ZYNQMP_CSU_IDCODE_SVD_SHIFT)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT	U(15)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK	(U(0xF) << ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT	U(19)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK	(U(0x3) << ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT		U(21)
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK		(U(0x7F) << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY		U(0x23)
 
-#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT	28U
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK		(0xFU << \
-					ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
-#define ZYNQMP_CSU_IDCODE_REVISION		0U
+#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT	U(28)
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK		(U(0xF) << ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
+#define ZYNQMP_CSU_IDCODE_REVISION		U(0)
 
-#define ZYNQMP_CSU_VERSION_OFFSET	0x44U
+#define ZYNQMP_CSU_VERSION_OFFSET	U(0x44)
 
 /* Efuse */
 #define EFUSE_BASEADDR		U(0xFFCC0000)
 #define EFUSE_IPDISABLE_OFFSET	0x1018
-#define EFUSE_IPDISABLE_VERSION	0x1FFU
+#define EFUSE_IPDISABLE_VERSION	U(0x1FF)
 #define ZYNQMP_EFUSE_IPDISABLE_SHIFT	20
 
 /* Access control register defines */
@@ -321,11 +347,11 @@
 #define IOU_SLCR_WDT_CLK_SEL		(IOU_SLCR_BASEADDR + 0x300)
 
 /* Global general storage register base address */
-#define GGS_BASEADDR		(0xFFD80030U)
+#define GGS_BASEADDR		U(0xFFD80030)
 #define GGS_NUM_REGS		U(4)
 
 /* Persistent global general storage register base address */
-#define PGGS_BASEADDR		(0xFFD80050U)
+#define PGGS_BASEADDR		U(0xFFD80050)
 #define PGGS_NUM_REGS		U(4)
 
 /* PMU GGS4 register 4 is used for warm restart boot health status */
@@ -334,7 +360,7 @@
 #define PM_BOOT_HEALTH_STATUS_MASK		U(0x01)
 /* WDT restart scope shift and mask */
 #define RESTART_SCOPE_SHIFT			(3)
-#define RESTART_SCOPE_MASK			(0x3U << RESTART_SCOPE_SHIFT)
+#define RESTART_SCOPE_MASK			(U(0x3) << RESTART_SCOPE_SHIFT)
 
 /* AFI registers */
 #define  AFIFM6_WRCTRL		U(13)
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 1e7df05..a619359 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -32,7 +32,7 @@
 
 static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
 {
-	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+	int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
 	const struct pm_proc *proc;
 	uint32_t buff[3];
 	enum pm_ret_status ret;
@@ -58,7 +58,7 @@
 	pm_client_wakeup(proc);
 
 	/* Send request to PMU to wake up selected APU CPU core */
-	pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
+	(void)pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
 
 	return PSCI_E_SUCCESS;
 }
@@ -88,7 +88,7 @@
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0);
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0);
 }
 
 static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
@@ -105,11 +105,11 @@
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMU to suspend this core */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, state, zynqmp_sec_entry);
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, state, zynqmp_sec_entry);
 
 	/* APU is to be turned off */
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
@@ -166,10 +166,10 @@
 	plat_arm_interconnect_exit_coherency();
 
 	/* Send the power down request to the PMU */
-	pm_system_shutdown(PMF_SHUTDOWN_TYPE_SHUTDOWN,
+	(void)pm_system_shutdown((uint32_t)PMF_SHUTDOWN_TYPE_SHUTDOWN,
 			   pm_get_shutdown_scope());
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -180,10 +180,10 @@
 	plat_arm_interconnect_exit_coherency();
 
 	/* Send the system reset request to the PMU */
-	pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
+	(void)pm_system_shutdown((uint32_t)PMF_SHUTDOWN_TYPE_RESET,
 			   pm_get_shutdown_scope());
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -204,7 +204,7 @@
 		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) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
diff --git a/plat/xilinx/zynqmp/plat_topology.c b/plat/xilinx/zynqmp/plat_topology.c
index 2596650..3755513 100644
--- a/plat/xilinx/zynqmp/plat_topology.c
+++ b/plat/xilinx/zynqmp/plat_topology.c
@@ -5,6 +5,8 @@
  */
 #include <stdint.h>
 
+#include <plat/common/platform.h>
+
 static const uint8_t plat_power_domain_tree_desc[] = {1, 4};
 
 const uint8_t *plat_get_power_domain_tree_desc(void)
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index e3a979e..e7c0378 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -10,7 +10,7 @@
 
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-	if (mpidr & MPIDR_CLUSTER_MASK) {
+	if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
 		return -1;
 	}
 
@@ -18,5 +18,5 @@
 		return -1;
 	}
 
-	return zynqmp_calc_core_pos(mpidr);
+	return (int32_t)zynqmp_calc_core_pos(mpidr);
 }
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 9fdc649..5a86658 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -111,12 +111,26 @@
 				${XLAT_TABLES_LIB_SRCS}
 
 ZYNQMP_CONSOLE	?=	cadence
-ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc))
+ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc dtb none))
 else
   $(error "Please define ZYNQMP_CONSOLE")
 endif
 $(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # Build PM code as a Library
 include plat/xilinx/zynqmp/libpm.mk
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 9682e59..dbc5f13 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -110,8 +110,8 @@
 		.type = TYPE_MUX,			\
 		.offset = PERIPH_MUX_SHIFT,		\
 		.width = PERIPH_MUX_WIDTH,		\
-		.clkflags = CLK_SET_RATE_NO_REPARENT |	\
-			    CLK_IS_BASIC,		\
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
+			    CLK_IS_BASIC),		\
 		.typeflags = NA_TYPE_FLAGS,		\
 		.mult = NA_MULT,			\
 		.div = NA_DIV,				\
@@ -122,9 +122,9 @@
 		.type = TYPE_MUX,			\
 		.offset = PERIPH_MUX_SHIFT,		\
 		.width = PERIPH_MUX_WIDTH,		\
-		.clkflags = CLK_IGNORE_UNUSED |		\
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |\
 			    CLK_SET_RATE_NO_REPARENT |	\
-			    CLK_IS_BASIC,		\
+			    CLK_IS_BASIC),		\
 		.typeflags = NA_TYPE_FLAGS,		\
 		.mult = NA_MULT,			\
 		.div = NA_DIV,				\
@@ -135,10 +135,10 @@
 		.type = TYPE_DIV1,				\
 		.offset = PERIPH_DIV1_SHIFT,			\
 		.width = PERIPH_DIV1_WIDTH,			\
-		.clkflags = CLK_SET_RATE_NO_REPARENT |		\
-			    CLK_IS_BASIC,			\
-		.typeflags = CLK_DIVIDER_ONE_BASED |		\
-			     CLK_DIVIDER_ALLOW_ZERO,		\
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
+			    CLK_IS_BASIC),			\
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
+			     CLK_DIVIDER_ALLOW_ZERO),		\
 		.mult = NA_MULT,				\
 		.div = NA_DIV,					\
 	}
@@ -148,11 +148,11 @@
 		.type = TYPE_DIV2,				\
 		.offset = PERIPH_DIV2_SHIFT,			\
 		.width = PERIPH_DIV2_WIDTH,			\
-		.clkflags = CLK_SET_RATE_NO_REPARENT |		\
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
 			    CLK_SET_RATE_PARENT |		\
-			    CLK_IS_BASIC,			\
-		.typeflags = CLK_DIVIDER_ONE_BASED |		\
-			     CLK_DIVIDER_ALLOW_ZERO,		\
+			    CLK_IS_BASIC),			\
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
+			     CLK_DIVIDER_ALLOW_ZERO),		\
 		.mult = NA_MULT,				\
 		.div = NA_DIV,					\
 	}
@@ -162,11 +162,11 @@
 		.type = TYPE_DIV##id,				\
 		.offset = PERIPH_DIV##id##_SHIFT,		\
 		.width = PERIPH_DIV##id##_WIDTH,		\
-		.clkflags = CLK_IGNORE_UNUSED |			\
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |	\
 			    CLK_SET_RATE_NO_REPARENT |		\
-			    CLK_IS_BASIC,			\
-		.typeflags = CLK_DIVIDER_ONE_BASED |		\
-			     CLK_DIVIDER_ALLOW_ZERO,		\
+			    CLK_IS_BASIC),			\
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
+			     CLK_DIVIDER_ALLOW_ZERO),		\
 		.mult = NA_MULT,				\
 		.div = NA_DIV,					\
 	}
@@ -176,9 +176,9 @@
 		.type = TYPE_GATE,				\
 		.offset = PERIPH_GATE_SHIFT,			\
 		.width = PERIPH_GATE_WIDTH,			\
-		.clkflags = CLK_SET_RATE_PARENT |		\
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |	\
 			    CLK_SET_RATE_GATE |			\
-			    CLK_IS_BASIC,			\
+			    CLK_IS_BASIC),			\
 		.typeflags = NA_TYPE_FLAGS,			\
 		.mult = NA_MULT,				\
 		.div = NA_DIV,					\
@@ -189,9 +189,9 @@
 		.type = TYPE_GATE,				\
 		.offset = PERIPH_GATE_SHIFT,			\
 		.width = PERIPH_GATE_WIDTH,			\
-		.clkflags = CLK_SET_RATE_PARENT |		\
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |	\
 			    CLK_IGNORE_UNUSED |			\
-			    CLK_IS_BASIC,			\
+			    CLK_IS_BASIC),			\
 		.typeflags = NA_TYPE_FLAGS,			\
 		.mult = NA_MULT,				\
 		.div = NA_DIV,					\
@@ -253,7 +253,7 @@
 		.type = TYPE_PLL,
 		.offset = NA_SHIFT,
 		.width = NA_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT,
+		.clkflags = (uint16_t)CLK_SET_RATE_NO_REPARENT,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -265,7 +265,7 @@
 		.type = TYPE_PLL,
 		.offset = NA_SHIFT,
 		.width = NA_WIDTH,
-		.clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -277,7 +277,7 @@
 		.type = TYPE_MUX,
 		.offset = PLL_PRESRC_MUX_SHIFT,
 		.width = PLL_PRESRC_MUX_WIDTH,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = (uint16_t)CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -289,7 +289,7 @@
 		.type = TYPE_FIXEDFACTOR,
 		.offset = NA_SHIFT,
 		.width = NA_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = 1,
 		.div = 2,
@@ -301,9 +301,9 @@
 		.type = TYPE_MUX,
 		.offset = PLL_DIV2_MUX_SHIFT,
 		.width =  PLL_DIV2_MUX_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
 			    CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -315,7 +315,7 @@
 		.type = TYPE_MUX,
 		.offset = PLL_POSTSRC_MUX_SHIFT,
 		.width = PLL_POSTSRC_MUX_WIDTH,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = (uint16_t)CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -327,9 +327,9 @@
 		.type = TYPE_MUX,
 		.offset = PLL_BYPASS_MUX_SHIFT,
 		.width = PLL_BYPASS_MUX_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
 			    CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -341,7 +341,7 @@
 		.type = TYPE_MUX,
 		.offset = PERIPH_MUX_SHIFT,
 		.width = PERIPH_MUX_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -350,8 +350,8 @@
 		.type = TYPE_DIV1,
 		.offset = PERIPH_DIV1_SHIFT,
 		.width = PERIPH_DIV1_WIDTH,
-		.clkflags = CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)CLK_IS_BASIC,
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -386,9 +386,9 @@
 		.type = TYPE_MUX,
 		.offset = PERIPH_MUX_SHIFT,
 		.width = PERIPH_MUX_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT |
-			    CLK_SET_RATE_PARENT | CLK_IS_BASIC,
-		.typeflags = CLK_FRAC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
+			    CLK_SET_RATE_PARENT | CLK_IS_BASIC),
+		.typeflags = (uint16_t)CLK_FRAC,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -396,10 +396,10 @@
 		.type = TYPE_DIV1,
 		.offset = PERIPH_DIV1_SHIFT,
 		.width = PERIPH_DIV1_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
-			     CLK_FRAC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+			    CLK_IS_BASIC),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+			     CLK_FRAC),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -407,10 +407,10 @@
 		.type = TYPE_DIV2,
 		.offset = PERIPH_DIV2_SHIFT,
 		.width = PERIPH_DIV2_WIDTH,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
-			     CLK_FRAC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+			    CLK_IS_BASIC),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+			     CLK_FRAC),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -418,9 +418,9 @@
 		.type = TYPE_GATE,
 		.offset = PERIPH_GATE_SHIFT,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_GATE |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -435,8 +435,8 @@
 		.type = TYPE_GATE,
 		.offset = USB_GATE_SHIFT,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC |
-			    CLK_SET_RATE_GATE,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC |
+			    CLK_SET_RATE_GATE),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -448,8 +448,8 @@
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)CLK_IS_BASIC,
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -460,8 +460,8 @@
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -481,9 +481,9 @@
 		.type = TYPE_GATE,
 		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_IGNORE_UNUSED |
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
 			    CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -495,9 +495,9 @@
 		.type = TYPE_GATE,
 		.offset = 24,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_IGNORE_UNUSED |
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
 			    CLK_SET_RATE_PARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -509,9 +509,9 @@
 		.type = TYPE_MUX,
 		.offset = 0,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -524,8 +524,8 @@
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC | CLK_IS_CRITICAL,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_IS_BASIC | CLK_IS_CRITICAL),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -537,8 +537,8 @@
 		.type = TYPE_DIV1,
 		.offset = PERIPH_DIV1_SHIFT,
 		.width = PERIPH_DIV1_WIDTH,
-		.clkflags = CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_IS_BASIC),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -546,8 +546,8 @@
 		.type = TYPE_DIV2,
 		.offset = PERIPH_DIV2_SHIFT,
 		.width = PERIPH_DIV2_WIDTH,
-		.clkflags = CLK_IS_BASIC | CLK_SET_RATE_PARENT,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_IS_BASIC | CLK_SET_RATE_PARENT),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -555,7 +555,7 @@
 		.type = TYPE_GATE,
 		.offset = PERIPH_GATE_SHIFT,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -567,7 +567,7 @@
 		.type = TYPE_GATE,
 		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -579,7 +579,7 @@
 		.type = TYPE_GATE,
 		.offset = 26,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -592,8 +592,8 @@
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -601,9 +601,9 @@
 		.type = TYPE_DIV2,
 		.offset = 16,
 		.width = 6,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
-			    CLK_SET_RATE_PARENT,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
+			    CLK_SET_RATE_PARENT),
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -614,9 +614,9 @@
 		.type = TYPE_MUX,
 		.offset = 1,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -628,9 +628,9 @@
 		.type = TYPE_MUX,
 		.offset = 6,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -642,9 +642,9 @@
 		.type = TYPE_MUX,
 		.offset = 11,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -656,9 +656,9 @@
 		.type = TYPE_MUX,
 		.offset = 16,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -670,7 +670,7 @@
 		.type = TYPE_GATE,
 		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -682,7 +682,7 @@
 		.type = TYPE_GATE,
 		.offset = 26,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -694,9 +694,9 @@
 		.type = TYPE_MUX,
 		.offset = 20,
 		.width = 2,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -708,9 +708,9 @@
 		.type = TYPE_MUX,
 		.offset = 0,
 		.width = 7,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -722,9 +722,9 @@
 		.type = TYPE_MUX,
 		.offset = 15,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -736,9 +736,9 @@
 		.type = TYPE_MUX,
 		.offset = 7,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -750,9 +750,9 @@
 		.type = TYPE_MUX,
 		.offset = 22,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -764,8 +764,8 @@
 		.type = TYPE_GATE,
 		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_IGNORE_UNUSED |
-			    CLK_IS_BASIC,
+		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -777,9 +777,9 @@
 		.type = TYPE_MUX,
 		.offset = 0,
 		.width = 3,
-		.clkflags = CLK_SET_RATE_PARENT |
+		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
 			    CLK_SET_RATE_NO_REPARENT |
-			    CLK_IS_BASIC,
+			    CLK_IS_BASIC),
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -792,8 +792,8 @@
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.clkflags = (uint16_t)CLK_IS_BASIC,
+		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -831,7 +831,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}),
 		.nodes = &ignore_unused_pll_nodes,
-		.num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
 	},
 	[CLK_APLL_PRE_SRC] = {
 		.name = "apll_pre_src",
@@ -849,7 +849,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_pre_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
 	},
 	[CLK_APLL_HALF] = {
 		.name = "apll_half",
@@ -857,7 +857,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}),
 		.nodes = &generic_pll_half_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
 	},
 	[CLK_APLL_INT_MUX] = {
 		.name = "apll_int_mux",
@@ -869,7 +869,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_int_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
 	},
 	[CLK_APLL_POST_SRC] = {
 		.name = "apll_post_src",
@@ -887,7 +887,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_post_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
 	},
 	[CLK_APLL] = {
 		.name = "apll",
@@ -899,7 +899,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_system_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
 	},
 	[CLK_DPLL_INT] = {
 		.name = "dpll_int",
@@ -907,7 +907,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}),
 		.nodes = &generic_pll_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
 	},
 	[CLK_DPLL_PRE_SRC] = {
 		.name = "dpll_pre_src",
@@ -925,7 +925,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_pre_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
 	},
 	[CLK_DPLL_HALF] = {
 		.name = "dpll_half",
@@ -933,7 +933,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}),
 		.nodes = &generic_pll_half_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
 	},
 	[CLK_DPLL_INT_MUX] = {
 		.name = "dpll_int_mux",
@@ -945,7 +945,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_int_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
 	},
 	[CLK_DPLL_POST_SRC] = {
 		.name = "dpll_post_src",
@@ -963,7 +963,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_post_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
 	},
 	[CLK_DPLL] = {
 		.name = "dpll",
@@ -975,7 +975,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_system_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
 	},
 	[CLK_VPLL_INT] = {
 		.name = "vpll_int",
@@ -983,7 +983,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}),
 		.nodes = &ignore_unused_pll_nodes,
-		.num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
 	},
 	[CLK_VPLL_PRE_SRC] = {
 		.name = "vpll_pre_src",
@@ -1001,7 +1001,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_pre_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
 	},
 	[CLK_VPLL_HALF] = {
 		.name = "vpll_half",
@@ -1009,7 +1009,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}),
 		.nodes = &generic_pll_half_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
 	},
 	[CLK_VPLL_INT_MUX] = {
 		.name = "vpll_int_mux",
@@ -1021,7 +1021,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_int_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
 	},
 	[CLK_VPLL_POST_SRC] = {
 		.name = "vpll_post_src",
@@ -1051,7 +1051,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_system_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
 	},
 	[CLK_IOPLL_INT] = {
 		.name = "iopll_int",
@@ -1059,7 +1059,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}),
 		.nodes = &generic_pll_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
 	},
 	[CLK_IOPLL_PRE_SRC] = {
 		.name = "iopll_pre_src",
@@ -1077,7 +1077,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_pre_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
 	},
 	[CLK_IOPLL_HALF] = {
 		.name = "iopll_half",
@@ -1085,7 +1085,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}),
 		.nodes = &generic_pll_half_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
 	},
 	[CLK_IOPLL_INT_MUX] = {
 		.name = "iopll_int_mux",
@@ -1097,7 +1097,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_int_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
 	},
 	[CLK_IOPLL_POST_SRC] = {
 		.name = "iopll_post_src",
@@ -1115,7 +1115,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_post_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
 	},
 	[CLK_IOPLL] = {
 		.name = "iopll",
@@ -1127,7 +1127,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_system_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
 	},
 	[CLK_RPLL_INT] = {
 		.name = "rpll_int",
@@ -1135,7 +1135,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}),
 		.nodes = &generic_pll_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
 	},
 	[CLK_RPLL_PRE_SRC] = {
 		.name = "rpll_pre_src",
@@ -1154,7 +1154,7 @@
 		}),
 
 		.nodes = &generic_pll_pre_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
 	},
 	[CLK_RPLL_HALF] = {
 		.name = "rpll_half",
@@ -1162,7 +1162,7 @@
 		.status_reg = CRF_APB_PLL_STATUS,
 		.parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}),
 		.nodes = &generic_pll_half_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
 	},
 	[CLK_RPLL_INT_MUX] = {
 		.name = "rpll_int_mux",
@@ -1174,7 +1174,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_int_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
 	},
 	[CLK_RPLL_POST_SRC] = {
 		.name = "rpll_post_src",
@@ -1192,7 +1192,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_post_src_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
 	},
 	[CLK_RPLL] = {
 		.name = "rpll",
@@ -1204,7 +1204,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_pll_system_nodes,
-		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
 	},
 	/* Peripheral Clocks */
 	[CLK_ACPU] = {
@@ -1219,14 +1219,14 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &acpu_nodes,
-		.num_nodes = ARRAY_SIZE(acpu_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(acpu_nodes),
 	},
 	[CLK_ACPU_FULL] = {
 		.name = "acpu_full",
 		.control_reg = CRF_APB_ACPU_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &acpu_full_nodes,
@@ -1244,7 +1244,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_DBG_FPD] = {
 		.name = "dbg_fpd",
@@ -1258,7 +1258,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_DBG_TSTMP] = {
 		.name = "dbg_tstmp",
@@ -1272,7 +1272,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_nodes),
 	},
 	[CLK_DP_VIDEO_REF] = {
 		.name = "dp_video_ref",
@@ -1286,7 +1286,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &dp_audio_video_ref_nodes,
-		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
 	},
 	[CLK_DP_AUDIO_REF] = {
 		.name = "dp_audio_ref",
@@ -1300,7 +1300,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &dp_audio_video_ref_nodes,
-		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
 	},
 	[CLK_DP_STC_REF] = {
 		.name = "dp_stc_ref",
@@ -1314,7 +1314,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_DPDMA_REF] = {
 		.name = "dpdma_ref",
@@ -1328,7 +1328,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_DDR_REF] = {
 		.name = "ddr_ref",
@@ -1340,7 +1340,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &ddr_nodes,
-		.num_nodes = ARRAY_SIZE(ddr_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(ddr_nodes),
 	},
 	[CLK_GPU_REF] = {
 		.name = "gpu_ref",
@@ -1354,7 +1354,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_SATA_REF] = {
 		.name = "sata_ref",
@@ -1368,7 +1368,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_PCIE_REF] = {
 		.name = "pcie_ref",
@@ -1382,7 +1382,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_GDMA_REF] = {
 		.name = "gdma_ref",
@@ -1396,7 +1396,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_GTGREF0_REF] = {
 		.name = "gtgref0_ref",
@@ -1410,7 +1410,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_TOPSW_MAIN] = {
 		.name = "topsw_main",
@@ -1424,7 +1424,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_TOPSW_LSBUS] = {
 		.name = "topsw_lsbus",
@@ -1438,7 +1438,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_IOU_SWITCH] = {
 		.name = "iou_switch",
@@ -1452,7 +1452,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_GEM0_REF_UNGATED] = {
 		.name = "gem0_ref_ung",
@@ -1574,7 +1574,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &usb_nodes,
-		.num_nodes = ARRAY_SIZE(usb_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
 	},
 	[CLK_USB1_BUS_REF] = {
 		.name = "usb1_bus_ref",
@@ -1588,7 +1588,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &usb_nodes,
-		.num_nodes = ARRAY_SIZE(usb_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
 	},
 	[CLK_USB3_DUAL_REF] = {
 		.name = "usb3_dual_ref",
@@ -1602,7 +1602,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &usb_nodes,
-		.num_nodes = ARRAY_SIZE(usb_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
 	},
 	[CLK_QSPI_REF] = {
 		.name = "qspi_ref",
@@ -1616,7 +1616,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_SDIO0_REF] = {
 		.name = "sdio0_ref",
@@ -1630,7 +1630,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_SDIO1_REF] = {
 		.name = "sdio1_ref",
@@ -1644,7 +1644,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_UART0_REF] = {
 		.name = "uart0_ref",
@@ -1658,7 +1658,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_UART1_REF] = {
 		.name = "uart1_ref",
@@ -1672,7 +1672,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_SPI0_REF] = {
 		.name = "spi0_ref",
@@ -1686,7 +1686,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_SPI1_REF] = {
 		.name = "spi1_ref",
@@ -1700,7 +1700,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_CAN0_REF] = {
 		.name = "can0_ref",
@@ -1714,7 +1714,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_CAN1_REF] = {
 		.name = "can1_ref",
@@ -1728,7 +1728,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_NAND_REF] = {
 		.name = "nand_ref",
@@ -1742,7 +1742,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_GEM_TSU_REF] = {
 		.name = "gem_tsu_ref",
@@ -1756,7 +1756,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_DLL_REF] = {
 		.name = "dll_ref",
@@ -1768,7 +1768,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &dll_ref_nodes,
-		.num_nodes = ARRAY_SIZE(dll_ref_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(dll_ref_nodes),
 	},
 	[CLK_ADMA_REF] = {
 		.name = "adma_ref",
@@ -1782,7 +1782,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_DBG_LPD] = {
 		.name = "dbg_lpd",
@@ -1796,7 +1796,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_CPU_R5] = {
 		.name = "cpu_r5",
@@ -1810,7 +1810,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_CSU_PLL] = {
 		.name = "csu_pll",
@@ -1824,7 +1824,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_PCAP] = {
 		.name = "pcap",
@@ -1838,7 +1838,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
 	},
 	[CLK_LPD_LSBUS] = {
 		.name = "lpd_lsbus",
@@ -1852,7 +1852,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_LPD_SWITCH] = {
 		.name = "lpd_switch",
@@ -1866,7 +1866,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_unused_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
 	[CLK_I2C0_REF] = {
 		.name = "i2c0_ref",
@@ -1880,7 +1880,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_I2C1_REF] = {
 		.name = "i2c1_ref",
@@ -1894,7 +1894,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_TIMESTAMP_REF] = {
 		.name = "timestamp_ref",
@@ -1912,7 +1912,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &timestamp_ref_nodes,
-		.num_nodes = ARRAY_SIZE(timestamp_ref_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(timestamp_ref_nodes),
 	},
 	[CLK_PL0_REF] = {
 		.name = "pl0_ref",
@@ -1926,7 +1926,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &pl_nodes,
-		.num_nodes = ARRAY_SIZE(pl_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
 	},
 	[CLK_PL1_REF] = {
 		.name = "pl1_ref",
@@ -1940,7 +1940,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &pl_nodes,
-		.num_nodes = ARRAY_SIZE(pl_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
 	},
 	[CLK_PL2_REF] = {
 		.name = "pl2_ref",
@@ -1954,7 +1954,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &pl_nodes,
-		.num_nodes = ARRAY_SIZE(pl_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
 	},
 	[CLK_PL3_REF] = {
 		.name = "pl3_ref",
@@ -1968,7 +1968,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &pl_nodes,
-		.num_nodes = ARRAY_SIZE(pl_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
 	},
 	[CLK_AMS_REF] = {
 		.name = "ams_ref",
@@ -1982,7 +1982,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &generic_mux_div_div_gate_nodes,
-		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
 	},
 	[CLK_IOPLL_TO_FPD] = {
 		.name = "iopll_to_fpd",
@@ -1990,7 +1990,7 @@
 		.status_reg = 0,
 		.parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
 		.nodes = &generic_domain_crossing_nodes,
-		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
 	[CLK_RPLL_TO_FPD] = {
 		.name = "rpll_to_fpd",
@@ -1998,7 +1998,7 @@
 		.status_reg = 0,
 		.parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
 		.nodes = &rpll_to_fpd_nodes,
-		.num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(rpll_to_fpd_nodes),
 	},
 	[CLK_APLL_TO_LPD] = {
 		.name = "apll_to_lpd",
@@ -2006,7 +2006,7 @@
 		.status_reg = 0,
 		.parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
 		.nodes = &generic_domain_crossing_nodes,
-		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
 	[CLK_DPLL_TO_LPD] = {
 		.name = "dpll_to_lpd",
@@ -2014,7 +2014,7 @@
 		.status_reg = 0,
 		.parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
 		.nodes = &generic_domain_crossing_nodes,
-		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
 	[CLK_VPLL_TO_LPD] = {
 		.name = "vpll_to_lpd",
@@ -2022,7 +2022,7 @@
 		.status_reg = 0,
 		.parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
 		.nodes = &generic_domain_crossing_nodes,
-		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
 	[CLK_GEM0_TX] = {
 		.name = "gem0_tx",
@@ -2033,7 +2033,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
 	},
 	[CLK_GEM1_TX] = {
 		.name = "gem1_tx",
@@ -2044,7 +2044,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
 	},
 	[CLK_GEM2_TX] = {
 		.name = "gem2_tx",
@@ -2055,7 +2055,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
 	},
 	[CLK_GEM3_TX] = {
 		.name = "gem3_tx",
@@ -2066,7 +2066,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
 	},
 	[CLK_GEM0_RX] = {
 		.name = "gem0_rx",
@@ -2077,7 +2077,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_rx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_GEM1_RX] = {
 		.name = "gem1_rx",
@@ -2088,7 +2088,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_rx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_GEM2_RX] = {
 		.name = "gem2_rx",
@@ -2099,7 +2099,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_rx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_GEM3_RX] = {
 		.name = "gem3_rx",
@@ -2110,18 +2110,18 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_rx_nodes,
-		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_ACPU_HALF] = {
 		.name = "acpu_half",
 		.control_reg = CRF_APB_ACPU_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &acpu_half_nodes,
-		.num_nodes = ARRAY_SIZE(acpu_half_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(acpu_half_nodes),
 	},
 	[CLK_FPD_WDT] = {
 		.name = "fpd_wdt",
@@ -2133,29 +2133,29 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &wdt_nodes,
-		.num_nodes = ARRAY_SIZE(wdt_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(wdt_nodes),
 	},
 	[CLK_GPU_PP0_REF] = {
 		.name = "gpu_pp0_ref",
 		.control_reg = CRF_APB_GPU_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &gpu_pp0_nodes,
-		.num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp0_nodes),
 	},
 	[CLK_GPU_PP1_REF] = {
 		.name = "gpu_pp1_ref",
 		.control_reg = CRF_APB_GPU_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &gpu_pp1_nodes,
-		.num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp1_nodes),
 	},
 	[CLK_GEM_TSU] = {
 		.name = "gem_tsu",
@@ -2169,19 +2169,19 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &gem_tsu_nodes,
-		.num_nodes = ARRAY_SIZE(gem_tsu_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tsu_nodes),
 	},
 	[CLK_CPU_R5_CORE] = {
 		.name = "cpu_r5_core",
 		.control_reg = CRL_APB_CPU_R5_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_CPU_R5 | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_DUMMY_PARENT,
 			CLK_NA_PARENT
 		}),
 		.nodes = &cpu_r5_core_nodes,
-		.num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(cpu_r5_core_nodes),
 	},
 	[CLK_CAN0_MIO] = {
 		.name = "can0_mio",
@@ -2209,7 +2209,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &can0_nodes,
-		.num_nodes = ARRAY_SIZE(can0_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(can0_nodes),
 	},
 	[CLK_CAN1] = {
 		.name = "can1",
@@ -2221,7 +2221,7 @@
 			CLK_NA_PARENT
 		}),
 		.nodes = &can1_nodes,
-		.num_nodes = ARRAY_SIZE(can1_nodes),
+		.num_nodes = (uint8_t)ARRAY_SIZE(can1_nodes),
 	},
 	[CLK_LPD_WDT] = {
 		.name = "lpd_wdt",
@@ -2455,15 +2455,17 @@
  */
 void pm_api_clock_get_name(uint32_t clock_id, char *name)
 {
-	if (clock_id == CLK_MAX) {
-		memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
-					 CLK_NAME_LEN : sizeof(END_OF_CLK));
+	uint32_t clock_id_num = clock_id;
+
+	if (clock_id_num == CLK_MAX) {
+		(void)memcpy(name, END_OF_CLK, ((sizeof(END_OF_CLK) > CLK_NAME_LEN) ?
+					 CLK_NAME_LEN : sizeof(END_OF_CLK)));
 	} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
-		memset(name, 0, CLK_NAME_LEN);
-	} else if (clock_id < CLK_MAX_OUTPUT_CLK) {
-		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
+		(void)memset(name, 0, CLK_NAME_LEN);
+	} else if (clock_id_num < (uint32_t)CLK_MAX_OUTPUT_CLK) {
+		(void)memcpy(name, clocks[clock_id_num].name, CLK_NAME_LEN);
 	} else {
-		memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
+		(void)memcpy(name, ext_clocks[clock_id_num - (uint32_t)CLK_MAX_OUTPUT_CLK].name,
 		       CLK_NAME_LEN);
 	}
 }
@@ -2486,7 +2488,7 @@
 					     uint32_t index,
 					     uint32_t *topology)
 {
-	struct pm_clock_node *clock_nodes;
+	const struct pm_clock_node *clock_nodes;
 	uint8_t num_nodes;
 	uint32_t i;
 	uint16_t typeflags;
@@ -2499,7 +2501,7 @@
 		return PM_RET_ERROR_NOTSUPPORTED;
 	}
 
-	memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
+	(void)memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
 	clock_nodes = *clocks[clock_id].nodes;
 	num_nodes = clocks[clock_id].num_nodes;
 
@@ -2514,13 +2516,13 @@
 		}
 
 		topology[i] = clock_nodes[index + i].type;
-		topology[i] |= clock_nodes[index + i].clkflags <<
-					CLK_CLKFLAGS_SHIFT;
+		topology[i] |= ((uint32_t)clock_nodes[index + i].clkflags <<
+					CLK_CLKFLAGS_SHIFT);
 		typeflags = clock_nodes[index + i].typeflags;
-		topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
-					CLK_TYPEFLAGS_SHIFT;
-		topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
-				(CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT);
+		topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
+					CLK_TYPEFLAGS_SHIFT);
+		topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
+				(CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT));
 	}
 
 	return PM_RET_SUCCESS;
@@ -2543,7 +2545,7 @@
 						       uint32_t *mul,
 						       uint32_t *div)
 {
-	struct pm_clock_node *clock_nodes;
+	const struct pm_clock_node *clock_nodes;
 	uint8_t num_nodes;
 	uint32_t type, i;
 
@@ -2598,7 +2600,7 @@
 					    uint32_t *parents)
 {
 	uint32_t i;
-	int32_t *clk_parents;
+	const int32_t *clk_parents;
 
 	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
@@ -2613,7 +2615,7 @@
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
+	(void)memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
 
 	/* Skip parent till index */
 	for (i = 0; i < index; i++) {
@@ -2623,7 +2625,7 @@
 	}
 
 	for (i = 0; i < 3U; i++) {
-		parents[i] = clk_parents[index + i];
+		parents[i] = (uint32_t)clk_parents[index + i];
 		if (clk_parents[index + i] == CLK_NA_PARENT) {
 			break;
 		}
@@ -2646,7 +2648,7 @@
 enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
 					       uint32_t *attr)
 {
-	if (clock_id >= CLK_MAX) {
+	if (clock_id >= (uint32_t)CLK_MAX) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2675,7 +2677,7 @@
 						uint32_t *max_div)
 {
 	uint32_t i;
-	struct pm_clock_node *nodes;
+	const struct pm_clock_node *nodes;
 
 	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
 		return PM_RET_ERROR_ARGS;
@@ -2684,11 +2686,12 @@
 	nodes = *clocks[clock_id].nodes;
 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
 		if (nodes[i].type == div_type) {
-			if (CLK_DIVIDER_POWER_OF_TWO &
-					nodes[i].typeflags) {
-				*max_div = (1U << (BIT(nodes[i].width) - 1U));
+			if ((CLK_DIVIDER_POWER_OF_TWO &
+						nodes[i].typeflags) != 0U) {
+				*max_div = (((uint32_t)1U <<
+						((uint32_t)BIT(nodes[i].width) - (uint32_t)1U)));
 			} else {
-				*max_div = BIT(nodes[i].width) - 1U;
+				*max_div = (uint32_t)BIT(nodes[i].width) - (uint32_t)1U;
 			}
 			return PM_RET_SUCCESS;
 		}
@@ -2789,9 +2792,9 @@
 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
 					    enum pm_node_id *node_id)
 {
-	struct pm_pll *pll = pm_clock_get_pll(clock_id);
+	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (pll) {
+	if (pll != NULL) {
 		*node_id = pll->nid;
 		return PM_RET_SUCCESS;
 	}
@@ -2812,10 +2815,10 @@
 	uint32_t i;
 
 	for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
-		if (pm_plls[i].pre_src == clock_id ||
-		    pm_plls[i].post_src == clock_id ||
-		    pm_plls[i].div2 == clock_id ||
-		    pm_plls[i].bypass == clock_id) {
+		if ((pm_plls[i].pre_src == clock_id) ||
+		    (pm_plls[i].post_src == clock_id) ||
+		    (pm_plls[i].div2 == clock_id) ||
+		    (pm_plls[i].bypass == clock_id)) {
 			return &pm_plls[i];
 		}
 	}
@@ -2883,7 +2886,7 @@
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if ((pll == NULL) || !state) {
+	if ((pll == NULL) || (state == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2990,10 +2993,10 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if ((pll == NULL) || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
+	if ((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE))) {
 		return PM_RET_ERROR_ARGS;
 	}
-	pll->mode = mode;
+	pll->mode = (uint8_t)mode;
 
 	return PM_RET_SUCCESS;
 }
@@ -3011,9 +3014,9 @@
 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
 					 uint32_t *mode)
 {
-	struct pm_pll *pll = pm_clock_get_pll(clock_id);
+	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if ((pll == NULL) || !mode) {
+	if ((pll == NULL) || (mode == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 	*mode = pll->mode;
@@ -3052,9 +3055,9 @@
 uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
 {
 	uint32_t i;
-	struct pm_clock_node *nodes;
+	const struct pm_clock_node *nodes;
 
-	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
+	if (clock_id >= (uint32_t)CLK_MAX_OUTPUT_CLK) {
 		return 0;
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index dd21499..a8404ba 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -62,7 +62,7 @@
 {
 	uint32_t 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) != 0U) {
 		return PM_RET_ERROR_ACCESS;
 	}
 
@@ -165,8 +165,8 @@
 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
 						       uint32_t value)
 {
-	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
-	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
+	if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
+	     (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -266,7 +266,7 @@
 
 	if (type == PM_TAPDELAY_INPUT) {
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
-				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
+				    (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
 
 		if (ret != PM_RET_SUCCESS) {
@@ -275,12 +275,12 @@
 
 		if (value == 0U) {
 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
-					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
+					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
 					     shift), 0);
 		} else {
 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
-					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
-					    shift), (ZYNQMP_SD_ITAPDLYENA <<
+					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
+					    shift), (uint64_t)(ZYNQMP_SD_ITAPDLYENA <<
 					    shift));
 		}
 
@@ -289,7 +289,7 @@
 		}
 
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
-				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
+				    (uint64_t)(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
 				    (value << shift));
 
 		if (ret != PM_RET_SUCCESS) {
@@ -297,17 +297,17 @@
 		}
 
 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
-				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
+				    (uint64_t)(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);
+				    (uint64_t)(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
 
 		if (ret != PM_RET_SUCCESS) {
 			goto reset_release;
 		}
 
 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
-				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
+				    (uint64_t)(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
 				    (value << shift));
 	} else {
 		ret = PM_RET_ERROR_ARGS;
@@ -422,7 +422,7 @@
 		return PM_RET_ERROR_ARGS;
 	}
 
-	return pm_mmio_write(GGS_BASEADDR + (index << 2),
+	return pm_mmio_write((uint64_t)(GGS_BASEADDR + (index << 2)),
 			     0xFFFFFFFFU, value);
 }
 
@@ -444,7 +444,7 @@
 		return PM_RET_ERROR_ARGS;
 	}
 
-	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
+	return pm_mmio_read((uint64_t)(GGS_BASEADDR + (index << 2)), value);
 }
 
 /**
@@ -465,7 +465,7 @@
 		return PM_RET_ERROR_ARGS;
 	}
 
-	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
+	return pm_mmio_write((uint64_t)(PGGS_BASEADDR + (index << 2)),
 			     0xFFFFFFFFU, value);
 }
 
@@ -481,7 +481,7 @@
 					      uint32_t value)
 {
 	uint32_t mask;
-	uint32_t regarr[] = {0xFD360000U,
+	const uint32_t regarr[] = {0xFD360000U,
 				0xFD360014U,
 				0xFD370000U,
 				0xFD370014U,
@@ -530,7 +530,7 @@
 		return PM_RET_ERROR_ARGS;
 	}
 
-	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
+	return pm_mmio_read((uint64_t)(PGGS_BASEADDR + (index << 2)), value);
 }
 
 /**
@@ -682,7 +682,7 @@
  */
 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
 {
-	uint8_t supported_ids[] = {
+	const uint8_t supported_ids[] = {
 		IOCTL_GET_RPU_OPER_MODE,
 		IOCTL_SET_RPU_OPER_MODE,
 		IOCTL_RPU_BOOT_ADDR_CONFIG,
@@ -703,7 +703,7 @@
 		IOCTL_AFI,
 	};
 	uint8_t i, ioctl_id;
-	int32_t ret;
+	enum pm_ret_status ret;
 
 	for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
 		ioctl_id = supported_ids[i];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 2d8c23b..763d9fa 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1991,7 +1991,7 @@
 enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
 						      uint32_t *ngroups)
 {
-	if (fid >= MAX_FUNCTION) {
+	if (fid >= (uint32_t)MAX_FUNCTION) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2011,10 +2011,10 @@
  */
 void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
 {
-	if (fid >= MAX_FUNCTION) {
-		memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
+	if (fid >= (uint32_t)MAX_FUNCTION) {
+		(void)memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
 	} else {
-		memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+		(void)memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
 	}
 }
 
@@ -2045,11 +2045,11 @@
 	uint16_t end_of_grp_offset;
 	uint16_t i;
 
-	if (fid >= MAX_FUNCTION) {
+	if (fid >= (uint32_t)MAX_FUNCTION) {
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+	(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = pinctrl_functions[fid].group_base;
 	end_of_grp_offset = grps + pinctrl_functions[fid].group_size;
@@ -2058,7 +2058,7 @@
 		if ((grps + index + i) >= end_of_grp_offset) {
 			break;
 		}
-		groups[i] = (grps + index + i);
+		groups[i] = (uint16_t)(grps + index + i);
 	}
 
 	return PM_RET_SUCCESS;
@@ -2088,13 +2088,13 @@
 						 uint16_t *groups)
 {
 	uint32_t i;
-	uint16_t *grps;
+	const uint16_t *grps;
 
-	if (pin >= MAX_PIN) {
+	if (pin >= (uint32_t)MAX_PIN) {
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+	(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = *zynqmp_pin_groups[pin].groups;
 	if (grps == NULL) {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 9d0e2c4..9882e30 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -46,22 +46,22 @@
 /* Order in pm_procs_all array must match cpu ids */
 static const struct pm_proc pm_procs_all[] = {
 	{
-		.node_id = NODE_APU_0,
+		.node_id = (uint32_t)NODE_APU_0,
 		.pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
 		.ipi = &apu_ipi,
 	},
 	{
-		.node_id = NODE_APU_1,
+		.node_id = (uint32_t)NODE_APU_1,
 		.pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
 		.ipi = &apu_ipi,
 	},
 	{
-		.node_id = NODE_APU_2,
+		.node_id = (uint32_t)NODE_APU_2,
 		.pwrdn_mask = APU_2_PWRCTL_CPUPWRDWNREQ_MASK,
 		.ipi = &apu_ipi,
 	},
 	{
-		.node_id = NODE_APU_3,
+		.node_id = (uint32_t)NODE_APU_3,
 		.pwrdn_mask = APU_3_PWRCTL_CPUPWRDWNREQ_MASK,
 		.ipi = &apu_ipi,
 	},
@@ -198,17 +198,18 @@
 
 	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2U));
+		uint32_t reg = mmio_read_32(isenabler1 + (uint64_t)(reg_num << 2U));
 
 		if (reg == 0) {
 			continue;
 		}
 
-		while (reg) {
+		while (reg != 0U) {
 			enum pm_node_id node;
-			uint32_t idx, ret, irq, lowest_set = reg & (-reg);
+			uint32_t idx, irq, lowest_set = reg & (-reg);
+			enum pm_ret_status ret;
 
-			idx = __builtin_ctz(lowest_set);
+			idx = (uint32_t)__builtin_ctz(lowest_set);
 			irq = base_irq + idx;
 
 			if (irq > IRQ_MAX) {
@@ -218,7 +219,7 @@
 			node = irq_to_pm_node(irq);
 			reg &= ~lowest_set;
 
-			if (node > NODE_UNKNOWN && node < NODE_MAX) {
+			if ((node > NODE_UNKNOWN) && (node < NODE_MAX)) {
 				if (pm_wakeup_nodes_set[node] == 0U) {
 					ret = pm_set_wakeup_source(NODE_APU, node, 1U);
 					pm_wakeup_nodes_set[node] = (ret == PM_RET_SUCCESS) ? 1U : 0U;
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index daf3e61..215bf30 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -51,164 +51,164 @@
 /* Dependent APIs for TF-A to check their version from firmware */
 static const eemi_api_dependency api_dep_table[] = {
 	{
-		.id = PM_SELF_SUSPEND,
-		.api_id = PM_SELF_SUSPEND,
+		.id = (uint8_t)PM_SELF_SUSPEND,
+		.api_id = (uint8_t)PM_SELF_SUSPEND,
 	},
 	{
-		.id = PM_REQ_WAKEUP,
-		.api_id = PM_REQ_WAKEUP,
+		.id = (uint8_t)PM_REQ_WAKEUP,
+		.api_id = (uint8_t)PM_REQ_WAKEUP,
 	},
 	{
-		.id = PM_ABORT_SUSPEND,
-		.api_id = PM_ABORT_SUSPEND,
+		.id = (uint8_t)PM_ABORT_SUSPEND,
+		.api_id = (uint8_t)PM_ABORT_SUSPEND,
 	},
 	{
-		.id = PM_SET_WAKEUP_SOURCE,
-		.api_id = PM_SET_WAKEUP_SOURCE,
+		.id = (uint8_t)PM_SET_WAKEUP_SOURCE,
+		.api_id = (uint8_t)PM_SET_WAKEUP_SOURCE,
 	},
 	{
-		.id = PM_SYSTEM_SHUTDOWN,
-		.api_id = PM_SYSTEM_SHUTDOWN,
+		.id = (uint8_t)PM_SYSTEM_SHUTDOWN,
+		.api_id = (uint8_t)PM_SYSTEM_SHUTDOWN,
 	},
 	{
-		.id = PM_GET_API_VERSION,
-		.api_id = PM_GET_API_VERSION,
+		.id = (uint8_t)PM_GET_API_VERSION,
+		.api_id = (uint8_t)PM_GET_API_VERSION,
 	},
 	{
-		.id = PM_CLOCK_ENABLE,
-		.api_id = PM_PLL_SET_MODE,
+		.id = (uint8_t)PM_CLOCK_ENABLE,
+		.api_id = (uint8_t)PM_PLL_SET_MODE,
 	},
 	{
-		.id = PM_CLOCK_ENABLE,
-		.api_id = PM_CLOCK_ENABLE,
+		.id = (uint8_t)PM_CLOCK_ENABLE,
+		.api_id = (uint8_t)PM_CLOCK_ENABLE,
 	},
 	{
-		.id = PM_CLOCK_DISABLE,
-		.api_id = PM_PLL_SET_MODE,
+		.id = (uint8_t)PM_CLOCK_DISABLE,
+		.api_id = (uint8_t)PM_PLL_SET_MODE,
 	},
 	{
-		.id = PM_CLOCK_DISABLE,
-		.api_id = PM_CLOCK_DISABLE,
+		.id = (uint8_t)PM_CLOCK_DISABLE,
+		.api_id = (uint8_t)PM_CLOCK_DISABLE,
 	},
 	{
-		.id = PM_CLOCK_GETSTATE,
-		.api_id = PM_PLL_GET_MODE,
+		.id = (uint8_t)PM_CLOCK_GETSTATE,
+		.api_id = (uint8_t)PM_PLL_GET_MODE,
 	},
 	{
-		.id = PM_CLOCK_GETSTATE,
-		.api_id = PM_CLOCK_GETSTATE,
+		.id = (uint8_t)PM_CLOCK_GETSTATE,
+		.api_id = (uint8_t)PM_CLOCK_GETSTATE,
 	},
 	{
-		.id = PM_CLOCK_SETDIVIDER,
-		.api_id = PM_PLL_SET_PARAMETER,
+		.id = (uint8_t)PM_CLOCK_SETDIVIDER,
+		.api_id = (uint8_t)PM_PLL_SET_PARAMETER,
 	},
 	{
-		.id = PM_CLOCK_SETDIVIDER,
-		.api_id = PM_CLOCK_SETDIVIDER,
+		.id = (uint8_t)PM_CLOCK_SETDIVIDER,
+		.api_id = (uint8_t)PM_CLOCK_SETDIVIDER,
 	},
 	{
-		.id = PM_CLOCK_GETDIVIDER,
-		.api_id = PM_PLL_GET_PARAMETER,
+		.id = (uint8_t)PM_CLOCK_GETDIVIDER,
+		.api_id = (uint8_t)PM_PLL_GET_PARAMETER,
 	},
 	{
-		.id = PM_CLOCK_GETDIVIDER,
-		.api_id = PM_CLOCK_GETDIVIDER,
+		.id = (uint8_t)PM_CLOCK_GETDIVIDER,
+		.api_id = (uint8_t)PM_CLOCK_GETDIVIDER,
 	},
 	{
-		.id = PM_CLOCK_SETPARENT,
-		.api_id = PM_PLL_SET_PARAMETER,
+		.id = (uint8_t)PM_CLOCK_SETPARENT,
+		.api_id = (uint8_t)PM_PLL_SET_PARAMETER,
 	},
 	{
-		.id = PM_CLOCK_SETPARENT,
-		.api_id = PM_CLOCK_SETPARENT,
+		.id = (uint8_t)PM_CLOCK_SETPARENT,
+		.api_id = (uint8_t)PM_CLOCK_SETPARENT,
 	},
 	{
-		.id = PM_CLOCK_GETPARENT,
-		.api_id = PM_PLL_GET_PARAMETER,
+		.id = (uint8_t)PM_CLOCK_GETPARENT,
+		.api_id = (uint8_t)PM_PLL_GET_PARAMETER,
 	},
 	{
-		.id = PM_CLOCK_GETPARENT,
-		.api_id = PM_CLOCK_GETPARENT,
+		.id = (uint8_t)PM_CLOCK_GETPARENT,
+		.api_id = (uint8_t)PM_CLOCK_GETPARENT,
 	},
 	{
-		.id = PM_PLL_SET_PARAMETER,
-		.api_id = PM_PLL_SET_PARAMETER,
+		.id = (uint8_t)PM_PLL_SET_PARAMETER,
+		.api_id = (uint8_t)PM_PLL_SET_PARAMETER,
 	},
 	{
-		.id = PM_PLL_GET_PARAMETER,
-		.api_id = PM_PLL_GET_PARAMETER,
+		.id = (uint8_t)PM_PLL_GET_PARAMETER,
+		.api_id = (uint8_t)PM_PLL_GET_PARAMETER,
 	},
 	{
-		.id = PM_PLL_SET_MODE,
-		.api_id = PM_PLL_SET_MODE,
+		.id = (uint8_t)PM_PLL_SET_MODE,
+		.api_id = (uint8_t)PM_PLL_SET_MODE,
 	},
 	{
-		.id = PM_PLL_GET_MODE,
-		.api_id = PM_PLL_GET_MODE,
+		.id = (uint8_t)PM_PLL_GET_MODE,
+		.api_id = (uint8_t)PM_PLL_GET_MODE,
 	},
 	{
-		.id = PM_REGISTER_ACCESS,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)PM_REGISTER_ACCESS,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = PM_REGISTER_ACCESS,
-		.api_id = PM_MMIO_READ,
+		.id = (uint8_t)PM_REGISTER_ACCESS,
+		.api_id = (uint8_t)PM_MMIO_READ,
 	},
 	{
-		.id = PM_FEATURE_CHECK,
-		.api_id = PM_FEATURE_CHECK,
+		.id = (uint8_t)PM_FEATURE_CHECK,
+		.api_id = (uint8_t)PM_FEATURE_CHECK,
 	},
 	{
-		.id = IOCTL_SET_TAPDELAY_BYPASS,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_SET_TAPDELAY_BYPASS,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_SD_DLL_RESET,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_SD_DLL_RESET,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_SET_SD_TAPDELAY,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_SET_SD_TAPDELAY,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_SET_SD_TAPDELAY,
-		.api_id = PM_MMIO_READ,
+		.id = (uint8_t)IOCTL_SET_SD_TAPDELAY,
+		.api_id = (uint8_t)PM_MMIO_READ,
 	},
 	{
-		.id = IOCTL_SET_PLL_FRAC_DATA,
-		.api_id = PM_PLL_SET_PARAMETER,
+		.id = (uint8_t)IOCTL_SET_PLL_FRAC_DATA,
+		.api_id = (uint8_t)PM_PLL_SET_PARAMETER,
 	},
 	{
-		.id = IOCTL_GET_PLL_FRAC_DATA,
-		.api_id = PM_PLL_GET_PARAMETER,
+		.id = (uint8_t)IOCTL_GET_PLL_FRAC_DATA,
+		.api_id = (uint8_t)PM_PLL_GET_PARAMETER,
 	},
 	{
-		.id = IOCTL_WRITE_GGS,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_WRITE_GGS,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_READ_GGS,
-		.api_id = PM_MMIO_READ,
+		.id = (uint8_t)IOCTL_READ_GGS,
+		.api_id = (uint8_t)PM_MMIO_READ,
 	},
 	{
-		.id = IOCTL_WRITE_PGGS,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_WRITE_PGGS,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_READ_PGGS,
-		.api_id = PM_MMIO_READ,
+		.id = (uint8_t)IOCTL_READ_PGGS,
+		.api_id = (uint8_t)PM_MMIO_READ,
 	},
 	{
-		.id = IOCTL_ULPI_RESET,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_ULPI_RESET,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_SET_BOOT_HEALTH_STATUS,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_SET_BOOT_HEALTH_STATUS,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_AFI,
-		.api_id = PM_MMIO_WRITE,
+		.id = (uint8_t)IOCTL_AFI,
+		.api_id = (uint8_t)PM_MMIO_WRITE,
 	},
 };
 
@@ -343,7 +343,7 @@
 
 	/* encode set Address into 1st bit of address */
 	encoded_address = address;
-	encoded_address |= !!set_address;
+	encoded_address |= (uint32_t)!!set_address;
 
 	/* Send request to the PMU to perform the wake of the PU */
 	PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
@@ -440,7 +440,7 @@
 {
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
-	if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
+	if (type == (uint32_t)PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
 		/* Setting scope for subsequent PSCI reboot or shutdown */
 		pm_shutdown_scope = subtype;
 		return PM_RET_SUCCESS;
@@ -710,7 +710,7 @@
 {
 	enum pm_ret_status ret = PM_RET_SUCCESS;
 	/* Return if interrupt is not from PMU */
-	if (!pm_ipi_irq_status(primary_proc)) {
+	if ((pm_ipi_irq_status(primary_proc) == 0U)) {
 		return ret;
 	}
 
@@ -769,8 +769,8 @@
 enum pm_ret_status check_api_dependency(uint8_t id)
 {
 	uint8_t i;
-	uint32_t version;
-	int ret;
+	uint32_t version_type;
+	enum pm_ret_status ret;
 
 	for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
 		if (api_dep_table[i].id == id) {
@@ -779,13 +779,13 @@
 			}
 
 			ret = fw_api_version(api_dep_table[i].api_id,
-					     &version, 1);
-			if (ret != PM_RET_SUCCESS) {
+					     &version_type, 1);
+			if (ret != (uint32_t)PM_RET_SUCCESS) {
 				return ret;
 			}
 
 			/* Check if fw version matches TF-A expected version */
-			if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
+			if (version_type != tfa_expected_ver_id[api_dep_table[i].api_id]) {
 				return PM_RET_ERROR_NOTSUPPORTED;
 			}
 		}
@@ -898,7 +898,7 @@
 	case PM_REGISTER_ACCESS:
 	case PM_FEATURE_CHECK:
 		status = check_api_dependency(api_id);
-		if (status != PM_RET_SUCCESS) {
+		if (status != (uint32_t)PM_RET_SUCCESS) {
 			return status;
 		}
 		return get_tfa_version_for_partial_apis(api_id, version);
@@ -925,13 +925,13 @@
 
 	/* Get API version implemented in TF-A */
 	status = feature_check_tfa(api_id, version, bit_mask);
-	if (status != PM_RET_ERROR_NO_FEATURE) {
+	if (status != (uint32_t)PM_RET_ERROR_NO_FEATURE) {
 		return status;
 	}
 
 	/* Get API version implemented by firmware and TF-A both */
 	status = feature_check_partial(api_id, version);
-	if (status != PM_RET_ERROR_NO_FEATURE) {
+	if (status != (uint32_t)PM_RET_ERROR_NO_FEATURE) {
 		return status;
 	}
 
@@ -940,20 +940,20 @@
 	/* IOCTL call may return failure whose ID is not implemented in
 	 * firmware but implemented in TF-A
 	 */
-	if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
+	if ((api_id != (uint32_t)PM_IOCTL) && (status != PM_RET_SUCCESS)) {
 		return status;
 	}
 
 	*version = ret_payload[0];
 
 	/* Update IOCTL bit mask which are implemented in TF-A */
-	if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
-		if (len < 2) {
+	if ((api_id == (uint32_t)PM_IOCTL) || (api_id == (uint32_t)PM_GET_OP_CHARACTERISTIC)) {
+		if (len < 2U) {
 			return PM_RET_ERROR_ARGS;
 		}
 		bit_mask[0] = ret_payload[1];
 		bit_mask[1] = ret_payload[2];
-		if (api_id == PM_IOCTL) {
+		if (api_id == (uint32_t)PM_IOCTL) {
 			/* Get IOCTL's implemented by TF-A */
 			status = tfa_ioctl_bitmask(bit_mask);
 		}
@@ -1115,7 +1115,7 @@
 		return status;
 	}
 
-	if (enable) {
+	if (enable != 0U) {
 		api_id = PM_CLOCK_ENABLE;
 	} else {
 		api_id = PM_CLOCK_DISABLE;
@@ -1150,7 +1150,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_enable(pll);
 	}
 
@@ -1175,7 +1175,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_disable(pll);
 	}
 
@@ -1203,9 +1203,9 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll)
+	if (pll != NULL) {
 		return pm_clock_pll_get_state(pll, state);
-
+	}
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
 	if (status != PM_RET_SUCCESS) {
@@ -1297,7 +1297,7 @@
 		return status;
 	}
 
-	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
+	if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) != 0U) {
 		/* Send request to the PMU to get div0 */
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV0_ID);
@@ -1308,7 +1308,7 @@
 		*divider = val;
 	}
 
-	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
+	if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) != 0U) {
 		/* Send request to the PMU to get div1 */
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV1_ID);
@@ -1341,7 +1341,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_set_parent(pll, clock_id, parent_index);
 	}
 
@@ -1376,7 +1376,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_get_parent(pll, clock_id, parent_index);
 	}
 
@@ -1521,47 +1521,47 @@
 		pm_clock_get_name(arg1, (char *)data);
 		break;
 	case PM_QID_CLOCK_GET_TOPOLOGY:
-		data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
+		data[0] = (uint32_t)pm_clock_get_topology(arg1, arg2, &data[1]);
 		break;
 	case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
-		data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
+		data[0] = (uint32_t)pm_clock_get_fixedfactor_params(arg1, &data[1],
 							  &data[2]);
 		break;
 	case PM_QID_CLOCK_GET_PARENTS:
-		data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
+		data[0] = (uint32_t)pm_clock_get_parents(arg1, arg2, &data[1]);
 		break;
 	case PM_QID_CLOCK_GET_ATTRIBUTES:
-		data[0] = pm_clock_get_attributes(arg1, &data[1]);
+		data[0] = (uint32_t)pm_clock_get_attributes(arg1, &data[1]);
 		break;
 	case PM_QID_PINCTRL_GET_NUM_PINS:
-		data[0] = pm_pinctrl_get_num_pins(&data[1]);
+		data[0] = (uint32_t)pm_pinctrl_get_num_pins(&data[1]);
 		break;
 	case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
-		data[0] = pm_pinctrl_get_num_functions(&data[1]);
+		data[0] = (uint32_t)pm_pinctrl_get_num_functions(&data[1]);
 		break;
 	case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
-		data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
+		data[0] = (uint32_t)pm_pinctrl_get_num_function_groups(arg1, &data[1]);
 		break;
 	case PM_QID_PINCTRL_GET_FUNCTION_NAME:
 		pm_pinctrl_get_function_name(arg1, (char *)data);
 		break;
 	case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
-		data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
+		data[0] = (uint32_t)pm_pinctrl_get_function_groups(arg1, arg2,
 							 (uint16_t *)&data[1]);
 		break;
 	case PM_QID_PINCTRL_GET_PIN_GROUPS:
-		data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
+		data[0] = (uint32_t)pm_pinctrl_get_pin_groups(arg1, arg2,
 						    (uint16_t *)&data[1]);
 		break;
 	case PM_QID_CLOCK_GET_NUM_CLOCKS:
-		data[0] = pm_clock_get_num_clocks(&data[1]);
+		data[0] = (uint32_t)pm_clock_get_num_clocks(&data[1]);
 		break;
 
 	case PM_QID_CLOCK_GET_MAX_DIVISOR:
-		data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
+		data[0] = (uint32_t)pm_clock_get_max_divisor(arg1, (uint8_t)arg2, &data[1]);
 		break;
 	default:
-		data[0] = PM_RET_ERROR_ARGS;
+		data[0] = (uint32_t)PM_RET_ERROR_ARGS;
 		WARN("Unimplemented query service call: 0x%x\n", qid);
 		break;
 	}
@@ -1657,7 +1657,7 @@
 	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;
 	}
 
@@ -1688,7 +1688,7 @@
 	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;
 	}
 
@@ -1721,7 +1721,7 @@
 	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;
 	}
 
@@ -1749,7 +1749,7 @@
 	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;
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
index af75c5c..c7d2b2c 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -187,9 +187,9 @@
  *
  */
 enum pm_shutdown_subtype {
-	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
-	PMF_SHUTDOWN_SUBTYPE_PS_ONLY,
-	PMF_SHUTDOWN_SUBTYPE_SYSTEM,
+	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM  = (0U),
+	PMF_SHUTDOWN_SUBTYPE_PS_ONLY = (1U),
+	PMF_SHUTDOWN_SUBTYPE_SYSTEM = (2U),
 };
 
 /**
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 65b2426..21435c6 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -22,6 +22,7 @@
 #include <plat_private.h>
 #include "pm_client.h"
 #include "pm_ipi.h"
+#include "pm_svc_main.h"
 #include "zynqmp_pm_api_sys.h"
 #include "zynqmp_pm_defs.h"
 
@@ -252,7 +253,7 @@
 		ret = status;
 	}
 
-	pm_up = !status;
+	pm_up = (status == 0);
 
 	return ret;
 }
@@ -321,7 +322,7 @@
 		uint32_t set_addr = pm_arg[1] & 0x1U;
 		uint64_t address = (uint64_t)pm_arg[2] << 32U;
 
-		address |= pm_arg[1] & (~0x1U);
+		address |= (uint64_t)(pm_arg[1] & (~0x1U));
 		ret = pm_req_wakeup(pm_arg[0], set_addr, address,
 				    pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
@@ -353,7 +354,7 @@
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_API_VERSION:
-		if (ipi_irq_flag == 0U) {
+		if ((uint32_t)ipi_irq_flag == 0U) {
 			/*
 			 * Enable IPI IRQ
 			 * assume the rich OS is OK to handle callback IRQs now.
@@ -374,7 +375,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_fpga_get_status(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_SECURE_RSA_AES:
@@ -389,15 +390,15 @@
 		}
 
 		SMC_RET2(handle,
-			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
-			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
+			 ((uint64_t)result[0] | ((uint64_t)result[1] << 32)),
+			 ((uint64_t)result[2] | ((uint64_t)result[3] << 32)));
 	case PM_IOCTL:
 	{
 		uint32_t value = 0U;
 
 		ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
 			       pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_QUERY_DATA:
@@ -406,8 +407,8 @@
 
 		pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
 			      pm_arg[3], data);
-		SMC_RET2(handle, (uint64_t)data[0]  | ((uint64_t)data[1] << 32),
-			 (uint64_t)data[2] | ((uint64_t)data[3] << 32));
+		SMC_RET2(handle, ((uint64_t)data[0]  | ((uint64_t)data[1] << 32)),
+			 ((uint64_t)data[2] | ((uint64_t)data[3] << 32)));
 	}
 
 	case PM_CLOCK_ENABLE:
@@ -423,7 +424,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_clock_getstate(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_CLOCK_SETDIVIDER:
@@ -435,7 +436,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_clock_getdivider(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_CLOCK_SETPARENT:
@@ -447,7 +448,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_GET_TRUSTZONE_VERSION:
@@ -472,7 +473,7 @@
 	{
 		ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], &result[0]);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
 			 result[1]);
 	}
 
@@ -482,7 +483,7 @@
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_SECURE_AES:
@@ -490,7 +491,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_PLL_SET_PARAMETER:
@@ -502,7 +503,7 @@
 		uint32_t value = 0U;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
+		SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)value << 32U)));
 	}
 
 	case PM_PLL_SET_MODE:
@@ -514,7 +515,7 @@
 		uint32_t mode = 0U;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
+		SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)mode << 32U)));
 	}
 
 	case PM_REGISTER_ACCESS:
@@ -523,7 +524,7 @@
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_EFUSE_ACCESS:
@@ -538,7 +539,7 @@
 		}
 #endif
 		ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, (uint64_t)ret | (((uint64_t)value) << 32U));
 	}
 
 	case PM_FPGA_GET_VERSION:
@@ -549,19 +550,19 @@
 		PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
 				 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
-		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32U,
-			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32U);
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)ret_payload[0] << 32U)),
+			 ((uint64_t)ret_payload[1] | ((uint64_t)ret_payload[2] << 32U)));
 	}
 
 	case PM_FEATURE_CHECK:
 	{
-		uint32_t version = 0;
+		uint32_t version_type = 0;
 		uint32_t bit_mask[2] = {0};
 
-		ret = pm_feature_check(pm_arg[0], &version, bit_mask,
-				       ARRAY_SIZE(bit_mask));
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32U),
-			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U));
+		ret = pm_feature_check(pm_arg[0], &version_type, bit_mask,
+				       (uint8_t)ARRAY_SIZE(bit_mask));
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)version_type << 32U)),
+			 ((uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U)));
 	}
 
 	default:
@@ -570,7 +571,7 @@
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
 				       RET_PAYLOAD_ARG_CNT);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
-			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
+			 ((uint64_t)result[1] | ((uint64_t)result[2] << 32U)));
 	}
 }
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index f5990ca..1baefb3 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -81,7 +81,7 @@
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & (uint32_t)SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
diff --git a/poetry.lock b/poetry.lock
index 9a90704..4127bcd 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
@@ -399,13 +399,13 @@
 
 [[package]]
 name = "jinja2"
-version = "3.1.4"
+version = "3.1.5"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
-    {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
+    {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
+    {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
 ]
 
 [package.dependencies]
@@ -869,23 +869,23 @@
 
 [[package]]
 name = "setuptools"
-version = "74.1.2"
+version = "75.3.0"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "setuptools-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"},
-    {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"},
+    {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"},
+    {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"},
 ]
 
 [package.extras]
 check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
-core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
 cover = ["pytest-cov"]
 doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
 enabler = ["pytest-enabler (>=2.2)"]
-test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
-type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"]
 
 [[package]]
 name = "shellingham"
@@ -1247,13 +1247,13 @@
 
 [[package]]
 name = "virtualenv"
-version = "20.26.4"
+version = "20.26.6"
 description = "Virtual Python Environment builder"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"},
-    {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"},
+    {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
+    {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
 ]
 
 [package.dependencies]
diff --git a/pyproject.toml b/pyproject.toml
index f34c3d1..62878b4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "trusted-firmware-a"
-version = "2.11.0"
+version = "2.12.0"
 description = "Trusted Firmware-A (TF-A) Python dependencies."
 authors = ["Arm Ltd."]
 license = "BSD-3-Clause"
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 5456164..6acd1b6 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -14,6 +14,9 @@
 #include <services/arm_arch_svc.h>
 #include <smccc_helpers.h>
 #include <plat/common/platform.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/el3_runtime/context_mgmt.h>
 
 static int32_t smccc_version(void)
 {
@@ -90,6 +93,12 @@
 		}
 		return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
 #endif
+
+#if ARCH_FEATURE_AVAILABILITY
+	case SMCCC_ARCH_FEATURE_AVAILABILITY:
+		return SMC_ARCH_CALL_SUCCESS;
+#endif /* ARCH_FEATURE_AVAILABILITY */
+
 #endif /* __aarch64__ */
 
 	/* Fallthrough */
@@ -113,6 +122,91 @@
 }
 
 /*
+ * Reads a system register, sanitises its value, and returns a bitmask
+ * representing which feature in that sysreg has been enabled by firmware. The
+ * bitmask is a 1:1 mapping to the register's fields.
+ */
+#if ARCH_FEATURE_AVAILABILITY
+static uintptr_t smccc_arch_feature_availability(u_register_t reg,
+						 void *handle,
+						 u_register_t flags)
+{
+	cpu_context_t *caller_context;
+	per_world_context_t *caller_per_world_context;
+	el3_state_t *state;
+	u_register_t bitmask, check;
+
+	/* check the caller security state */
+	if (is_caller_secure(flags)) {
+		caller_context = cm_get_context(SECURE);
+		caller_per_world_context = &per_world_context[CPU_CONTEXT_SECURE];
+	} else if (is_caller_non_secure(flags)) {
+		caller_context = cm_get_context(NON_SECURE);
+		caller_per_world_context = &per_world_context[CPU_CONTEXT_NS];
+	} else {
+#if ENABLE_RME
+		caller_context = cm_get_context(REALM);
+		caller_per_world_context = &per_world_context[CPU_CONTEXT_REALM];
+#else /* !ENABLE_RME */
+		assert(0); /* shouldn't be possible */
+#endif /* ENABLE_RME */
+	}
+
+	state = get_el3state_ctx(caller_context);
+
+	switch (reg) {
+	case SCR_EL3_OPCODE:
+		bitmask  = read_ctx_reg(state, CTX_SCR_EL3);
+		bitmask &= ~SCR_EL3_IGNORED;
+		check    = bitmask & ~SCR_EL3_FEATS;
+		bitmask &= SCR_EL3_FEATS;
+		bitmask ^= SCR_EL3_FLIPPED;
+		/* will only report 0 if neither is implemented */
+		if (is_feat_rng_trap_supported() || is_feat_rng_present())
+			bitmask |= SCR_TRNDR_BIT;
+		break;
+	case CPTR_EL3_OPCODE:
+		bitmask  = caller_per_world_context->ctx_cptr_el3;
+		check    = bitmask & ~CPTR_EL3_FEATS;
+		bitmask &= CPTR_EL3_FEATS;
+		bitmask ^= CPTR_EL3_FLIPPED;
+		break;
+	case MDCR_EL3_OPCODE:
+		bitmask  = read_ctx_reg(state, CTX_MDCR_EL3);
+		bitmask &= ~MDCR_EL3_IGNORED;
+		check    = bitmask & ~MDCR_EL3_FEATS;
+		bitmask &= MDCR_EL3_FEATS;
+		bitmask ^= MDCR_EL3_FLIPPED;
+		break;
+#if ENABLE_FEAT_MPAM
+	case MPAM3_EL3_OPCODE:
+		bitmask  = caller_per_world_context->ctx_mpam3_el3;
+		bitmask &= ~MPAM3_EL3_IGNORED;
+		check    = bitmask & ~MPAM3_EL3_FEATS;
+		bitmask &= MPAM3_EL3_FEATS;
+		bitmask ^= MPAM3_EL3_FLIPPED;
+		break;
+#endif /* ENABLE_FEAT_MPAM */
+	default:
+		SMC_RET2(handle, SMC_INVALID_PARAM, ULL(0));
+	}
+
+	/*
+	 * failing this means that the requested register has a bit set that
+	 * hasn't been declared as a known feature bit or an ignore bit. This is
+	 * likely to happen when support for a new feature is added but the
+	 * bitmask macros are not updated.
+	 */
+	if (ENABLE_ASSERTIONS && check != 0) {
+		ERROR("Unexpected bits 0x%lx were set in register %lx!\n", check, reg);
+		assert(0);
+	}
+
+	SMC_RET2(handle, SMC_ARCH_CALL_SUCCESS, bitmask);
+}
+#endif /* ARCH_FEATURE_AVAILABILITY */
+
+/*
  * Top-level Arm Architectural Service SMC handler.
  */
 static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid,
@@ -161,6 +255,11 @@
 		SMC_RET0(handle);
 #endif
 #endif /* __aarch64__ */
+#if ARCH_FEATURE_AVAILABILITY
+	/* return is 64 bit so only reply on SMC64 requests */
+	case SMCCC_ARCH_FEATURE_AVAILABILITY | (SMC_64 << FUNCID_CC_SHIFT):
+		return smccc_arch_feature_availability(x1, handle, flags);
+#endif /* ARCH_FEATURE_AVAILABILITY */
 	default:
 		WARN("Unimplemented Arm Architecture Service Call: 0x%x \n",
 			smc_fid);
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 9e83848..8910ec6 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -190,24 +190,28 @@
 	if (!optee_ep_info->pc)
 		return 1;
 
-	if (TRANSFER_LIST &&
-		optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
-					REGISTER_CONVENTION_VERSION_MASK)) {
-		tl = (void *)optee_ep_info->args.arg3;
-		if (transfer_list_check_header(tl) == TL_OPS_NON) {
-			return 1;
-		}
-
-		opteed_rw = GET_RW(optee_ep_info->spsr);
+	tl = (void *)optee_ep_info->args.arg3;
+	if (TRANSFER_LIST && transfer_list_check_header(tl)) {
 		te = transfer_list_find(tl, TL_TAG_FDT);
 		dt = transfer_list_entry_data(te);
 
+		opteed_rw = GET_RW(optee_ep_info->spsr);
 		if (opteed_rw == OPTEE_AARCH64) {
+			if (optee_ep_info->args.arg1 !=
+			    TRANSFER_LIST_HANDOFF_X1_VALUE(
+				REGISTER_CONVENTION_VERSION))
+				return 1;
+
 			arg0 = (uint64_t)dt;
 			arg2 = 0;
 		} else {
-			arg2 = (uint64_t)dt;
+			if (optee_ep_info->args.arg1 !=
+			    TRANSFER_LIST_HANDOFF_R1_VALUE(
+				REGISTER_CONVENTION_VERSION))
+				return 1;
+
 			arg0 = 0;
+			arg2 = (uint64_t)dt;
 		}
 
 		arg1 = optee_ep_info->args.arg1;
diff --git a/services/spd/tlkd/tlkd.mk b/services/spd/tlkd/tlkd.mk
index 56de0a6..fc8840d 100644
--- a/services/spd/tlkd/tlkd.mk
+++ b/services/spd/tlkd/tlkd.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,9 @@
 SPD_INCLUDES		:=	-Iinclude/bl32/payloads
 endif
 
+ifeq (${ENABLE_FEAT_D128}, 0)
 SPD_SOURCES		:=	services/spd/tlkd/tlkd_common.c		\
 				services/spd/tlkd/tlkd_helpers.S	\
 				services/spd/tlkd/tlkd_main.c		\
 				services/spd/tlkd/tlkd_pm.c
+endif
\ No newline at end of file
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index 6cb4992..8ff71cc 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -575,6 +575,11 @@
 		 * of the DIT PSTATE bit.
 		 */
 	case TSP_YIELD_FID(TSP_CHECK_DIT):
+		/*
+		 * Request from non-secure client to modify the EL1
+		 * context registers.
+		 */
+	case TSP_YIELD_FID(TSP_MODIFY_EL1_CTX):
 		if (ns) {
 			/*
 			 * This is a fresh request from the non-secure client.
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 8d27e96..f58f615 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -108,7 +108,7 @@
 				plat_drtm_get_imp_def_dlme_region_size();
 
 	dlme_data_min_size += dlme_data_hdr_init.dlme_addr_map_size +
-			      PLAT_DRTM_EVENT_LOG_MAX_SIZE +
+			      ARM_DRTM_MIN_EVENT_LOG_SIZE +
 			      dlme_data_hdr_init.dlme_tcb_hashes_table_size +
 			      dlme_data_hdr_init.dlme_impdef_region_size;
 
@@ -208,7 +208,7 @@
 		return DENIED;
 	}
 
-	running_on_single_core = psci_is_last_on_cpu_safe();
+	running_on_single_core = psci_is_last_on_cpu_safe(plat_my_core_pos());
 	if (!running_on_single_core) {
 		ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
 		return SECONDARY_PE_NOT_OFF;
@@ -282,9 +282,9 @@
 
 	/* Prepare DRTM event log for DLME. */
 	drtm_serialise_event_log(dlme_data_cursor, &serialised_bytes_actual);
-	assert(serialised_bytes_actual <= PLAT_DRTM_EVENT_LOG_MAX_SIZE);
-	dlme_data_hdr->dlme_tpm_log_size = serialised_bytes_actual;
-	dlme_data_cursor += serialised_bytes_actual;
+	assert(serialised_bytes_actual <= ARM_DRTM_MIN_EVENT_LOG_SIZE);
+	dlme_data_hdr->dlme_tpm_log_size = ARM_DRTM_MIN_EVENT_LOG_SIZE;
+	dlme_data_cursor +=  dlme_data_hdr->dlme_tpm_log_size;
 
 	/*
 	 * TODO: Prepare the TCB hashes for DLME, currently its size
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index a7d053f..c105b56 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -37,6 +37,11 @@
 		(((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off))
 
 /*
+ * Minimum size of Event Log in DLME data (64 KiB)
+ */
+#define ARM_DRTM_MIN_EVENT_LOG_SIZE	U(0x10000)
+
+/*
  * Range(Min/Max) of DRTM parameter structure versions supported
  */
 #define ARM_DRTM_PARAMS_MIN_VERSION	U(1)
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index f73236c..7d4ea70 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +13,8 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include "rmmd_private.h"
-#include <services/rmmd_svc.h>
+#include <services/rmm_el3_token_sign.h>
+#include <smccc_helpers.h>
 
 static spinlock_t lock;
 
@@ -156,10 +158,110 @@
 						 (unsigned int)ecc_curve);
 	if (err != 0) {
 		ERROR("Failed to get attestation key: %d.\n", err);
-		err =  E_RMM_UNK;
+		err = E_RMM_UNK;
 	}
 
 	spin_unlock(&lock);
 
 	return err;
 }
+
+static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (buf_size < sizeof(struct el3_token_sign_request)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Call platform port to handle attestation toekn signing request. */
+	err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+
+	if (buf_size < sizeof(struct el3_token_sign_response)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Pull attestation signing response from HES. */
+	err = plat_rmmd_el3_token_sign_pull_resp(
+			(struct el3_token_sign_response *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
+				   uint64_t ecc_curve)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, *buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Get the Realm attestation public key from platform port. */
+	err = plat_rmmd_el3_token_sign_get_rak_pub(
+		(uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
+
+	spin_unlock(&lock);
+	if (err != 0) {
+		ERROR("Failed to get attestation public key from HES: %d.\n",
+		      err);
+		err = E_RMM_UNK;
+	}
+
+
+	return err;
+}
+
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
+				    uint64_t x3, uint64_t x4)
+{
+	int ret;
+
+	switch (opcode) {
+	case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
+		ret = rmmd_el3_token_sign_push_req(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
+		ret = rmmd_el3_token_sign_pull_resp(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
+		ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
+		SMC_RET2(handle, ret, x3);
+	default:
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 153bb01..13ea5db 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -33,6 +33,8 @@
 #include <smccc_helpers.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/sve.h>
+#include <lib/extensions/spe.h>
+#include <lib/extensions/trbe.h>
 #include "rmmd_initial_context.h"
 #include "rmmd_private.h"
 
@@ -127,6 +129,20 @@
 	if (is_feat_sme_supported()) {
 		sme_enable(ctx);
 	}
+
+	/*
+	 * SPE and TRBE cannot be fully disabled from EL3 registers alone, only
+	 * sysreg access can. In case the EL1 controls leave them active on
+	 * context switch, we want the owning security state to be NS so Realm
+	 * can't be DOSed.
+	 */
+	if (is_feat_spe_supported()) {
+		spe_disable(ctx);
+	}
+
+	if (is_feat_trbe_supported()) {
+		trbe_disable(ctx);
+	}
 }
 
 static void manage_extensions_realm_per_world(void)
@@ -441,6 +457,21 @@
 	return ret;
 }
 
+static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
+					 uint64_t *feat_reg)
+{
+	if (feat_reg_idx != RMM_EL3_FEAT_REG_0_IDX) {
+		ERROR("RMMD: Failed to get feature register %ld\n", feat_reg_idx);
+		return E_RMM_INVAL;
+	}
+
+	*feat_reg = 0UL;
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	*feat_reg |= RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK;
+#endif
+	return E_RMM_OK;
+}
+
 /*******************************************************************************
  * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
@@ -448,7 +479,7 @@
 				uint64_t x3, uint64_t x4, void *cookie,
 				void *handle, uint64_t flags)
 {
-	uint64_t remaining_len = 0;
+	uint64_t remaining_len = 0UL;
 	uint32_t src_sec_state;
 	int ret;
 
@@ -479,7 +510,13 @@
 	case RMM_ATTEST_GET_REALM_KEY:
 		ret = rmmd_attest_get_signing_key(x1, &x2, x3);
 		SMC_RET2(handle, ret, x2);
-
+	case RMM_EL3_FEATURES:
+		ret = rmm_el3_ifc_get_feat_register(x1, &x2);
+		SMC_RET2(handle, ret, x2);
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	case RMM_EL3_TOKEN_SIGN:
+		return rmmd_el3_token_sign(handle, x1, x2, x3, x4);
+#endif
 	case RMM_BOOT_COMPLETE:
 		VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 		rmmd_rmm_sync_exit(x1);
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index 6d3b5ec..0ce104d 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -51,6 +51,8 @@
 				   uint64_t *remaining_len);
 int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
 				uint64_t ecc_curve);
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t x1, uint64_t x2,
+				    uint64_t x3, uint64_t x4);
 
 /* Assembly helpers */
 uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index e093a82..6fd0f2b 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -134,6 +134,9 @@
 
 	/* Track the source partition ID to validate a direct response. */
 	uint16_t dir_req_origin_id;
+
+	/* Track direct message function id to validate a direct response. */
+	uint16_t dir_req_funcid;
 };
 
 /*
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index c6ec30c..b0d6ba6 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -304,6 +304,7 @@
 					void *handle)
 {
 	/* Retrieve populated Direct Response Arguments. */
+	uint64_t smc_fid = SMC_GET_GP(handle, CTX_GPREG_X0);
 	uint64_t x1 = SMC_GET_GP(handle, CTX_GPREG_X1);
 	uint64_t x2 = SMC_GET_GP(handle, CTX_GPREG_X2);
 	uint16_t src_id = ffa_endpoint_source(x1);
@@ -323,7 +324,8 @@
 		return false;
 	}
 
-	if (!direct_msg_validate_arg2(x2)) {
+	if ((smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) &&
+			!direct_msg_validate_arg2(x2)) {
 		ERROR("Invalid EL3 LP message encoding.\n");
 		return false;
 	}
@@ -331,6 +333,21 @@
 }
 
 /*******************************************************************************
+ * Helper function to check that partition can receive direct msg or not.
+ ******************************************************************************/
+static bool direct_msg_receivable(uint32_t properties, uint16_t dir_req_fnum)
+{
+	if ((dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ &&
+			((properties & FFA_PARTITION_DIRECT_REQ_RECV) == 0U)) ||
+			(dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ2 &&
+			((properties & FFA_PARTITION_DIRECT_REQ2_RECV) == 0U))) {
+		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,
@@ -345,14 +362,21 @@
 {
 	uint16_t src_id = ffa_endpoint_source(x1);
 	uint16_t dst_id = ffa_endpoint_destination(x1);
+	uint16_t dir_req_funcid;
 	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);
+	dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_REQ2_SMC64) ?
+		FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
+
+	/*
+	 * Sanity check for DIRECT_REQ:
+	 * Check if arg2 has been populated correctly based on message type
+	 */
+	if ((dir_req_funcid == FFA_FNUM_MSG_SEND_DIRECT_REQ) &&
+			!direct_msg_validate_arg2(x2)) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
 	}
 
 	/* Validate Sender is either the current SP or from the normal world. */
@@ -368,6 +392,10 @@
 	/* 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) {
+			if (!direct_msg_receivable(el3_lp_descs[i].properties, dir_req_funcid)) {
+				return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+			}
+
 			uint64_t ret = el3_lp_descs[i].direct_req(
 						smc_fid, secure_origin, x1, x2,
 						x3, x4, cookie, handle, flags);
@@ -402,6 +430,10 @@
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
+	if (!direct_msg_receivable(sp->properties, dir_req_funcid)) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
 	/* Protect the runtime state of a UP S-EL0 SP with a lock. */
 	if (sp->runtime_el == S_EL0) {
 		spin_lock(&sp->rt_state_lock);
@@ -430,6 +462,7 @@
 	sp->ec[idx].rt_state = RT_STATE_RUNNING;
 	sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
 	sp->ec[idx].dir_req_origin_id = src_id;
+	sp->ec[idx].dir_req_funcid = dir_req_funcid;
 
 	if (sp->runtime_el == S_EL0) {
 		spin_unlock(&sp->rt_state_lock);
@@ -453,9 +486,13 @@
 					uint64_t flags)
 {
 	uint16_t dst_id = ffa_endpoint_destination(x1);
+	uint16_t dir_req_funcid;
 	struct secure_partition_desc *sp;
 	unsigned int idx;
 
+	dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) ?
+		FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
+
 	/* Check if arg2 has been populated correctly based on message type. */
 	if (!direct_msg_validate_arg2(x2)) {
 		return spmc_ffa_error_return(handle,
@@ -507,6 +544,15 @@
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
+	if (dir_req_funcid != sp->ec[idx].dir_req_funcid) {
+		WARN("Unmatched direct req/resp func id. req:%x, resp:%x on core%u.\n",
+		     sp->ec[idx].dir_req_funcid, (smc_fid & FUNCID_NUM_MASK), idx);
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
 	if (sp->ec[idx].dir_req_origin_id != dst_id) {
 		WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
 		     dst_id, sp->ec[idx].dir_req_origin_id, idx);
@@ -522,6 +568,9 @@
 	/* Clear the ongoing direct request ID. */
 	sp->ec[idx].dir_req_origin_id = INV_SP_ID;
 
+	/* Clear the ongoing direct request message version. */
+	sp->ec[idx].dir_req_funcid = 0U;
+
 	if (sp->runtime_el == S_EL0) {
 		spin_unlock(&sp->rt_state_lock);
 	}
@@ -647,6 +696,8 @@
 {
 	struct secure_partition_desc *sp;
 	unsigned int idx;
+	uint16_t dst_id = ffa_endpoint_destination(x1);
+	bool cancel_dir_req = false;
 
 	/* Check that the response did not originate from the Normal world. */
 	if (!secure_origin) {
@@ -674,6 +725,32 @@
 		panic();
 	}
 
+	if (sp->runtime_el == S_EL0) {
+		spin_lock(&sp->rt_state_lock);
+	}
+
+	if (sp->ec[idx].rt_state == RT_STATE_RUNNING &&
+			sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+		sp->ec[idx].rt_state = RT_STATE_WAITING;
+		sp->ec[idx].dir_req_origin_id = INV_SP_ID;
+		sp->ec[idx].dir_req_funcid = 0x00;
+		cancel_dir_req = true;
+	}
+
+	if (sp->runtime_el == S_EL0) {
+		spin_unlock(&sp->rt_state_lock);
+	}
+
+	if (cancel_dir_req) {
+		if (dst_id == FFA_SPMC_ID) {
+			spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+			/* Should not get here. */
+			panic();
+		} else
+			return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+					       handle, cookie, flags, dst_id);
+	}
+
 	return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
 }
 
@@ -1267,6 +1344,7 @@
 	case FFA_RX_RELEASE:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
 	case FFA_PARTITION_INFO_GET:
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
@@ -1289,6 +1367,7 @@
 	case FFA_SECONDARY_EP_REGISTER_SMC64:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
 	case FFA_MEM_RELINQUISH:
 	case FFA_MSG_WAIT:
 	case FFA_CONSOLE_LOG_SMC32:
@@ -1909,7 +1988,9 @@
 
 	/* Validate this entry, we currently only support direct messaging. */
 	if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
-			  FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
+			  FFA_PARTITION_DIRECT_REQ_SEND |
+			  FFA_PARTITION_DIRECT_REQ2_RECV |
+			  FFA_PARTITION_DIRECT_REQ2_SEND)) != 0U) {
 		WARN("Invalid Secure Partition messaging method (0x%x)\n",
 		     config_32);
 		return -EINVAL;
@@ -2077,39 +2158,34 @@
 		return ret;
 	}
 
-	/* Check that the runtime EL in the manifest was correct. */
-	if (sp->runtime_el != S_EL0 && 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, boot_info_reg);
 
 	/* Perform any initialisation specific to S-EL1 SPs. */
 	if (sp->runtime_el == S_EL1) {
 		spmc_el1_sp_setup(sp, next_image_ep_info);
+		spmc_sp_common_ep_commit(sp, next_image_ep_info);
 	}
-
 #if SPMC_AT_EL3_SEL0_SP
-	/* Setup spsr in endpoint info for common context management routine. */
-	if (sp->runtime_el == S_EL0) {
+	/* Perform any initialisation specific to S-EL0 SPs. */
+	else if (sp->runtime_el == S_EL0) {
+		/* Setup spsr in endpoint info for common context management routine. */
 		spmc_el0_sp_spsr_setup(next_image_ep_info);
-	}
-#endif /* SPMC_AT_EL3_SEL0_SP */
 
-	/* Initialize the SP context with the required ep info. */
-	spmc_sp_common_ep_commit(sp, next_image_ep_info);
+		spmc_sp_common_ep_commit(sp, next_image_ep_info);
 
-#if SPMC_AT_EL3_SEL0_SP
-	/*
-	 * Perform any initialisation specific to S-EL0 not set by common
-	 * context management routine.
-	 */
-	if (sp->runtime_el == S_EL0) {
+		/*
+		 * Perform any initialisation specific to S-EL0 not set by common
+		 * context management routine.
+		 */
 		spmc_el0_sp_setup(sp, boot_info_reg, sp_manifest);
 	}
 #endif /* SPMC_AT_EL3_SEL0_SP */
+	else {
+		ERROR("Unexpected runtime EL: %u\n", sp->runtime_el);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -2356,11 +2432,13 @@
 
 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+	case FFA_MSG_SEND_DIRECT_REQ2_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:
+	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
 		return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
 					       x3, x4, cookie, handle, flags);
 
@@ -2426,11 +2504,13 @@
 		return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
 						x4, cookie, handle, flags);
 
-	case FFA_MEM_PERM_GET:
+	case FFA_MEM_PERM_GET_SMC32:
+	case FFA_MEM_PERM_GET_SMC64:
 		return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
 						x3, x4, cookie, handle, flags);
 
-	case FFA_MEM_PERM_SET:
+	case FFA_MEM_PERM_SET_SMC32:
+	case FFA_MEM_PERM_SET_SMC64:
 		return ffa_mem_perm_set_handler(smc_fid, secure_origin, x1, x2,
 						x3, x4, cookie, handle, flags);
 
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index 517d6d5..0a6215c 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -147,6 +147,8 @@
 	ec->rt_model = RT_MODEL_DIR_REQ;
 	ec->rt_state = RT_STATE_RUNNING;
 	ec->dir_req_origin_id = FFA_SPMC_ID;
+	/* Expect a direct message response from the SP. */
+	ec->dir_req_funcid = FFA_FNUM_MSG_SEND_DIRECT_REQ;
 
 	rc = spmc_sp_synchronous_entry(ec);
 	if (rc != 0ULL) {
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index f7357f1..d42115d 100644
--- a/services/std_svc/spm/el3_spmc/spmc_setup.c
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -5,14 +5,22 @@
  */
 
 #include <assert.h>
+#include <errno.h>
 #include <string.h>
 
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
+
 #include <context.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#if HOB_LIST
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/hob/mpinfo.h>
+#endif
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <libfdt.h>
@@ -51,6 +59,199 @@
 	SP_MEM_REGION_NOT_SPECIFIED
 };
 
+
+#if HOB_LIST
+static int get_memory_region_info(void *sp_manifest, int mem_region_node,
+		const char *name, uint32_t granularity,
+		uint64_t *base_address, uint32_t *size)
+{
+	char *property;
+	int node, ret;
+
+	if (name != NULL) {
+		node = fdt_subnode_offset_namelen(sp_manifest, mem_region_node,
+				name, strlen(name));
+		if (node < 0) {
+			ERROR("Not found '%s' region in memory regions configuration for SP.\n",
+					name);
+			return -ENOENT;
+		}
+	} else {
+		node = mem_region_node;
+	}
+
+	property = "base-address";
+	ret = fdt_read_uint64(sp_manifest, node, property, base_address);
+	if (ret < 0) {
+		ERROR("Not found property(%s) in memory region(%s).\n",
+				property, name);
+		return -ENOENT;
+	}
+
+	property = "pages-count";
+	ret = fdt_read_uint32(sp_manifest, node, property, size);
+	if (ret < 0) {
+		ERROR("Not found property(%s) in memory region(%s).\n",
+				property, name);
+		return -ENOENT;
+	}
+
+	*size = ((*size) << (PAGE_SIZE_SHIFT + (granularity << 1)));
+
+	return 0;
+}
+
+static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
+		void *sp_manifest, uintptr_t hob_table_start, size_t *hob_table_size)
+{
+	struct efi_hob_handoff_info_table *hob_table;
+	uintptr_t base_address;
+	int mem_region_node;
+	int32_t node, ret;
+	const char *name;
+	uint32_t granularity, size;
+	uint32_t mem_region_num;
+	struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
+	struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
+	struct efi_mmram_descriptor *mmram_desc_data;
+	struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
+
+	if (sp_manifest == NULL || hob_table_size == NULL || *hob_table_size == 0) {
+		return NULL;
+	}
+
+	node = fdt_path_offset(sp_manifest, "/");
+	if (node < 0) {
+		ERROR("Failed to get root in sp_manifest.\n");
+		return NULL;
+	}
+
+	ret = fdt_read_uint32(sp_manifest, node, "xlat-granule", &granularity);
+	if (ret < 0) {
+		ERROR("Not found property(xlat-granule) in sp_manifest.\n");
+		return NULL;
+	}
+
+	if (granularity > 0x02) {
+		ERROR("Invalid granularity value: 0x%x\n", granularity);
+		return NULL;
+	}
+
+	mem_region_node = fdt_subnode_offset_namelen(sp_manifest, 0, "memory-regions",
+			sizeof("memory-regions") - 1);
+	if (node < 0) {
+		ERROR("Not found memory-region configuration for SP.\n");
+		return NULL;
+	}
+
+	INFO("Generating PHIT_HOB...\n");
+
+	hob_table = create_hob_list(BL32_BASE, BL32_LIMIT,
+			hob_table_start, *hob_table_size);
+	if (hob_table == NULL) {
+		ERROR("Failed to create Hob Table.\n");
+		return NULL;
+	}
+
+	/*
+	 * Create fv hob.
+	 */
+	ret = get_memory_region_info(sp_manifest, mem_region_node,
+			"stmm_region", granularity, &base_address, &size);
+	if (ret < 0) {
+		return NULL;
+	}
+
+	if (base_address != BL32_BASE &&
+			base_address + size > BL32_LIMIT) {
+		ERROR("Image is ouf of bound(0x%lx/0x%x), should be in (0x%llx/0x%llx)\n",
+				base_address, size, BL32_BASE, BL32_LIMIT - BL32_BASE);
+		return NULL;
+	}
+
+	ret = create_fv_hob(hob_table, base_address, size);
+	if (ret < 0) {
+		ERROR("Failed to create fv hob... ret:%d\n", ret);
+		return NULL;
+	}
+
+	INFO("Success to create FV hob(0x%lx/0x%x).\n", base_address, size);
+
+	/*
+	 * Create Ns Buffer hob.
+	 */
+	ret = get_memory_region_info(sp_manifest, mem_region_node,
+			"ns_comm_buffer", granularity, &base_address, &size);
+	if (ret < 0) {
+		return NULL;
+	}
+
+	ret = create_guid_hob(hob_table, &ns_buf_guid,
+			sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
+	if (ret < 0) {
+		ERROR("Failed to create ns buffer hob\n");
+		return NULL;
+	}
+
+	mmram_desc_data->physical_start = base_address;
+	mmram_desc_data->physical_size = size;
+	mmram_desc_data->cpu_start = base_address;
+	mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+	/*
+	 * Create mmram_resv hob.
+	 */
+	for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
+			node >= 0;
+			node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
+		ret = get_memory_region_info(sp_manifest, node, NULL, granularity,
+				&base_address, &size);
+		if (ret < 0) {
+			name = fdt_get_name(sp_manifest, node, NULL);
+			ERROR("Invalid memory region(%s) found!\n", name);
+			return NULL;
+		}
+	}
+
+	ret = create_guid_hob(hob_table, &mmram_resv_guid,
+			(sizeof(struct efi_mmram_hob_descriptor_block) +
+			 (sizeof(struct efi_mmram_descriptor) * mem_region_num)),
+			(void **) &mmram_hob_desc_data);
+	if (ret < 0) {
+		ERROR("Failed to create mmram_resv hob. ret: %d\n", ret);
+		return NULL;
+	}
+
+	mmram_hob_desc_data->number_of_mm_reserved_regions = mem_region_num;
+
+	for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
+			node >= 0;
+			node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
+		get_memory_region_info(sp_manifest, node, NULL, granularity,
+				&base_address, &size);
+		name = fdt_get_name(sp_manifest, node, NULL);
+
+		mmram_desc_data = &mmram_hob_desc_data->descriptor[mem_region_num];
+		mmram_desc_data->physical_start = base_address;
+		mmram_desc_data->physical_size = size;
+		mmram_desc_data->cpu_start = base_address;
+
+		if (!strcmp(name, "heap")) {
+			mmram_desc_data->region_state = EFI_CACHEABLE;
+		} else {
+			mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+		}
+	}
+
+	*hob_table_size = hob_table->efi_free_memory_bottom -
+		(efi_physical_address_t) hob_table;
+
+  return hob_table;
+}
+#endif
+
+
+
 /*
  * This function creates a initialization descriptor in the memory reserved
  * for passing boot information to an SP. It then copies the partition manifest
@@ -62,14 +263,13 @@
 {
 	struct ffa_boot_info_header *boot_header;
 	struct ffa_boot_info_desc *boot_descriptor;
-	uintptr_t manifest_addr;
+	uintptr_t content_addr;
 
 	/*
 	 * Calculate the maximum size of the manifest that can be accommodated
 	 * in the boot information memory region.
 	 */
-	const unsigned int
-	max_manifest_sz = sizeof(ffa_boot_info_mem) -
+	size_t max_sz = sizeof(ffa_boot_info_mem) -
 			  (sizeof(struct ffa_boot_info_header) +
 			   sizeof(struct ffa_boot_info_desc));
 
@@ -83,17 +283,6 @@
 		return;
 	}
 
-	/*
-	 * Check if the manifest will fit into the boot info memory region else
-	 * bail.
-	 */
-	if (ep_info->args.arg1 > max_manifest_sz) {
-		WARN("Unable to copy manifest into boot information. ");
-		WARN("Max sz = %u bytes. Manifest sz = %lu bytes\n",
-		     max_manifest_sz, ep_info->args.arg1);
-		return;
-	}
-
 	/* Zero the memory region before populating. */
 	memset(ffa_boot_info_mem, 0, PAGE_SIZE);
 
@@ -125,29 +314,58 @@
 	/* Set the count. Currently 1 since only the manifest is specified. */
 	boot_header->count_boot_info_desc = 1;
 
+	boot_descriptor->flags =
+		FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
+		FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
+
+	content_addr = (uintptr_t) (ffa_boot_info_mem +
+				     boot_header->offset_boot_info_desc +
+				     boot_header->size_boot_info_desc);
+
+#if HOB_LIST
+	/* Populate the boot information descriptor for the hob_list. */
+	boot_descriptor->type =
+		FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
+		FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_HOB);
+
+	content_addr = (uintptr_t) build_sp_boot_hob_list(
+			(void *) ep_info->args.arg0, content_addr, &max_sz);
+	if (content_addr == (uintptr_t) NULL) {
+		WARN("Unable to create phit hob properly.");
+		return;
+	}
+
+	boot_descriptor->size_boot_info = max_sz;
+	boot_descriptor->content = content_addr;
+#else
+	/*
+	 * Check if the manifest will fit into the boot info memory region else
+	 * bail.
+	 */
+	if (ep_info->args.arg1 > max_sz) {
+		WARN("Unable to copy manifest into boot information. ");
+		WARN("Max sz = %lu bytes. Manifest sz = %lu bytes\n",
+		     max_sz, ep_info->args.arg1);
+		return;
+	}
+
 	/* Populate the boot information descriptor for the manifest. */
 	boot_descriptor->type =
 		FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
 		FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT);
 
-	boot_descriptor->flags =
-		FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
-		FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
-
 	/*
 	 * Copy the manifest into boot info region after the boot information
 	 * descriptor.
 	 */
 	boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1;
 
-	manifest_addr = (uintptr_t) (ffa_boot_info_mem +
-				     boot_header->offset_boot_info_desc +
-				     boot_header->size_boot_info_desc);
 
-	memcpy((void *) manifest_addr, (void *) ep_info->args.arg0,
+	memcpy((void *) content_addr, (void *) ep_info->args.arg0,
 	       boot_descriptor->size_boot_info);
 
-	boot_descriptor->content = manifest_addr;
+	boot_descriptor->content = content_addr;
+#endif
 
 	/* Calculate the size of the total boot info blob. */
 	boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc +
@@ -158,7 +376,7 @@
 	INFO("SP boot info @ 0x%lx, size: %u bytes.\n",
 	     (uintptr_t) ffa_boot_info_mem,
 	     boot_header->size_boot_info_blob);
-	INFO("SP manifest @ 0x%lx, size: %u bytes.\n",
+	INFO("SP content @ 0x%lx, size: %u bytes.\n",
 	     boot_descriptor->content,
 	     boot_descriptor->size_boot_info);
 }
@@ -194,6 +412,7 @@
 		out[0] = '\0';
 	} else {
 		memcpy(out, prop, MIN(lenp, (int)len));
+		out[MIN(lenp, (int)len) - 1] = '\0';
 	}
 }
 
@@ -292,10 +511,11 @@
 		sp_mem_regions.base_va = base_address;
 		sp_mem_regions.size = size;
 
-		INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n",
+		INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx mem_attr: 0x%x, attr:0x%x\n",
 		     sp_mem_regions.base_pa,
 		     sp_mem_regions.base_va,
 		     sp_mem_regions.size,
+		     mem_attr,
 		     sp_mem_regions.attr);
 
 		if (type == SP_MEM_REGION_DEVICE) {
@@ -464,7 +684,6 @@
 	}
 
 	spmc_el0_sp_setup_system_registers(sp, ctx);
-
 }
 #endif /* SPMC_AT_EL3_SEL0_SP */
 
diff --git a/services/std_svc/spm/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
index de05459..66ce84c 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -13,6 +13,15 @@
 #include <context.h>
 #include <common/debug.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#if HOB_LIST
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/hob/mpinfo.h>
+#endif
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <platform_def.h>
 #include <plat/common/common_def.h>
@@ -23,6 +32,92 @@
 #include "spm_mm_private.h"
 #include "spm_shim_private.h"
 
+#if HOB_LIST && TRANSFER_LIST
+static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
+		const spm_mm_boot_info_t *sp_boot_info, uint16_t *hob_table_size)
+{
+	int ret;
+	struct efi_hob_handoff_info_table *hob_table;
+	struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
+	struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
+	struct efi_mmram_descriptor *mmram_desc_data;
+	uint16_t mmram_resv_data_size;
+	struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
+	uint64_t hob_table_offset;
+
+	hob_table_offset = sizeof(struct transfer_list_header) +
+		sizeof(struct transfer_list_entry);
+
+	*hob_table_size = 0U;
+
+	hob_table = create_hob_list(sp_boot_info->sp_mem_base,
+			sp_boot_info->sp_mem_limit - sp_boot_info->sp_mem_base,
+			sp_boot_info->sp_shared_buf_base + hob_table_offset,
+			sp_boot_info->sp_shared_buf_size);
+	if (hob_table == NULL) {
+		return NULL;
+	}
+
+	ret = create_fv_hob(hob_table, sp_boot_info->sp_image_base,
+			sp_boot_info->sp_image_size);
+	if (ret) {
+		return NULL;
+	}
+
+	ret = create_guid_hob(hob_table, &ns_buf_guid,
+			sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
+	if (ret) {
+		return NULL;
+	}
+
+	mmram_desc_data->physical_start = sp_boot_info->sp_ns_comm_buf_base;
+	mmram_desc_data->physical_size = sp_boot_info->sp_ns_comm_buf_size;
+	mmram_desc_data->cpu_start = sp_boot_info->sp_ns_comm_buf_base;
+	mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+	mmram_resv_data_size = sizeof(struct efi_mmram_hob_descriptor_block) +
+		sizeof(struct efi_mmram_descriptor) * sp_boot_info->num_sp_mem_regions;
+
+	ret = create_guid_hob(hob_table, &mmram_resv_guid,
+			mmram_resv_data_size, (void **) &mmram_hob_desc_data);
+	if (ret) {
+		return NULL;
+	}
+
+	*hob_table_size = hob_table->efi_free_memory_bottom -
+		(efi_physical_address_t) hob_table;
+
+	mmram_hob_desc_data->number_of_mm_reserved_regions = 4U;
+	mmram_desc_data = &mmram_hob_desc_data->descriptor[0];
+
+	/* First, should be image mm range. */
+	mmram_desc_data[0].physical_start = sp_boot_info->sp_image_base;
+	mmram_desc_data[0].physical_size = sp_boot_info->sp_image_size;
+	mmram_desc_data[0].cpu_start = sp_boot_info->sp_image_base;
+	mmram_desc_data[0].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+	/* Second, should be shared buffer mm range. */
+	mmram_desc_data[1].physical_start = sp_boot_info->sp_shared_buf_base;
+	mmram_desc_data[1].physical_size = sp_boot_info->sp_shared_buf_size;
+	mmram_desc_data[1].cpu_start = sp_boot_info->sp_shared_buf_base;
+	mmram_desc_data[1].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+	/* Ns Buffer mm range */
+	mmram_desc_data[2].physical_start = sp_boot_info->sp_ns_comm_buf_base;
+	mmram_desc_data[2].physical_size = sp_boot_info->sp_ns_comm_buf_size;
+	mmram_desc_data[2].cpu_start = sp_boot_info->sp_ns_comm_buf_base;
+	mmram_desc_data[2].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+	/* Heap mm range */
+	mmram_desc_data[3].physical_start = sp_boot_info->sp_heap_base;
+	mmram_desc_data[3].physical_size = sp_boot_info->sp_heap_size;
+	mmram_desc_data[3].cpu_start = sp_boot_info->sp_heap_base;
+	mmram_desc_data[3].region_state = EFI_CACHEABLE;
+
+	return hob_table;
+}
+#endif
+
 /* Setup context of the Secure Partition */
 void spm_sp_setup(sp_context_t *sp_ctx)
 {
@@ -32,6 +127,15 @@
 	const spm_mm_boot_info_t *sp_boot_info =
 			plat_get_secure_partition_boot_info(NULL);
 
+#if HOB_LIST && TRANSFER_LIST
+	struct efi_hob_handoff_info_table *hob_table;
+	struct transfer_list_header *sp_boot_tl;
+	struct transfer_list_entry *sp_boot_te;
+	uint16_t hob_table_size;
+#endif
+
+	assert(sp_boot_info != NULL);
+
 	/*
 	 * Initialize CPU context
 	 * ----------------------
@@ -195,7 +299,35 @@
 	 * Prepare information in buffer shared between EL3 and S-EL0
 	 * ----------------------------------------------------------
 	 */
+#if HOB_LIST && TRANSFER_LIST
+	sp_boot_tl = transfer_list_init((void *) sp_boot_info->sp_shared_buf_base,
+			sp_boot_info->sp_shared_buf_size);
+	assert(sp_boot_tl != NULL);
 
+	hob_table = build_sp_boot_hob_list(sp_boot_info, &hob_table_size);
+	assert(hob_table != NULL);
+
+	transfer_list_update_checksum(sp_boot_tl);
+
+	sp_boot_te = transfer_list_add(sp_boot_tl, TL_TAG_HOB_LIST,
+			hob_table_size, hob_table);
+	if (sp_boot_te == NULL) {
+		ERROR("Failed to add HOB list to xfer list\n");
+	}
+
+	transfer_list_set_handoff_args(sp_boot_tl, &ep_info);
+
+	transfer_list_dump(sp_boot_tl);
+
+	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0,
+			ep_info.args.arg0);
+	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1,
+			ep_info.args.arg1);
+	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2,
+			ep_info.args.arg2);
+	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3,
+			ep_info.args.arg3);
+#else
 	void *shared_buf_ptr = (void *) sp_boot_info->sp_shared_buf_base;
 
 	/* Copy the boot information into the shared buffer with the SP. */
@@ -205,7 +337,6 @@
 	assert(sp_boot_info->sp_shared_buf_base <=
 				(UINTPTR_MAX - sp_boot_info->sp_shared_buf_size + 1));
 
-	assert(sp_boot_info != NULL);
 
 	memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
 	       sizeof(spm_mm_boot_info_t));
@@ -256,4 +387,5 @@
 		if (plat_my_core_pos() == sp_mp_info[index].linear_id)
 			sp_mp_info[index].flags |= MP_INFO_FLAG_PRIMARY_CPU;
 	}
+#endif
 }
diff --git a/tools/amlogic/Makefile b/tools/amlogic/Makefile
index 7bfee7d..cdaf7e7 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -1,5 +1,6 @@
 #
 # Copyright (C) 2019 Remi Pommarel <repk@triplefau.lt>
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier:     BSD-3-Clause
 # https://spdx.org/licenses
@@ -7,11 +8,10 @@
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
-PROJECT := doimage${BIN_EXT}
+PROJECT := doimage$(.exe)
 OBJECTS := doimage.o
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
@@ -38,6 +38,6 @@
 	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+	$(q)rm -rf $(PROJECT) $(OBJECTS)
 
 distclean: clean
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index ce12a66..e403b2d 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,18 +1,17 @@
 #
-# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 PLAT		:= none
 DEBUG		:= 0
-CRTTOOL		?= cert_create${BIN_EXT}
+CRTTOOL		?= cert_create$(.exe)
 BINARY		:= $(notdir ${CRTTOOL})
 COT		:= tbbr
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
@@ -95,7 +94,7 @@
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL,${OBJECTS})
+	$(q)rm -rf $(OBJECTS)
 
 realclean: clean
-	$(call SHELL_DELETE,${BINARY})
+	$(q)rm -f $(BINARY)
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index f7adfab..83a7b18 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -45,8 +45,8 @@
 	{ 2048, 1024, 3072, 4096 },	/* KEY_ALG_RSA */
 #ifndef OPENSSL_NO_EC
 	{ 256, 384 },			/* KEY_ALG_ECDSA_NIST */
-	{},				/* KEY_ALG_ECDSA_BRAINPOOL_R */
-	{}				/* KEY_ALG_ECDSA_BRAINPOOL_T */
+	{ 256 },			/* KEY_ALG_ECDSA_BRAINPOOL_R */
+	{ 256 }				/* KEY_ALG_ECDSA_BRAINPOOL_T */
 #endif /* OPENSSL_NO_EC */
 };
 
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 190c096..4fc0add 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -17,6 +17,7 @@
 #include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <openssl/ssl.h>
 
 #include "cert.h"
 #include "cmd_opt.h"
@@ -214,6 +215,13 @@
 	EVP_PKEY *pkey;
 	ENGINE *e;
 
+#if !USING_OPENSSL3
+	if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) {
+		fprintf(stderr, "Failed to init SSL\n");
+		return NULL;
+	}
+#endif
+
 	ENGINE_load_builtin_engines();
 	e = ENGINE_by_id("pkcs11");
 	if (!e) {
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index 56cb21a..9975ea3 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "conventional-changelog-tf-a",
-  "version": "2.11.0",
+  "version": "2.12.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/cot_dt2c/poetry.lock b/tools/cot_dt2c/poetry.lock
index df58d54..eea96cd 100644
--- a/tools/cot_dt2c/poetry.lock
+++ b/tools/cot_dt2c/poetry.lock
@@ -1,35 +1,6 @@
 # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
 
 [[package]]
-name = "atomicwrites"
-version = "1.4.1"
-description = "Atomic file writes."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
-    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
-]
-
-[[package]]
-name = "attrs"
-version = "24.2.0"
-description = "Classes Without Boilerplate"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
-    {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
-]
-
-[package.extras]
-benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
-tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
-
-[[package]]
 name = "click"
 version = "8.1.7"
 description = "Composable command line interface toolkit"
@@ -55,6 +26,20 @@
 ]
 
 [[package]]
+name = "exceptiongroup"
+version = "1.2.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
+    {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
 name = "igraph"
 version = "0.11.6"
 description = "High performance graph data structures and algorithms"
@@ -218,17 +203,6 @@
 testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
-name = "py"
-version = "1.11.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
-    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
-    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
-]
-
-[[package]]
 name = "pydevicetree"
 version = "0.0.13"
 description = "A library for parsing Devicetree Source v1"
@@ -258,27 +232,25 @@
 
 [[package]]
 name = "pytest"
-version = "6.2.5"
+version = "8.3.4"
 description = "pytest: simple powerful testing with Python"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
 files = [
-    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
-    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
+    {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
+    {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
 ]
 
 [package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
-attrs = ">=19.2.0"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
 iniconfig = "*"
 packaging = "*"
-pluggy = ">=0.12,<2.0"
-py = ">=1.8.2"
-toml = "*"
+pluggy = ">=1.5,<2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
 
 [package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
 
 [[package]]
 name = "tenacity"
@@ -318,6 +290,47 @@
 ]
 
 [[package]]
+name = "tomli"
+version = "2.2.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+    {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+    {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+    {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+    {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+    {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+    {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+    {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+    {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
+]
+
+[[package]]
 name = "typing-extensions"
 version = "4.12.2"
 description = "Backported and Experimental Type Hints for Python 3.8+"
@@ -331,4 +344,4 @@
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "afa5cb49be96467a848bab753a630c6f5ec42d6750d67d29920c3e3971774e36"
+content-hash = "0f5b2b008bb5de8545881eaeacfdd1a6fe50e5271feea4635d622ffce9e550dc"
diff --git a/tools/cot_dt2c/pyproject.toml b/tools/cot_dt2c/pyproject.toml
index 73251d7..fc31d54 100644
--- a/tools/cot_dt2c/pyproject.toml
+++ b/tools/cot_dt2c/pyproject.toml
@@ -38,7 +38,7 @@
 
 [tool.poetry.group.dev.dependencies]
 mypy = "^0.910"
-pytest = "^6.2.5"
+pytest = "^8.3.4"
 
 [tool.mypy]
 # https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 50b0fa2..14def1d 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2024, Arm Limited. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited. All rights reserved.
 # Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -7,13 +7,12 @@
 
 BUILD_INFO	?= 1
 DEBUG		:= 0
-ENCTOOL		?= encrypt_fw${BIN_EXT}
+ENCTOOL		?= encrypt_fw$(.exe)
 BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
@@ -75,7 +74,7 @@
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL,${OBJECTS})
+	$(q)rm -rf $(OBJECTS)
 
 realclean: clean
-	$(call SHELL_DELETE,${BINARY})
+	$(q)rm -f $(BINARY)
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
index 6e43e73..b6246f6 100644
--- a/tools/encrypt_fw/src/main.c
+++ b/tools/encrypt_fw/src/main.c
@@ -26,7 +26,9 @@
 
 /* Global options */
 
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
 static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
+#endif
 
 static char *key_algs_str[] = {
 	[KEY_ALG_GCM] = "gcm",
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 54dee87..a660a50 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,17 +1,16 @@
 #
-# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
-FIPTOOL ?= fiptool${BIN_EXT}
+FIPTOOL ?= fiptool$(.exe)
 PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
 STATIC ?= 0
@@ -93,4 +92,4 @@
 endif # STATIC
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} $(DEPS))
+	$(q)rm -rf $(PROJECT) $(OBJECTS) $(DEPS)
diff --git a/tools/fiptool/Makefile.msvc b/tools/fiptool/Makefile.msvc
deleted file mode 100644
index 9081bc6..0000000
--- a/tools/fiptool/Makefile.msvc
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-CC = cl.exe
-LD = link.exe
-
-# FIPTOOLPATH and FIPTOOL are passed from the main makefile.
-
-OBJECTS = $(FIPTOOLPATH)\fiptool.obj     \
-          $(FIPTOOLPATH)\tbbr_config.obj \
-          $(FIPTOOLPATH)\win_posix.obj
-
-INC = -I$(FIPTOOLPATH) -Iinclude\tools_share
-
-CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT
-
-all: $(FIPTOOL)
-
-$(FIPTOOL): $(OBJECTS)
-	$(LD) /nologo /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $**
-
-.PHONY: clean realclean
-
-clean:
-	-@del /f /q $(OBJECTS) > nul
-	-@del /f /q $(FIPTOOLPATH)\*.pdb > nul
-
-realclean:
-	-@del /f /q $(OBJECTS) > nul
-	-@del /f /q $(FIPTOOLPATH)\*.pdb > nul
-	-@del /f /q $(FIPTOOL) > nul
-
-.c.obj:
-	$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index 22aa921..965cc51 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -1,18 +1,18 @@
 #
 # Copyright 2018-2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 MAKE_HELPERS_DIRECTORY := ../../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
-PROJECT_1 := create_pbl${BIN_EXT}
+PROJECT_1 := create_pbl$(.exe)
 OBJECTS_1 := create_pbl.o
-PROJECT_2 := byte_swap${BIN_EXT}
+PROJECT_2 := byte_swap$(.exe)
 OBJECTS_2 := byte_swap.o
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
@@ -49,5 +49,5 @@
 	$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT_1} ${OBJECTS_1})
-	$(call SHELL_DELETE_ALL, ${PROJECT_2} ${OBJECTS_2})
+	$(q)rm -rf $(PROJECT_1) $(OBJECTS_1)
+	$(q)rm -rf $(PROJECT_2) $(OBJECTS_2)
diff --git a/tools/nxp/create_pbl/create_pbl.mk b/tools/nxp/create_pbl/create_pbl.mk
index 305c049..81f6d13 100644
--- a/tools/nxp/create_pbl/create_pbl.mk
+++ b/tools/nxp/create_pbl/create_pbl.mk
@@ -1,12 +1,13 @@
 #
 # Copyright 2018-2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #
 
-CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
 
 HOST_GCC	:= gcc
 
diff --git a/tools/nxp/create_pbl/pbl_ch2.mk b/tools/nxp/create_pbl/pbl_ch2.mk
index bf05a12..47ff892 100644
--- a/tools/nxp/create_pbl/pbl_ch2.mk
+++ b/tools/nxp/create_pbl/pbl_ch2.mk
@@ -1,12 +1,13 @@
 #
 # Copyright 2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #
 
-CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
 
 HOST_GCC	:= gcc
 
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index 15129e4..f5d42cd 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -1,13 +1,14 @@
 #
 # Copyright 2018-2022 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #
 SHELL=/bin/bash
 
-CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL	?=	${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP	?=	${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
 
 HOST_GCC	:= gcc
 
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index 7a64b19..f89f379 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -102,7 +102,7 @@
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
 $(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
-	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
 
 $(FILE_NAME_SA6).srec: $(OUTPUT_FILE_SA6) | $$(@D)/
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
@@ -111,7 +111,7 @@
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
 
 $(OUTPUT_FILE_SA6): $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) | $$(@D)/
-	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
 
 ###################################################
 # Compile
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index 0da5c09..f579a42 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -1,16 +1,15 @@
 #
-# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
-SPTOOL  ?= sptool${BIN_EXT}
+SPTOOL  ?= sptool$(.exe)
 PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
 
@@ -40,4 +39,4 @@
 	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+	$(q)rm -rf $(PROJECT) $(OBJECTS)
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index 453daae..64b6ccf 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -1,16 +1,15 @@
 #
-# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
-PROJECT := stm32image${BIN_EXT}
+PROJECT := stm32image$(.exe)
 OBJECTS := stm32image.o
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
@@ -37,6 +36,6 @@
 	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
-	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+	$(q)rm -rf $(PROJECT) $(OBJECTS)
 
 distclean: clean
diff --git a/tools/tlc/poetry.lock b/tools/tlc/poetry.lock
index decec59..ea1b750 100644
--- a/tools/tlc/poetry.lock
+++ b/tools/tlc/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
 
 [[package]]
 name = "astroid"
@@ -495,13 +495,13 @@
 
 [[package]]
 name = "jinja2"
-version = "3.1.4"
+version = "3.1.5"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
-    {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
+    {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
+    {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
 ]
 
 [package.dependencies]
@@ -1331,13 +1331,13 @@
 
 [[package]]
 name = "virtualenv"
-version = "20.26.5"
+version = "20.26.6"
 description = "Virtual Python Environment builder"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6"},
-    {file = "virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4"},
+    {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
+    {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
 ]
 
 [package.dependencies]
@@ -1431,4 +1431,4 @@
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "aac9123f3fa544b8c3e9b085f41f5a1c6c4ed2d59ce3236dcda6ea2aef5a694c"
+content-hash = "a4b9c3bababadba14f49a8de0ccee1f5a141b6cea23d02a19ab8bf4f8c45533f"
diff --git a/tools/tlc/pyproject.toml b/tools/tlc/pyproject.toml
index b606238..e9ff26f 100644
--- a/tools/tlc/pyproject.toml
+++ b/tools/tlc/pyproject.toml
@@ -39,7 +39,7 @@
 click = "^8.1.7"
 pyyaml = "^6.0.1"
 tox = "^4.18.0"
-jinja2 = "^3.1.4"
+jinja2 = "^3.1.5"
 
 [tool.poetry.group.dev]
 optional = true
diff --git a/tools/tlc/tests/conftest.py b/tools/tlc/tests/conftest.py
index b8f88b5..93e44a9 100644
--- a/tools/tlc/tests/conftest.py
+++ b/tools/tlc/tests/conftest.py
@@ -9,6 +9,8 @@
 
 """ Common configurations and fixtures for test environment."""
 
+from random import randint
+
 import pytest
 import yaml
 from click.testing import CliRunner
@@ -16,6 +18,10 @@
 from tlc.cli import cli
 
 
+def generate_random_bytes(n):
+    return bytes([randint(0, 255) for _ in range(n)])
+
+
 @pytest.fixture
 def tmptlstr(tmpdir):
     return tmpdir.join("tl.bin").strpath
@@ -63,10 +69,27 @@
 def tlcrunner(tmptlstr):
     runner = CliRunner()
     with runner.isolated_filesystem():
-        runner.invoke(cli, ["create", tmptlstr])
+        runner.invoke(cli, ["create", "--size", 0x1F000, tmptlstr])
     return runner
 
 
 @pytest.fixture
 def tlc_entries(tmpfdt):
     return [(0, "/dev/null"), (1, tmpfdt.strpath), (0x102, tmpfdt.strpath)]
+
+
+@pytest.fixture
+def random_entry():
+    def _random_entry(max_size):
+        return randint(0, 0xFFFFFF), generate_random_bytes(randint(0, max_size))
+
+    return _random_entry
+
+
+@pytest.fixture
+def random_entries(random_entry):
+    def _random_entries(n=5, max_size=0x100):
+        for _ in range(n):
+            yield random_entry(max_size)
+
+    return _random_entries
diff --git a/tools/tlc/tests/test_cli.py b/tools/tlc/tests/test_cli.py
index a5ef30e..ebe1f6a 100644
--- a/tools/tlc/tests/test_cli.py
+++ b/tools/tlc/tests/test_cli.py
@@ -17,6 +17,7 @@
 import pytest
 import yaml
 from click.testing import CliRunner
+from conftest import generate_random_bytes
 
 from tlc.cli import cli
 from tlc.te import TransferEntry
@@ -32,6 +33,22 @@
     assert TransferList.fromfile(test_file) is not None
 
 
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_create_with_align(align, tlcrunner, tmpdir):
+    tl_file = tmpdir.join("tl.bin").strpath
+    tlcrunner.invoke(cli, ["create", "-s", "10000", "-a", align, tl_file])
+
+    blob = tmpdir.join("blob.bin")
+
+    blob.write_binary(generate_random_bytes(0x200))
+    tlcrunner.invoke(cli, ["add", "--entry", 1, blob.strpath, tl_file])
+
+    tl = TransferList.fromfile(tl_file)
+    te = tl.entries[-1]
+    assert tl.alignment == align
+    assert (te.offset + te.hdr_size) % (1 << align) == 0
+
+
 def test_create_with_fdt(tmpdir):
     runner = CliRunner()
     fdt = tmpdir.join("fdt.dtb")
@@ -69,6 +86,20 @@
     assert len(tl.entries) == len(tlc_entries)
 
 
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_cli_add_entry_with_align(align, tlcrunner, tmpdir, tmptlstr):
+    blob = tmpdir.join("blob.bin")
+    blob.write_binary(bytes(0x100))
+
+    tlcrunner.invoke(cli, ["add", "--align", align, "--entry", 1, blob, tmptlstr])
+    tl = TransferList.fromfile(tmptlstr)
+    te = tl.entries[-1]
+
+    print(tl, *(te for te in tl.entries), sep="\n---------------\n")
+    assert (te.offset + te.hdr_size) % (1 << align) == 0
+    assert tl.alignment == align
+
+
 def test_info(tlcrunner, tmptlstr, tmpfdt):
     tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
     tlcrunner.invoke(cli, ["add", "--fdt", tmpfdt.strpath, tmptlstr])
diff --git a/tools/tlc/tests/test_transfer_list.py b/tools/tlc/tests/test_transfer_list.py
index e8c430e..6900b41 100644
--- a/tools/tlc/tests/test_transfer_list.py
+++ b/tools/tlc/tests/test_transfer_list.py
@@ -9,6 +9,7 @@
 """Contains unit tests for the types TransferEntry and TransferList."""
 
 import math
+from random import randint
 
 import pytest
 
@@ -49,15 +50,39 @@
         assert tl.checksum == csum
 
 
-@pytest.mark.parametrize(("tag_id", "data"), test_entries)
-def test_add_transfer_entry(tag_id, data):
+def test_add_transfer_entry(random_entries):
     tl = TransferList(0x1000)
-    te = TransferEntry(tag_id, len(data), data)
 
-    tl.add_transfer_entry(tag_id, data)
-
+    # Add a single entry and check it's in the list of entries
+    te = tl.add_transfer_entry(1, bytes(100))
     assert te in tl.entries
-    assert tl.size == TransferList.hdr_size + te.size
+    assert tl.size % 8 == 0
+
+    # Add a range of tag id's
+    for id, data in random_entries(50, 1):
+        te = tl.add_transfer_entry(id, data)
+        assert te in tl.entries
+        assert tl.size % 8 == 0
+
+
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_add_transfer_entry_with_align(align, random_entries, random_entry):
+    tl = TransferList(0xF00000)
+    id, data = random_entry(4)
+
+    tl.add_transfer_entry(id, data)
+
+    # Add an entry with a larger alignment requirement
+    _, data = random_entry(4)
+    te = tl.add_transfer_entry(1, data, data_align=align)
+    assert (te.offset + te.hdr_size) % (1 << align) == 0
+    assert tl.alignment == align
+
+    # Add some more entries and ensure the alignment is preserved
+    for id, data in random_entries(5, 0x200):
+        te = tl.add_transfer_entry(id, data, data_align=align)
+        assert (te.offset + te.hdr_size) % (1 << align) == 0
+        assert tl.alignment == align
 
 
 @pytest.mark.parametrize(
@@ -88,12 +113,19 @@
     assert te.sum_of_bytes == csum
 
 
-@pytest.mark.parametrize(("tag_id", "data"), test_entries)
-def test_calculate_tl_checksum(tag_id, data):
+def test_calc_tl_checksum(tmpdir, random_entries):
+    tl_file = tmpdir.join("tl.bin")
+
     tl = TransferList(0x1000)
 
-    tl.add_transfer_entry(tag_id, data)
-    assert tl.sum_of_bytes() == 0
+    for id, data in random_entries(10):
+        tl.add_transfer_entry(id, data)
+
+    assert sum(tl.to_bytes()) % 256 == 0
+
+    # Write the transfer list to a file and check that the sum of bytes is 0
+    tl.write_to_file(tl_file)
+    assert sum(tl_file.read_binary()) % 256 == 0
 
 
 def test_empty_transfer_list_blob(tmpdir):
@@ -125,28 +157,44 @@
         assert f.read(te.data_size) == te.data
 
 
-def test_multiple_te_transfer_list(tmpdir):
+def test_write_multiple_tes_to_file(tmpdir, random_entries, random_entry):
     """Check that we can create a TL with multiple TE's."""
     test_file = tmpdir.join("test_tl_blob.bin")
-    tl = TransferList(0x1000)
+    tl = TransferList(0x4000)
+    _test_entries = list(random_entries())
 
-    for tag_id, data in test_entries:
+    for tag_id, data in _test_entries:
         tl.add_transfer_entry(tag_id, data)
 
+    # Add a few entries with special alignment requirements
+    blob_id, blob = random_entry(0x200)
+    tl.add_transfer_entry(blob_id, blob, data_align=12)
+
     tl.write_to_file(test_file)
 
     with open(test_file, "rb") as f:
         assert f.read(tl.hdr_size) == tl.header_to_bytes()
         # Ensure that TE's have the correct alignment
-        for tag_id, data in test_entries:
-            f.seek(int(math.ceil(f.tell() / 2**tl.alignment) * 2**tl.alignment))
-            print(f.tell())
+        for tag_id, data in _test_entries:
+            f.seek(int(math.ceil(f.tell() / 8) * 8))
+
             assert int.from_bytes(f.read(3), "little") == tag_id
             assert int.from_bytes(f.read(1), "little") == TransferEntry.hdr_size
             # Make sure the data in the TE matches the data in the original case
             data_size = int.from_bytes(f.read(4), "little")
             assert f.read(data_size) == data
 
+        f.seek(int(math.ceil(f.tell() / (1 << 12)) * (1 << 12)) - 8)
+        assert int.from_bytes(f.read(3), "little") == blob_id
+        assert int.from_bytes(f.read(1), "little") == TransferEntry.hdr_size
+        # Make sure the data in the TE matches the data in the original case
+        data_size = int.from_bytes(f.read(4), "little")
+        assert f.read(data_size) == blob
+
+        # padding is added to align TE's, make sure padding is added to the size of
+        # the TL by checking we don't overflow.
+        assert f.tell() <= tl.size
+
 
 def test_read_empty_transfer_list_from_file(tmpdir):
     test_file = tmpdir.join("test_tl_blob.bin")
@@ -196,19 +244,17 @@
     assert tl.sum_of_bytes() == 0
 
 
-@pytest.mark.parametrize("tag", [tag for tag, _ in test_entries])
-def test_remove_tag_from_file(tag):
-    tl = TransferList(0x1000)
+def test_remove_tag(random_entry):
+    """Adds a transfer entry and remove it, size == transfer list header."""
+    tl = TransferList(0x100)
+    id, data = random_entry(tl.total_size // 2)
 
-    for tag_id, data in test_entries:
-        tl.add_transfer_entry(tag_id, data)
+    te = tl.add_transfer_entry(id, data)
+    assert te in tl.entries
 
-    removed_entries = list(filter(lambda te: te.id == tag, tl.entries))
-    original_size = tl.size
-    tl.remove_tag(tag)
-
-    assert not any(tag == te.id for te in tl.entries)
-    assert tl.size == original_size - sum(map(lambda te: te.size, removed_entries))
+    tl.remove_tag(id)
+    assert not tl.get_entry(id) and te not in tl.entries
+    assert tl.size == tl.hdr_size
 
 
 def test_get_fdt_offset(tmpdir):
diff --git a/tools/tlc/tlc/cli.py b/tools/tlc/tlc/cli.py
index 3d60938..431af04 100644
--- a/tools/tlc/tlc/cli.py
+++ b/tools/tlc/tlc/cli.py
@@ -27,6 +27,14 @@
 @cli.command()
 @click.argument("filename", type=click.Path(dir_okay=False))
 @click.option(
+    "-a",
+    "--align",
+    type=int,
+    default=3,
+    show_default=True,
+    help="Set alignment in powers of 2 (e.g., -a 3 for 8 byte alignment).",
+)
+@click.option(
     "-s", "--size", default=0x1000, type=int, help="Maximum size of the Transfer List"
 )
 @click.option(
@@ -51,7 +59,7 @@
     type=click.Path(exists=True),
     help="Create the transfer list from a YAML config file.",
 )
-def create(filename, size, fdt, entry, flags, from_yaml):
+def create(filename, align, size, fdt, entry, flags, from_yaml):
     """Create a new Transfer List."""
     try:
         if from_yaml:
@@ -60,12 +68,12 @@
 
             tl = TransferList.from_dict(config)
         else:
-            tl = TransferList(size)
+            tl = TransferList(size, flags=flags, alignment=align)
 
             entry = (*entry, (1, fdt)) if fdt else entry
 
             for id, path in entry:
-                tl.add_transfer_entry_from_file(id, path)
+                tl.add_transfer_entry_from_file(id, path, data_align=align)
     except MemoryError as mem_excp:
         raise MemoryError(
             "TL max size exceeded, consider increasing with the option -s"
@@ -133,19 +141,24 @@
 
 
 @cli.command()
-@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "-a",
+    "--align",
+    type=int,
+    help="Set alignment in powers of 2 (e.g., -a 3 for 8 byte alignment).",
+)
 @click.option(
     "--entry",
     type=(int, click.Path(exists=True)),
     multiple=True,
     help="A tag ID and the corresponding path to a binary blob in the form <id> <path-to-blob>.",
 )
-def add(filename, entry):
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+def add(align, entry, filename):
     """Update an existing Transfer List with given images."""
     tl = TransferList.fromfile(filename)
-
     for id, path in entry:
-        tl.add_transfer_entry_from_file(id, path)
+        tl.add_transfer_entry_from_file(id, path, data_align=align)
 
     tl.write_to_file(filename)
 
diff --git a/tools/tlc/tlc/te.py b/tools/tlc/tlc/te.py
index cf7aa67..0b6b532 100644
--- a/tools/tlc/tlc/te.py
+++ b/tools/tlc/tlc/te.py
@@ -48,7 +48,10 @@
 
     @property
     def sum_of_bytes(self) -> int:
-        return (sum(self.header_to_bytes()) + sum(self.data)) % 256
+        return sum(self.to_bytes()) % 256
+
+    def to_bytes(self) -> bytes:
+        return self.header_to_bytes() + self.data
 
     def header_to_bytes(self) -> bytes:
         return self.id.to_bytes(3, "little") + struct.pack(
diff --git a/tools/tlc/tlc/tl.py b/tools/tlc/tlc/tl.py
index 98d2205..dfbea9f 100644
--- a/tools/tlc/tlc/tl.py
+++ b/tools/tlc/tlc/tl.py
@@ -83,13 +83,17 @@
     hdr_size = 0x18
     signature = 0x4A0FB10B
     version = 1
+    granule = 8
 
     def __init__(
-        self, max_size: int = hdr_size, flags: int = TRANSFER_LIST_ENABLE_CHECKSUM
+        self,
+        max_size: int = hdr_size,
+        flags: int = TRANSFER_LIST_ENABLE_CHECKSUM,
+        alignment: int = 3,
     ) -> None:
         assert max_size >= self.hdr_size
         self.checksum: int = 0
-        self.alignment: int = 3
+        self.alignment: int = alignment
         self.size = self.hdr_size
         self.total_size = max_size
         self.flags = flags
@@ -138,16 +142,15 @@
                     # the 3-byte wide ID as a 4-byte uint, shift out this padding
                     # once we have the id.
                     te_base = f.tell()
-                    (id, hdr_size, data_size) = struct.unpack(
+                    (id, _, data_size) = struct.unpack(
                         TransferEntry.encoding[0] + "I" + TransferEntry.encoding[1:],
                         b"\x00" + f.read(TransferEntry.hdr_size),
                     )
 
                     id >>= 8
-
                     te = tl.add_transfer_entry(id, f.read(data_size))
                     te.offset = te_base
-                    f.seek(align(te_base + hdr_size + data_size, 2**tl.alignment))
+                    f.seek(align(f.tell(), tl.granule))
 
         return tl
 
@@ -163,10 +166,14 @@
         # get settings from config and set defaults
         max_size = config.get("max_size", 0x1000)
         has_checksum = config.get("has_checksum", True)
+        align = config.get("alignment", None)
 
         flags = TRANSFER_LIST_ENABLE_CHECKSUM if has_checksum else 0
 
-        tl = cls(max_size, flags)
+        if align:
+            tl = cls(max_size, flags, alignment=align)
+        else:
+            tl = cls(max_size, flags)
 
         for entry in config["entries"]:
             tl.add_transfer_entry_from_dict(entry)
@@ -189,13 +196,15 @@
 
     def update_checksum(self) -> None:
         """Calculates the checksum based on the sum of bytes."""
-        self.checksum = 256 - ((self.sum_of_bytes() - self.checksum) % 256)
+        self.checksum = (256 - (self.sum_of_bytes() - self.checksum)) % 256
+        assert self.checksum <= 0xFF
+
+    def to_bytes(self) -> bytes:
+        return self.header_to_bytes() + b"".join([te.to_bytes() for te in self.entries])
 
     def sum_of_bytes(self) -> int:
         """Sum of all bytes between the base address and the end of that last TE (modulo 0xff)."""
-        return (
-            sum(self.header_to_bytes()) + sum(te.sum_of_bytes for te in self.entries)
-        ) % 256
+        return (sum(self.to_bytes())) % 256
 
     def get_entry(self, tag_id: int) -> Optional[TransferEntry]:
         for te in self.entries:
@@ -213,18 +222,35 @@
 
         return te.offset + te.hdr_size
 
-    def add_transfer_entry(self, tag_id: int, data: bytes) -> TransferEntry:
+    def add_transfer_entry(
+        self, tag_id: int, data: bytes, data_align: int = 0
+    ) -> TransferEntry:
         """Appends a TransferEntry into the internal list of TE's."""
+        data_offset = TransferEntry.hdr_size + self.size
+        data_align = self.alignment if not data_align else data_align
+
+        aligned_data_offset = align(data_offset, 1 << data_align)
+
+        if tag_id != 0 and data_offset != aligned_data_offset:
+            void_len = aligned_data_offset - data_offset - TransferEntry.hdr_size
+            self.add_transfer_entry(0, bytes(void_len))
+
+        assert align(self.size, self.granule)
+
         if not (self.total_size >= self.size + TransferEntry.hdr_size + len(data)):
             raise MemoryError(
                 f"TL size has exceeded the maximum allocation {self.total_size}."
             )
-        else:
-            te = TransferEntry(tag_id, len(data), data)
-            self.entries.append(te)
-            self.size += te.size
-            self.update_checksum()
-            return te
+
+        te = TransferEntry(tag_id, len(data), data, offset=self.size)
+        self.entries.append(te)
+
+        self.size += align(te.size, self.granule)
+        if data_align > self.alignment:
+            self.alignment = data_align
+
+        self.update_checksum()
+        return te
 
     def add_transfer_entry_from_struct_format(
         self, tag_id: int, struct_format: str, *args: Any
@@ -305,32 +331,40 @@
         tag_id = entry["tag_id"]
         if tag_id in tag_name_to_tag_id:
             tag_id = tag_name_to_tag_id[tag_id]
-        te_format = transfer_entry_formats[tag_id]
-        tag_name = te_format["tag_name"]
+
+        align = entry.get("alignment", None)
 
         if "blob_file_path" in entry:
-            return self.add_transfer_entry_from_file(tag_id, entry["blob_file_path"])
-        elif tag_name == "tpm_event_log_table":
-            with open(entry["event_log"], "rb") as f:
-                event_log_data = f.read()
-
-            flags_bytes = entry["flags"].to_bytes(4, "little")
-            data = flags_bytes + event_log_data
-
-            return self.add_transfer_entry(tag_id, data)
-        elif tag_name == "exec_ep_info":
-            return self.add_entry_point_info_transfer_entry(entry)
-        elif "format" in te_format and "fields" in te_format:
-            fields = [entry[field] for field in te_format["fields"]]
-            return self.add_transfer_entry_from_struct_format(
-                tag_id, te_format["format"], *fields
+            return self.add_transfer_entry_from_file(
+                tag_id, entry["blob_file_path"], data_align=align
             )
         else:
-            raise ValueError(f"Invalid transfer entry {entry}.")
+            te_format = transfer_entry_formats[tag_id]
+            tag_name = te_format["tag_name"]
 
-    def add_transfer_entry_from_file(self, tag_id: int, path: Path) -> TransferEntry:
+            if tag_name == "tpm_event_log_table":
+                with open(entry["event_log"], "rb") as f:
+                    event_log_data = f.read()
+
+                flags_bytes = entry["flags"].to_bytes(4, "little")
+                data = flags_bytes + event_log_data
+
+                return self.add_transfer_entry(tag_id, data, data_align=align)
+            elif tag_name == "exec_ep_info":
+                return self.add_entry_point_info_transfer_entry(entry)
+            elif "format" in te_format and "fields" in te_format:
+                fields = [entry[field] for field in te_format["fields"]]
+                return self.add_transfer_entry_from_struct_format(
+                    tag_id, te_format["format"], *fields
+                )
+            else:
+                raise ValueError(f"Invalid transfer entry {entry}.")
+
+    def add_transfer_entry_from_file(
+        self, tag_id: int, path: Path, data_align: int = 0
+    ) -> TransferEntry:
         with open(path, "rb") as f:
-            return self.add_transfer_entry(tag_id, f.read())
+            return self.add_transfer_entry(tag_id, f.read(), data_align=data_align)
 
     def write_to_file(self, file: Path) -> None:
         """Write the contents of the TL to a file."""
@@ -338,20 +372,11 @@
             f.write(self.header_to_bytes())
             for te in self.entries:
                 assert f.tell() + te.hdr_size + te.data_size < self.total_size
-                te_base = f.tell()
+
                 f.write(te.header_to_bytes())
                 f.write(te.data)
-                # Ensure the next TE has the correct alignment
-                f.write(
-                    bytes(
-                        (
-                            align(
-                                te_base + te.hdr_size + te.data_size, 2**self.alignment
-                            )
-                            - f.tell()
-                        )
-                    )
-                )
+                # Ensure the next TE is at an 8-byte aligned address
+                f.write(bytes((align(f.tell(), self.granule) - f.tell())))
 
     def remove_tag(self, tag: int) -> None:
         self.entries = list(filter(lambda te: te.id != tag, self.entries))