Merge "fix(nxp-sfp): shift gpio register offsets by 2" into integration
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 7b6a1f5..2d1afab 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,4 +1,4 @@
-# Copyright (c) 2023, Arm Limited. All rights reserved
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,9 +19,8 @@
   jobs:
     post_create_environment:
       - pip install poetry=="1.3.2"
-      - poetry config virtualenvs.create false
     post_install:
-      - poetry install --with doc
+      - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs
 
 sphinx:
   configuration: docs/conf.py
diff --git a/Makefile b/Makefile
index 2ba4fa7..baf8431 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 10
+VERSION_MINOR			:= 11
 # VERSION_PATCH is only used for LTS releases
 VERSION_PATCH			:= 0
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
@@ -24,6 +24,8 @@
 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
 
 ################################################################################
 # Default values for build configurations, and their dependencies
@@ -35,6 +37,17 @@
 # Configure the toolchains used to build TF-A and its tools
 ################################################################################
 
+#
+# The clean and check targets do not behave correctly if the user's environment
+# does not appropriately configure a toolchain. While we try to find a permanent
+# solution to this, do not try to detect any toolchains if we are building
+# exclusively with targets which do not use any toolchain tools.
+#
+
+ifeq ($(filter-out check% %clean doc %tool,$(or $(MAKECMDGOALS),all)),)
+        toolchains :=
+endif
+
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 # Assertions enabled for DEBUG builds by default
@@ -82,23 +95,10 @@
 # Process build options
 ################################################################################
 
-# Verbose flag
-ifeq (${V},0)
-	Q:=@
-	ECHO:=@echo
+ifeq ($(verbose),)
 	CHECKCODE_ARGS	+=	--no-summary --terse
-else
-	Q:=
-	ECHO:=$(ECHO_QUIET)
 endif
 
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
-	Q:=@
-	ECHO:=$(ECHO_QUIET)
-endif
-
-export Q ECHO
-
 ################################################################################
 # Auxiliary tools (fiptool, cert_create, etc)
 ################################################################################
@@ -299,7 +299,7 @@
 				-fsanitize-undefined-trap-on-error
 endif #(${SANITIZE_UB},trap)
 
-GCC_V_OUTPUT		:=	$(shell $($(ARCH)-cc) -v 2>&1)
+GCC_V_OUTPUT		:=	$(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -v 2>&1))
 
 TF_LDFLAGS		+=	-z noexecstack
 
@@ -691,8 +691,6 @@
 	FFH_SUPPORT := 0
 endif
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
-
 ifeq (${ARM_ARCH_MAJOR},7)
 include make_helpers/armv7-a-cpus.mk
 endif
@@ -1228,9 +1226,11 @@
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
 	ENABLE_FEAT_CSV2_3 \
+	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_DIT \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_HCX \
 	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
@@ -1298,6 +1298,7 @@
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
 	ENABLE_BTI \
+	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_MPAM \
 	ENABLE_PAUTH \
 	ENABLE_PIE \
@@ -1331,6 +1332,8 @@
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
 	RESET_TO_BL31 \
+	RME_GPT_BITLOCK_BLOCK \
+	RME_GPT_MAX_BLOCK \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
@@ -1380,6 +1383,7 @@
 	ENABLE_MPMM \
 	ENABLE_MPMM_FCONF \
 	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_SEL2 \
@@ -1464,7 +1468,7 @@
 all: msg_start
 
 msg_start:
-	@echo "Building ${PLAT}"
+	$(s)echo "Building ${PLAT}"
 
 ifeq (${ERROR_DEPRECATED},0)
 # Check if deprecated declarations and cpp warnings should be treated as error or not.
@@ -1475,7 +1479,6 @@
 endif
 endif #(!ERROR_DEPRECATED)
 
-$(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
 
 # Expand build macros for the different images
@@ -1559,12 +1562,12 @@
 
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
-$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
-	@${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
+$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | $$(@D)/
+	$(q)${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
 sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
-	@${ECHO_BLANK_LINE}
-	@echo "Built SP Images successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built SP Images successfully"
+	$(s)echo
 endif #(NEED_SP_PKG)
 
 locate-checkpatch:
@@ -1577,37 +1580,37 @@
 endif #(CHECKPATCH)
 
 clean:
-	@echo "  CLEAN"
+	$(s)echo "  CLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(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
+	$(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
+	$(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:
-	@echo "  REALCLEAN"
+	$(s)echo "  REALCLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
 	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(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
+	$(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
+	$(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
 
 checkcodebase:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -d .git ; then						\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -d .git ; then						\
 		git ls-files | grep -E -v 'libfdt|libc|docs|\.rst' |	\
 		while read GIT_FILE ;					\
 		do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ;	\
@@ -1623,11 +1626,11 @@
 	fi
 
 checkpatch:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -n "${CHECKPATCH_OPTS}"; then				\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -n "${CHECKPATCH_OPTS}"; then				\
 		echo "    with ${CHECKPATCH_OPTS} option(s)";		\
 	fi
-	${Q}COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
+	$(q)COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
 	for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`;	\
 	do								\
 		printf "\n[*] Checking style of '$$commit'\n\n";	\
@@ -1642,44 +1645,44 @@
 certtool: ${CRTTOOL}
 
 ${CRTTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${CRTTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} --no-print-directory -C ${CRTTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 certificates: ${CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "Certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "Certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FIP_CMD})
-	${Q}${FIPTOOL} create ${FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${FWU_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "FWU certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${FWU_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "FWU certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FWU_FIP_CMD})
-	${Q}${FIPTOOL} create ${FWU_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FWU_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fiptool: ${FIPTOOL}
 fip: ${BUILD_PLAT}/${FIP_NAME}
@@ -1687,85 +1690,85 @@
 
 ${FIPTOOL}: FORCE
 ifdef UNIX_MK
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${FIPTOOLPATH} all
+	$(q)${MAKE} 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))
+	$(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
+	$(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
 
 memmap: all
 ifdef UNIX_MK
-	${Q}PYTHONPATH=${CURDIR}/tools/memory \
+	$(q)PYTHONPATH=${CURDIR}/tools/memory \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 else
-	${Q}set PYTHONPATH=${CURDIR}/tools/memory && \
+	$(q)set PYTHONPATH=${CURDIR}/tools/memory && \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 endif
 
 doc:
-	@echo "  BUILD DOCUMENTATION"
-	${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html
+	$(s)echo "  BUILD DOCUMENTATION"
+	$(q)${MAKE} --no-print-directory -C ${DOCS_PATH} html
 
 enctool: ${ENCTOOL}
 
 ${ENCTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${ENCTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} --no-print-directory -C ${ENCTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 cscope:
-	@echo "  CSCOPE"
-	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
-	${Q}cscope -b -q -k
+	$(s)echo "  CSCOPE"
+	$(q)find ${CURDIR} -name "*.[chsS]" > cscope.files
+	$(q)cscope -b -q -k
 
 help:
-	@echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
-	@echo ""
-	@echo "PLAT is used to specify which platform you wish to build."
-	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
-	@echo ""
-	@echo "platform = ${PLATFORM_LIST}"
-	@echo ""
-	@echo "Please refer to the User Guide for a list of all supported options."
-	@echo "Note that the build system doesn't track dependencies for build "
-	@echo "options. Therefore, if any of the build options are changed "
-	@echo "from a previous build, a clean build must be performed."
-	@echo ""
-	@echo "Supported Targets:"
-	@echo "  all            Build all individual bootloader binaries"
-	@echo "  bl1            Build the BL1 binary"
-	@echo "  bl2            Build the BL2 binary"
-	@echo "  bl2u           Build the BL2U binary"
-	@echo "  bl31           Build the BL31 binary"
-	@echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
-	@echo "                 this builds secure payload specified by AARCH32_SP"
-	@echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
-	@echo "  fip            Build the Firmware Image Package (FIP)"
-	@echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
-	@echo "  checkcodebase  Check the coding style of the entire source tree"
-	@echo "  checkpatch     Check the coding style on changes in the current"
-	@echo "                 branch against BASE_COMMIT (default origin/master)"
-	@echo "  clean          Clean the build for the selected platform"
-	@echo "  cscope         Generate cscope index"
-	@echo "  distclean      Remove all build artifacts for all platforms"
-	@echo "  certtool       Build the Certificate generation tool"
-	@echo "  enctool        Build the Firmware encryption tool"
-	@echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
-	@echo "  sp             Build the Secure Partition Packages"
-	@echo "  sptool         Build the Secure Partition Package creation tool"
-	@echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
-	@echo "  memmap         Print the memory map of the built binaries"
-	@echo "  doc            Build html based documentation using Sphinx tool"
-	@echo ""
-	@echo "Note: most build targets require PLAT to be set to a specific platform."
-	@echo ""
-	@echo "example: build all targets for the FVP platform:"
-	@echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
+	$(s)echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
+	$(s)echo ""
+	$(s)echo "PLAT is used to specify which platform you wish to build."
+	$(s)echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
+	$(s)echo ""
+	$(s)echo "platform = ${PLATFORM_LIST}"
+	$(s)echo ""
+	$(s)echo "Please refer to the User Guide for a list of all supported options."
+	$(s)echo "Note that the build system doesn't track dependencies for build "
+	$(s)echo "options. Therefore, if any of the build options are changed "
+	$(s)echo "from a previous build, a clean build must be performed."
+	$(s)echo ""
+	$(s)echo "Supported Targets:"
+	$(s)echo "  all            Build all individual bootloader binaries"
+	$(s)echo "  bl1            Build the BL1 binary"
+	$(s)echo "  bl2            Build the BL2 binary"
+	$(s)echo "  bl2u           Build the BL2U binary"
+	$(s)echo "  bl31           Build the BL31 binary"
+	$(s)echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
+	$(s)echo "                 this builds secure payload specified by AARCH32_SP"
+	$(s)echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
+	$(s)echo "  fip            Build the Firmware Image Package (FIP)"
+	$(s)echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
+	$(s)echo "  checkcodebase  Check the coding style of the entire source tree"
+	$(s)echo "  checkpatch     Check the coding style on changes in the current"
+	$(s)echo "                 branch against BASE_COMMIT (default origin/master)"
+	$(s)echo "  clean          Clean the build for the selected platform"
+	$(s)echo "  cscope         Generate cscope index"
+	$(s)echo "  distclean      Remove all build artifacts for all platforms"
+	$(s)echo "  certtool       Build the Certificate generation tool"
+	$(s)echo "  enctool        Build the Firmware encryption tool"
+	$(s)echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
+	$(s)echo "  sp             Build the Secure Partition Packages"
+	$(s)echo "  sptool         Build the Secure Partition Package creation tool"
+	$(s)echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
+	$(s)echo "  memmap         Print the memory map of the built binaries"
+	$(s)echo "  doc            Build html based documentation using Sphinx tool"
+	$(s)echo ""
+	$(s)echo "Note: most build targets require PLAT to be set to a specific platform."
+	$(s)echo ""
+	$(s)echo "example: build all targets for the FVP platform:"
+	$(s)echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
 
 .PHONY: FORCE
 FORCE:;
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 40add91..7e9fde3 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -105,6 +105,10 @@
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
 
+ifneq (${ENABLE_FEAT_FGT2},0)
+BL31_SOURCES		+=	lib/extensions/fgt/fgt2.c
+endif
+
 ifeq (${ENABLE_MPMM},1)
 BL31_SOURCES		+=	${MPMM_SOURCES}
 endif
@@ -120,6 +124,10 @@
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
 endif
 
+ifneq (${ENABLE_FEAT_DEBUGV8P9},0)
+BL31_SOURCES		+=	lib/extensions/debug/debugv8p9.c
+endif
+
 ifneq (${ENABLE_TRBE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/trbe/trbe.c
 endif
diff --git a/changelog.yaml b/changelog.yaml
index ad9c9b5..2b760c7 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -104,9 +104,15 @@
       - title: Extended Translation Control Register (FEAT_TCR2).
         scope: tcr2
 
+      - title: Fine-grained Traps 2 (FEAT_FGT2).
+        scope: fgt2
+
       - title: CPU feature / ID register handling in general
         scope: cpufeat
 
+      - title: Debug Extension (FEAT_Debugv8p9)
+        scope: debugv8p9
+
       - title: Guarded Control Stack (FEAT_GCS)
         scope: gcs
 
@@ -152,11 +158,15 @@
       - title: Self-hosted Trace Extensions (FEAT_TRF)
         scope: trf
 
+      - title: DynamIQ Shared Unit (DSU)
+        scope: dsu
+
   - title: Platforms
     scope: platforms
 
     deprecated:
       - plat/common
+      - plat
 
     subsections:
       - title: Allwinner
@@ -222,6 +232,9 @@
               - title: SGI-575
                 scope: sgi575
 
+              - title: RD-E1-Edge
+                scope: rde1edge
+
               - title: RD-N1-Edge
                 scope: rdn1edge
 
@@ -234,9 +247,15 @@
               - title: RD-N2
                 scope: rdn2
 
+              - title: RD-V3
+                scope: rdv3
+
                 deprecated:
                   - board/rdn2
 
+            deprecated:
+              - neoverse
+
           - title: TC
             scope: tc
 
@@ -651,12 +670,11 @@
               - plat/xilinx/versal
               - plat/versal
 
-            subsections:
-             - title: Versal NET
-               scope: versal-net
+          - title: Versal NET
+            scope: versal-net
 
-               deprecated:
-                 - versal_net
+            deprecated:
+              - versal_net
 
           - title: ZynqMP
             scope: zynqmp
@@ -665,6 +683,13 @@
               - plat/zynqmp
               - plat/xilinx/zynqmp
 
+      - title: AMD
+        scope: amd
+
+        subsections:
+          - title: Versal Gen 2
+            scope: versal2
+
       - title: Nuvoton
         scope: nuvoton
 
@@ -752,6 +777,9 @@
         deprecated:
           - errata_abi
 
+      - title: ChromeOS
+        scope: cros
+
   - title: Libraries
     scope: lib
 
@@ -834,6 +862,9 @@
       - title: Firmware Handoff
         scope: handoff
 
+      - title: Exception Handling Framework (EHF)
+        scope: ehf
+
   - title: Drivers
 
     subsections:
@@ -1121,6 +1152,9 @@
           - title: TRDC
             scope: imx-trdc
 
+          - title: Clock
+            scope: nxp-clk
+
       - title: Renesas
         scope: renesas-drivers
 
@@ -1388,6 +1422,9 @@
       - title: Certificate Creation Tool
         scope: cert-create
 
+      - title: Firmware Encryption Tool
+        scope: encrypt-fw
+
       - title: Memory Mapping Tool
         scope: memmap
 
@@ -1397,6 +1434,19 @@
       - title: Marvell Tools
         scope: marvell-tools
 
+      - title: Renesas Tools
+        scope: renesas-tools
+
+        subsections:
+          - title: R-Car Layout Tool
+            scope: rcar-layout
+
+          - title: R/ZG Layout Tool
+            scope: rzg-layout
+
+      - title: Transfer List Compiler
+        scope: tlc
+
   - title: Dependencies
     scope: deps
 
diff --git a/common/bl_common.c b/common/bl_common.c
index fe4de0a..2a9f32f 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -211,18 +211,18 @@
 {
 	int err;
 
-/*
- * All firmware banks should be part of the same non-volatile storage as per
- * PSA FWU specification, hence don't check for any alternate boot source
- * when PSA FWU is enabled.
- */
-#if PSA_FWU_SUPPORT
-	err = load_auth_image_internal(image_id, image_data);
-#else
-	do {
+	if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) {
 		err = load_auth_image_internal(image_id, image_data);
-	} while ((err != 0) && (plat_try_next_boot_source() != 0));
-#endif /* PSA_FWU_SUPPORT */
+	} else {
+		do {
+			err = load_auth_image_internal(image_id, image_data);
+			if (err != 0) {
+				if (plat_try_img_ops->next_instance(image_id) != 0) {
+					return err;
+				}
+			}
+		} while (err != 0);
+	}
 
 	if (err == 0) {
 		/*
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 09088c9..9b9f7b4 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -94,6 +94,12 @@
 			     ID_AA64PFR0_CSV2_MASK);
 }
 
+static unsigned int read_feat_debugv8p9_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_DEBUGVER_SHIFT,
+			     ID_AA64DFR0_DEBUGVER_MASK);
+}
+
 static unsigned int read_feat_pmuv3_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT,
@@ -289,7 +295,7 @@
 	 * revisions so that we catch them as they come along
 	 */
 	check_feature(FEAT_STATE_ALWAYS, read_feat_pmuv3_id_field(),
-		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P7);
+		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P8);
 
 	/* v8.1 features */
 	check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
@@ -328,7 +334,8 @@
 	/* v8.6 features */
 	check_feature(ENABLE_FEAT_AMUv1p1, read_feat_amu_id_field(),
 		      "AMUv1p1", 2, 2);
-	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 1);
+	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 2);
+	check_feature(ENABLE_FEAT_FGT2, read_feat_fgt_id_field(), "FGT2", 2, 2);
 	check_feature(ENABLE_FEAT_ECV, read_feat_ecv_id_field(), "ECV", 1, 2);
 	check_feature(ENABLE_FEAT_TWED, read_feat_twed_id_field(),
 		      "TWED", 1, 1);
@@ -356,6 +363,8 @@
 		      "S1POE", 1, 1);
 	check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
 		      "CSV2_3", 3, 3);
+	check_feature(ENABLE_FEAT_DEBUGV8P9, read_feat_debugv8p9_id_field(),
+			"DEBUGV8P9", 11, 11);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/Makefile b/docs/Makefile
index 5bc24db..9fd7d76 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,11 +1,13 @@
 #
-# Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 # Minimal makefile for Sphinx documentation
 #
 
+include ../make_helpers/common.mk
+
 # You can set these variables from the command line.
 SPHINXOPTS    = -W
 SPHINXBUILD   = sphinx-build
@@ -13,20 +15,13 @@
 SOURCEDIR     = .
 BUILDDIR      = build
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
-endif
-
 # Put it first so that "make" without argument is like "make help".
 help:
-	${Q}$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+	$(q)$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 .PHONY: help Makefile
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	${Q}$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+.DEFAULT: Makefile
+	$(q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 1f68927..cbed72f 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -63,8 +63,8 @@
 :|G|: `bipinravi-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
 :|G|: `joannafarley-arm`_
-:|M|: Okash Khawaja <okash@google.com>
-:|G|: `bytefire`_
+:|M|: Jidong Sun <jidong@google.com>
+:|G|: `jidongsun`_
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
 :|G|: `vwadekar`_
 :|M|: Yann Gautier <yann.gautier@st.com>
@@ -114,6 +114,8 @@
 :|M|: Marc Bonnici <marc.bonnici@arm.com>
 :|G|: `marcbonnici`_
 :|F|: services/std_svc/spm/el3_spmc/\*
+:|F|: include/services/el3_spmc\_\*
+:|F|: include/services/spmc_svc.h
 
 Secure Partition Manager Dispatcher (SPMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +123,13 @@
 :|G|: `odeprez`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
 :|F|: services/std_svc/spmd/\*
+:|F|: plat/common/plat_spmd_manifest.c
+:|F|: include/services/ffa_svc.h
+:|F|: include/services/el3_spmd_logical_sp.h
+:|F|: include/services/spmd_svc.h
 
 Exception Handling Framework (EHF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,6 +139,16 @@
 :|G|: `manish-pandey-arm`_
 :|F|: bl31/ehf.c
 
+Runtime Exceptions and Interrupt Management
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl31/aarch64/
+:|F|: bl31/interrupt_mgmt.c
+:|F|: include/bl31/interrupt_mgmt.h
+
 Realm Management Monitor Dispatcher (RMMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
@@ -216,12 +234,14 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/psci/
+:|F|: include/lib/psci/
 
 DebugFS
 ^^^^^^^
 :|M|: Olivier Deprez <olivier.deprez@arm.com>
 :|G|: `odeprez`_
 :|F|: lib/debugfs/
+:|F|: include/lib/debugfs.h
 
 Firmware Configuration Framework (FCONF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,6 +252,10 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/fconf/
+:|F|: plat/arm/common/fconf/
+:|F|: include/lib/fconf/
+:|F|: include/plat/arm/common/arm_fconf\_\*
+:|F|: include/plat/arm/common/fconf\_\*
 
 Performance Measurement Framework (PMF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -253,6 +277,7 @@
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/cpus/
+:|F|: include/lib/cpus/
 
 Reliability Availability Serviceabilty (RAS) framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -380,6 +405,8 @@
 :|M|: Manish Pandey <manish.pandey2@arm.com>
 :|G|: `manish-pandey-arm`_
 :|F|: services/std_svc/drtm
+:|F|: include/plat/common/plat_drtm.h
+:|F|: include/services/drtm_svc.h
 
 PSA Firmware Update
 ^^^^^^^^^^^^^^^^^^^
@@ -433,6 +460,32 @@
 :|F|: lib/transfer_list
 :|F|: include/lib/transfer_list.h
 
+Context Management
+^^^^^^^^^^^^^^^^^^
+:|M|: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
+:|G|: `jayanthchidanand-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl1/aarch32/bl1_context_mgmt.c
+:|F|: bl1/aarch64/bl1_context_mgmt.c
+:|F|: bl31/bl31_context_mgmt.c
+:|F|: lib/el3_runtime/
+:|F|: include/lib/el3_runtime/
+
+Runtime Services
+^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: services/std_svc/std_svc_setup.c
+:|F|: common/runtime_svc.c
+:|F|: include/common/runtime_svc.h
+:|F|: include/services/arm_arch_svc.h
+:|F|: include/services/std_svc.h
+
 Platform Ports
 ~~~~~~~~~~~~~~
 
@@ -604,7 +657,6 @@
 :|M|: Avi Fishman <avi.fishman@nuvoton.com>
 :|G|: `avifishman`_
 :|F|: docs/plat/npcm845x.rst
-:|F|: drivers/nuvoton/
 :|F|: include/drivers/nuvoton/
 :|F|: include/plat/nuvoton/
 :|F|: plat/nuvoton/
@@ -715,6 +767,7 @@
 :|M|: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
 :|G|: `gprocopciucnxp`_
 :|F|: docs/plat/s32g274a.rst
+:|F|: drivers/nxp/clk/s32cc
 :|F|: drivers/nxp/console/linflex_console.S
 :|F|: include/drivers/nxp/console/linflex.h
 :|F|: plat/nxp/s32
@@ -983,7 +1036,7 @@
 .. _bijucdas: https://github.com/bijucdas
 .. _bipinravi-arm: https://github.com/bipinravi-arm
 .. _bryanodonoghue: https://github.com/bryanodonoghue
-.. _bytefire: https://github.com/bytefire
+.. _jidongsun: https://github.com/jidongsun
 .. _carlocaione: https://github.com/carlocaione
 .. _chandnich: https://github.com/chandnich
 .. _ChiaweiW: https://github.com/chiaweiw
@@ -1061,3 +1114,7 @@
 .. _vwadekar: https://github.com/vwadekar
 .. _xueliang-zhong-arm: https://github.com/xueliang-zhong-arm
 .. _Yann-lms: https://github.com/Yann-lms
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index a5fd1d6..7fafe03 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -83,7 +83,7 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| STM32MP15_OPTEE_RSV_SHM        |     2.10    |   3.0   | OP-TEE manages its own memory on STM32MP15              |
+|                                |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 Removal of Deprecated Drivers
diff --git a/docs/change-log.md b/docs/change-log.md
index cfc8c56..1e6647f 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,924 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [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
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - Any platform or downstream code trying to use
+      SCR_EL3.ATA bit(26) will see failures as this is now moved to be
+      used only with FEAT_MTE2 with
+      commit@ef0d0e5478a3f19cbe70a378b9b184036db38fe2
+
+      **See:** remove mte, mte_perm ([c282384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c282384dbb45b6185b4aba14efebbad110d18e49))
+
+- **Services**
+
+  - **SPM**
+
+    - **SPMD**
+
+      - Given the optimizations made in TF-A SPMD to simplify NS EL1 context
+        management, platform integrators must use SPMC binaries built by
+        picking commits after 2fc6dcfa97e05159f95859fcf68db3031586f8c7 from
+        hafnium repository.
+
+        **See:** skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Drivers**
+
+  - **Arm**
+
+    - **RSE**
+
+      - remove PLAT_RSS_NOT_SUPPORTED build option
+
+        **See:** remove PLAT_RSS_NOT_SUPPORTED build option ([878354a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/878354a845cbc51c198b879d3d92ed472e21889c))
+
+  - **FWU**
+
+    - add a config flag for including image info in the FWU metadata ([11d05a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d05a77295885f27530cf07029ebc2b36f49918))
+    - add a function to obtain an alternate FWU bank to boot ([26aab79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26aab79560a2281c4207b01102495459c2bddefc))
+    - add some sanity checks for the FWU metadata ([d2566cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2566cfb896672ea07c31c37e7acd9ef77abc4fb))
+    - document the config flag for including image info in the FWU metadata ([7ae1619](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ae16196cc73a580f298734bb98f2ccb210e3ba9))
+    - migrate FWU metadata structure to version 2 ([a89d58b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a89d58bb204c00db260225859bce0b55aa5e2385))
+
+### New Features
+
+- **Architecture**
+
+  - **CPU feature / ID register handling in general**
+
+    - add cortex-a35 l2 extended control register ([a727d59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a727d59d9c1ef5ecf2f221ce289506da2011dda1))
+    - add feature detection for FEAT_CSV2_3 ([30019d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30019d8698b219d4a642dc59e7178006f59654ff))
+    - added few helper functions ([30f05b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30f05b4f5db605ddc1a3ca0ae0cbd13ed0e728b6))
+
+  - **DynamIQ Shared Unit (DSU)**
+
+    - save/restore DSU PMU register ([f99a69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f99a69c386ce5448edfc47eaf146d1a20ac8216e))
+
+  - **Memory Tagging Extension2**
+
+    - add mte2 feat ([8e39788](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e3978899a481484d8c60bf276be503aebd43afb))
+
+- **Platforms**
+
+  - update SZ_* macros ([6d511a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d511a8c31f0d792695566ae75c8f7b08b3b7236))
+
+  - **Arm**
+
+    - add COT_DESC_IN_DTB option for CCA CoT ([b76a43c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b76a43c9382e85969cac896cd4d5d6774d0d1553))
+    - add trusty_sp_fw_config build option ([0686a01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0686a01b0cacb9aab840a5c334409b5739a95a97))
+    - move GPT setup to common BL source ([341df6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/341df6af6eb911ffd175e129f61fc59efcf9fcea))
+    - retrieve GPT related data from platform ([86e4859](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86e4859a05614b40ff3cf38f8bd4efc856c546fe))
+    - support FW handoff b/w BL1 & BL2 ([9c11ed7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c11ed7e3e5536ad1fcb9190560e0368da9c5ab5))
+    - support FW handoff b/w BL2 & BL31 ([a5566f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5566f65fd1be689ca5c63baa1f5b61b40960c8d))
+    - add platform API that gets cluster ID ([e6ae019](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6ae019a84c4d2ad2d2825b32fbcbe304752e3ae))
+
+    - **CSS**
+
+      - initialise generic timer early in the boot ([3447ba1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3447ba1f0405a8590ec31e4b79737efe151c3d5b))
+
+    - **FVP**
+
+      - add CCA CoT in DTB support ([4c79b86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c79b86ed6a36b572cf9e96f0269eb5dd0b46d5f))
+      - add stdout-path ([8c30a0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c30a0c7fe0162de0618b26fb34cc91ea582e5f7))
+      - add support for virto-net, virtio-9p and virtio-rng ([51b8b9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51b8b9c3c46cec87ebb7b484727c80ff29d73057))
+      - added calls to unprotect/protect memory ([6873088](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6873088c2cd6983025b6777d4c3bde912eade571))
+      - delegate FFH RAS handling to SP ([d07d4d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07d4d63374b0d155b9281f9fcaf6b44f18117c8))
+      - remove left-over RSS usage ([a1726fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1726fa7ffecdcc8f8f4d09bd0bdc97ef3b72f11))
+
+    - **Neoverse-RD**
+
+      - add scope for RD-V1 ([86a4949](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86a4949fd012a9912c8bf909d14e20657bba2240))
+      - add scope for RD-V1-MC ([6fb16da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fb16dac6e6672040ec80f85f2f337f52cf3f3d3))
+      - add scope for SGI-575 ([18b5070](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18b50707f7732a8b3deb46d8d011566199711c0b))
+      - disable SPMD_SPM_AT_SEL2 for A75/V1/N1 platforms ([b9c3273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9c32730e5b7efe5170ed3c0dda7ab9db397c478))
+      - disable SPMD_SPM_AT_SEL2 for N2/V2 platforms ([301c017](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/301c01748ea717d0f2cf3ba1f0a2fe389b6fb155))
+      - enable AMU if supported by the platform ([fed9368](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fed9368529e5bc2c9111ac5a743688166661fd8f))
+      - remove unused SGI_PLAT build-option ([2d32517](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d32517ce64886f154c6d509f80d0fcde05dc498))
+
+      - **SGI-575**
+
+        - remove SGI-575 from deprecated list ([f104eec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f104eecdea209af87de43c62811a0a9456f2838c))
+
+      - **RD-E1-Edge**
+
+        - remove support for RD-E1-Edge ([c69253c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69253cc3ad3063380c8f905125fe85f6d942d09))
+
+      - **RD-N1-Edge**
+
+        - remove RD-N1-Edge from deprecated list ([78b7939](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78b793956f3a86a3dd62394c858ae9ee41379b8b))
+
+      - **RD-N2**
+
+        - enable NEOVERSE_Nx_EXTERNAL_LLC flag ([ab2b363](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab2b3632171dd5488952ba3f68693e490857e9dc))
+        - add dts for secure partition ([49df726](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49df7261be44d5199a930c95667edb6b878355d1))
+        - enable AMU if present on the platform ([2cfedfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2cfedfad9c2c59316adf17d4f0ee561b50a041b6))
+        - enable MTE2 if present on the platform ([3a5b375](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a5b3753033561cb5d7cd7aace634cc66eab0fa7))
+        - update power message value to 0 ([08f6398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/08f6398b2b9566812cd110498e3135dfc2e3e494))
+
+    - **TC**
+
+      - add arm_ffa node in dts ([4fc4e9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc4e9c969930d83f1144441199301d3b4b34a5a))
+      - add DPE backend to the measured boot framework ([e7f1181](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7f1181f8a7729acb07ebac86944e36932bcd09e))
+      - add DPE context handle node to device tree ([1f47a71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f47a7133f7fe7fb038aca97fc93533964b2b429))
+      - add dummy TRNG support to be able to boot pVMs ([7be391d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7be391d1ce5683c717fcf2be584f3d294ebc2bf3))
+      - add firmware update secure partition ([d062872](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0628728a627ee11c97839640d404221a74c3a65))
+      - add memory node in the device tree ([5ee4deb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ee4deb8e69175f57fa51519ef37e3674aa6b9a0))
+      - add PMU entry ([553b06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/553b06b5d4f7ec8e49796e0ffdf081bf5cf30d53))
+      - add RSS SDS region right after SCMI payload ([6f503e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6f503e0eea23a2663ed5cbfe9b925e1e0d65c236))
+      - add save/restore DSU PMU register support ([b87d7ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b87d7ab13f4b03f872c3c4a3dd7c755baf3a38d3))
+      - add SCMI power domain and IOMMU toggles ([a658b46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a658b46dc74ceaa51d119bd7bd9eccdefb0cc455))
+      - add spmc manifest with trusty sp ([ba197f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba197f5f708fe8e033971c6f4d5b25f6783aaa45))
+      - add TC3 platform definitions ([62320dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62320dc4fd2c13d9f4b227fe73cad2a79bdba42c))
+      - allow booting from DRAM ([18f754a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18f754a275083ea66823b1c9f39e234cf430140e))
+      - choose the DPU address and irq based on the target ([8e94163](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e94163ec041f2d7df41c2dfd8625c06655ba08e))
+      - enable gpu/dpu scmi power domain and also gpu perf domain ([127eabe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/127eabeddfc4fb596a1b499fe68ee6f7e5b5b6d5))
+      - factor in FVP/FPGA differences ([1b8ed09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b8ed0993fc5c04f76d949df7e2851e67040bbf9))
+      - get the parent component provided DPE context_handle ([467bdf2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/467bdf26b64a38cfbfb3bf8ab915eb97eb6b3037))
+      - group components into certificates ([6df8d76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6df8d7647dad5c347d363554d25e590d24eb05e5))
+      - interrupt numbers for `smmu_700` ([2c406dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c406ddaf700e0f1c80535e309a2245b9e0bee92))
+      - introduce an FPGA subvariant and TC3 CPUs ([a02bb36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a02bb36caa521259ae57a904dedb7fd4e6a51340))
+      - pass the DTB address to BL33 in R0 ([638e4a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638e4a92d80346b4d46ef2cc5fbb7941d1b7fd31))
+      - provide a mock mbedtls-random generation function ([a877818](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8778185d2fd2b80cee8af7879ecb92be1aa3898))
+      - share DPE context handle with child component ([03d388d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03d388d8e3eb5c6cce65afba060a16fae83d4d12))
+
+  - **Intel**
+
+    - add in QSPI ECC for Linux ([4d122e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d122e5f199ad1531650ae11de5121057cfc0855))
+    - enable query of fip offset on RSU ([6cbe2c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cbe2c5d19c4af0ba6bbba049962bf55454da8bb))
+    - enable SDMMC frontdoor load for ATF->Linux ([32a87d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32a87d440087e0a71765a61ec341af7cfcfbda97))
+    - increase bl2 size limit ([2d46b2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d46b2e46189120b6779cd27ec6bd6ec9901f72c))
+    - restructure watchdog ([47ca43b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ca43bcb4565a992bf527f68e1ff60fc036fd12))
+    - support QSPI ECC Linux for Agilex ([d6ae69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6ae69c8c69016d05d64752538aad53f319b88a2))
+    - support QSPI ECC Linux for N5X ([6cf16b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cf16b36821b9f2a60ed9abbaa593ef62b8b9f2b))
+    - support QSPI ECC Linux for Stratix10 ([8be16e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8be16e44cf0143e8651090d80bd14194aa78b1f2))
+    - support query of fip offset using RSU ([62be2a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62be2a1ae3efcba0bb8b7ec8ef73b2a0f5a437e3))
+    - support SDM mailbox safe inject seu error for Linux ([fffcb25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fffcb25c3c2171624c582d92173154f570708a9a))
+    - support wipe DDR after calibration ([68bb3e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68bb3e836e93b271f9f1c05787025dd3f04dd788))
+
+  - **MediaTek**
+
+    - remove bl32 flag for mtk_bl ([9c41cc1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c41cc182dd7acf541565ab3df7a4261fb7eaf1b))
+
+    - **MT8188**
+
+      - add secure iommu support ([5fb5ff5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fb5ff5694c1bcf0ddfc972600b69d7494ca6645))
+      - remove apusys kernel handler usage constraints ([0c77651](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c77651fb47c7ffd4b1b37a74aea77373179ab5d))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add 3600 MTps DDR PLL rate ([f1bb459](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1bb459c3192eb6b3fc6b9b77658d82227eae2d5))
+        - add defines for csu_sa access security ([81de503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81de50372c9192098118fc8bddaf086a620add87))
+        - add imx csu_sa enum type defines for imx8m ([2ac4909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2ac4909a5ec0a50a75cab9bb587fb1b8e592794d))
+        - make bl33 start configurable via PRELOADED_BL33_BASE ([9260a8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9260a8c818aadbf513b2744cad978c18d0f65a8e))
+        - obtain boot image set for imx8mn/mp ([6d2c502](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d2c502afb845e7af94c610ab5a375b868c885ba))
+
+        - **i.MX 8M Mini**
+
+          - restrict peripheral access to secure world ([1156c76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1156c76361c170c83c6b9a9dd7c22aa401a4ce2e))
+          - set and lock almost all peripherals as non-secure ([f4b11e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4b11e59b81af3e485e6992b10b50b362902eee1))
+
+        - **i.MX 8M Plus**
+
+          - restrict peripheral access to secure world ([0324081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0324081af0105af536992c8ced2caa5a1928010f))
+          - set and lock almost all peripherals as non-secure ([cba7daa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cba7daa10576684670e06d05ff02888a5b4f16bf))
+
+        - **i.MX 8Q**
+
+          - detect console base address during runtime ([52ee817](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52ee8173041c46aafcfa43f004029dddbfa9f9b5))
+
+      - **i.MX 8ULP**
+
+        - add a flag check for the ddr status ([4fafccb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fafccb9a8f7b35406b08743f6d9c9b519b01c61))
+        - add APD power down mode(PD) support in system suspend ([478af8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/478af8d3c34576793a820733ddba6449c2cf2fac))
+        - add i.MX8ULP basic support ([fcd41e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fcd41e8692ce8e8fc98d069bc131820cbf83c55c))
+        - add memory region policy ([5fd0642](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fd06421f8bf9f5b67e73828281534f14f302630))
+        - add OPTEE support ([e7b82a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7b82a7d2fa1fc3f32724e6836b8f6078d20c103))
+        - add some delay before cmc1 access ([c514d3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c514d3cfa7640313c4d78674df9d7cbe9227420b))
+        - add system power off support ([891c547](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/891c547e9658c1827559d8da5e3b87de5a2e9f6a))
+        - add the basic support for idle & system suspned ([daa4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/daa4478a3cb2f86501c37e5a301cd4d6a6e60ee6))
+        - add the initial XRDC support ([ac5d69b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac5d69b628736f66f72e99532656105fdc07a3fe))
+        - add trusty support ([e853041](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e853041920b15b77839027ab802d0cd9a08c7c35))
+        - adjust the dram mapped region ([8d50c91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d50c91b476474cc403c30eb6de6af28cb246e5a))
+        - adjust the voltage when sys dvfs enabled ([416c443](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/416c4433f0047a86165e450e60f93020c561151b))
+        - allocated caam did for the non secure world ([7c5eedc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c5eedca4c7f176448e6b92eb5c22ee2ea45e70a))
+        - allow RTD to reset APD through MU ([ea1f7a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea1f7a2e109181f19f5bdeb71533e7dfda753df7))
+        - ddrc switch auto low power and software interface ([ee25e6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee25e6a51bf20c92471e737ccba98af4a74d1383))
+        - enable 512KB cache after resume on imx8ulp ([bcca70b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcca70b9688c5effa0731f39e2b209071f54be2c))
+        - enable the DDR frequency scaling support ([caee273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/caee2733ba4e7a09ea656b0be85f150a275cc57c))
+        - give HIFI4 DSP access to more resources ([351976b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/351976bb063cca7866e214a6bda9302f9ab018b3))
+        - not power off LPAV PD when LPAV owner is RTD ([ab787db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab787dba7726bdf58c15626e5cc9a3525aade8a3))
+        - protect TEE region for secure access only ([ff5e179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff5e1793b95ed4297deae72cdb665178e6e72e44))
+        - update the upower config for power optimization ([36af80c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36af80c2b420cb32ff57273eda0d7d0e93b49153))
+        - update XRDC for ELE to access DDR with CA35 DID ([d159c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d159c00532afe50686dd92215de9b420d60502f6))
+
+    - **S32G274A**
+
+      - add S32G274ARDB2 board support ([8b81a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b81a39e28a087e1123271a42c04a7ce3b496a58))
+      - enable BL31 stage ([e73c3c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e73c3c3a6cbc1e81de4c9d73a5d713e6b37ae3b2))
+
+  - **QEMU**
+
+    - allow ARM_ARCH_MAJOR/MINOR override ([e769f83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e769f830d3116f49ed82769d9d731c4dca8f6188))
+    - enable FEAT_ECV when present ([1b694c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b694c77c497cb8272c97417ef1fa4f5f9c869c1))
+    - enable transfer list to BL31/32 ([305825b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/305825b490a77e5b0ee816ea29c53bc6444a1d63))
+    - load and run RMM image ([8ffe0b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ffe0b2edea6b00c9fe7d9ecaeca43c734d3764d))
+    - setup Granule Protection Table ([6cd113f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cd113fe06fdaa67a8457391eb6bcffd295f87fd))
+    - setup memory map for RME ([cd75693](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd75693f5ed303c1366fdff9b392d766848b6b67))
+    - support TRP for RME ([ebe82a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebe82a392f06aa0adddf9cc5caa7af8f561b2fb4))
+    - update mapping types for RME ([a5ab1ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5ab1ef7febb2dc931cd8f7fcd76caac04d628cd))
+    - update to manifest v0.3 ([762a1c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/762a1c44b985b71495a90bc3484b576d28c8511a))
+    - use mock attestation functions for RME ([c69e95e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69e95eed0491b481971b48f5df855402ed5392a))
+
+    - **SBSA**
+
+      - handle CPU information ([42925c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42925c15bee09162c6dfc8c2204843ffac6201c1))
+      - handle memory information ([8b7dd83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b7dd8397dd017b61ecda8447e8956a1d9d6d5d3))
+      - mpidr needs to be present ([4fc54c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc54c99d08926c2d42173902c8aaf3862722c84))
+
+  - **Raspberry Pi**
+
+    - add Raspberry Pi 5 support ([f834b64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f834b64f889c1c4e03e590d44a6a52e3ac79cf42))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - add cache operations to boot process ([7e06b06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e06b06753b12d567b6f48b6e60d6d0a56cf72e5))
+        - change CAM setting to improve bus latency of R-Car Gen3 ([e366f8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e366f8cf3349189daafb7ac2ab74d98931757a60))
+        - change MMU configurations ([5e8c2d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e8c2d8e23ca0760bca7e5b692ee95dd2871ec89))
+        - enable the stack protection ([cfa466a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfa466ab733ff021771b94b4a98d22bfdd246139))
+        - update IPL and Secure Monitor Rev.4.0.0 ([516a98e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/516a98ef277626aa1858d9a4018d13ab2aeb39e7))
+
+  - **ST**
+
+    - add a function to clear the FWU trial state counter ([6e99fee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e99fee43efa256bdac3b38864206c94bd9ae3c8))
+    - add logic to boot the platform from an alternate bank ([6166051](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6166051426638087b5433eff1739d26478313dff))
+    - do not directly call BSEC functions in common code ([3007c72](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3007c72844c72e0911721e499dbab37b3eca1cdc))
+    - get the state of the active bank directly ([588b01b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/588b01b5e4726cd4a6d235e9f566a546ef17f631))
+    - use stm32_get_otp_value_from_idx() in BL31 ([189db94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/189db9486ddd949f279faa970bfc1dd9cc0e3623))
+
+    - **STM32MP1**
+
+      - only fuse monotonic counter on closed devices ([d6bb94f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6bb94f3a14ddbcf44c667134ed302eff054954c))
+
+    - **STM32MP2**
+
+      - add BSEC and OTP support ([197ac78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/197ac780d73c3421c4643e0bc02d112ceffd248f))
+      - add ddr-fw parameter for fiptool ([e494afc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e494afc05f8562455e09b4f131f2699990a744f8))
+      - add plat_my_core_pos ([d1c85da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1c85da8ef23a99387823272b03399a07e3a00da))
+      - add STM32MP_USB_PROGRAMMER compilation ([2e905c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e905c0682b4e6d2cfdbd42e41f6097b16967ff5))
+      - put back core 1 in wfi after debugger's halt ([2331a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2331a34f783b29a9a1fe86f5142d0a359cacb259))
+      - use early traces ([47ea303](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ea303389f6d0ac81617366973ece9d93dc49c9))
+
+  - **Xilinx**
+
+    - add handler for power down req sgi irq ([ade92a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ade92a64e4d2fbb5f246e6ad891465d10e0d9b26))
+    - add new state to identify cpu power down ([5949701](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5949701600c7f3c3a6589d0efd743615156c34b6))
+    - add wrapper to handle cpu power down req ([3dd118c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3dd118cf9d60e1eab97af505eb63a2cdc044d747))
+    - power down all cores on receiving cpu pwrdwn req ([c3280df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3280df1bb95ed09b5d5f91f8977bbe99c6a923b))
+    - request cpu power down from reset ([88ee081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88ee0816a7429689890659f69b895ac84e48f141))
+    - send SGI to mailbox driver ([9a7f892](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a7f892e29ea81c67f6f6b1342a367234e125b63))
+
+    - **Versal**
+
+      - enable errata management feature ([d766f99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d766f994d2bd00c538f66e95686fc47b45ccbdb9))
+      - extend platform address space sizes ([663f024](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/663f024f207bddb7b80167e661c094d77955e292))
+
+      - **Versal NET**
+
+        - add bufferless IPI Support ([511e4a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/511e4a48ccd5e74af338041be238f5df12fffe3e))
+
+    - **ZynqMP**
+
+      - remove unused pm_get_proc_by_node() ([b03ba48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03ba4801d39da1d5acc7a58d9c7736e57efc099))
+
+- **Bootloader Images**
+
+  - **BL32**
+
+    - create an sp_min_setup function ([a1255c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1255c758593f9f6fb85b70165fad21de7491e1e))
+
+- **Services**
+
+  - **FF-A**
+
+    - update FF-A version to v1.2 ([e830e4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e830e4cdee3d2238314326ef8c259b35d1c4f167))
+
+  - **RME**
+
+    - build TF-A with ENABLE_RME for Armv9.2 ([7d5fc98](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d5fc98f5483efb942f7cbe4c04bf546a9a8598c))
+    - pass console info via RMM-EL3 ifc ([3290447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32904472cc55a4bc9d8181a389ce3419033e0101))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - add support for FFA_CONSOLE_LOG ([638a6f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638a6f8e04c543649369374492524f2952f8d6b6))
+      - add support for FFA_MEM_PERM_GET and SET ABIs ([1f6b2b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f6b2b26535d5254d998239f232d997972d0475b))
+      - add support to handle power mgmt calls for s-el0 sp ([5917379](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59173793f47e27a66c871a0e8237e0f0d462080d))
+      - add support to map S-EL0 SP device regions ([727ab1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/727ab1c4ab1e5ce1559fa6efec510114ce51fdf8))
+      - add support to map S-EL0 SP memory regions ([83c3da7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c3da7711a246e04f4d0a64593fc0ab46f08bad))
+      - add support to setup S-EL0 context ([48db2b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48db2b0120d1726208ff38a0edf6962f55a988bf))
+      - synchronize access to the s-el0 sp context ([5ed8e25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ed8e255096bd34d12bc6621e48cf9139bf414b2))
+
+    - **SPMD**
+
+      - add FFA_MSG_SEND_DIR_REQ2 ([cc6047b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc6047b3de52e412988f321723f67077a409e27d))
+      - add FFA_MSG_SEND_DIR_RESP2 ([0651b7b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0651b7beb7e08a01c6e28be61026b053d53308fa))
+      - initialize SCR_EL3.EEL2 bit at RESET ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+      - pass SMCCCv1.3 SVE hint to lower EL ([c925867](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c925867ec1be039abb72a7d65bff1b6a85b3d67a))
+
+  - **DRTM**
+
+    - add ACPI table region size to the DLME header ([5dde96b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dde96b02490829d023b37931737c2ba2a6ed431))
+    - add additional return codes ([89f5c75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89f5c753af8e5b8091543e8b1cae4d37e345ed7f))
+    - for TPM features fw hash algorithm should be 16-bits ([c86cfa3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c86cfa35975542d25d2192b81908074195aafe96))
+    - update DRTM version to 1.0 ([9c36b90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c36b900f904642f41e201024df584c0eaef9fc5))
+    - update references to DRTM beta0 ([b94d590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b94d59099f0addb32389952dc6ecf35136a23859))
+    - update return code if secondary PE is not off ([bc9064a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc9064ae5c983aaca56102c2c0d3513ed022fd46))
+
+  - **ChromeOS**
+
+    - add ChromeOS widevine SMC handler ([b22e689](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b22e6898e1493eb00d0f0de6d48655d744264cb6))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for Poseidon V CPU ([b77f55d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b77f55d6c7e51025d6c7ada1b4aa9506a046cf0f))
+    - support to update External LLC presence in Neoverse N3 ([6fbc98b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fbc98b15d92d881c4fbb74fd1344f0ef3f128ad))
+    - support to update External LLC presence in Neoverse V2 ([6aa5d1b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aa5d1b3ab7b29c85ffe05942f2991da869e7fed))
+
+  - **EL3 Runtime**
+
+    - introduce UNDEF injection to lower EL ([3c789bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3c789bfccca548ebcbdafbc7ecb07461d9368bea))
+
+  - **FCONF**
+
+    - support signing-key in root cert node ([04ac0b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04ac0b3c2711a4cb2f35983e91ff0ee842b52bbd))
+
+  - **OP-TEE**
+
+    - enable transfer list in opteed ([0e8def9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e8def996e73673d3e2c3d755a84e2b759ab3052))
+
+  - **PSCI**
+
+    - add psci_do_manage_extensions API ([160e843](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/160e8434baa48cc19d69913b00d2a643c788caec))
+
+  - **GPT**
+
+    - validate CRC of GPT partition entries ([7a9e9f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a9e9f6e96a93617abd33ef48734b65ad792ec13))
+
+  - **SMCCC**
+
+    - add vendor specific el3 id ([be5b1e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be5b1e22346c6d8ce4b0c56604c99f7a9d3676cc))
+    - add vendor-specific el3 service ([de6b79d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de6b79d8b5e15262b328051095e15ad4c67518eb))
+    - add version FID for PMF ([42cbefc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42cbefc72721a9cbf68a70d81cbcb141a2d085f1))
+
+  - **C Standard Library**
+
+    - add printf support for space padding ([0926d2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0926d2df7a5606c2b7c341d51f04a396084c39f2))
+
+  - **Locks**
+
+    - add bitlock ([222f885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/222f885df38c3abd34ee239a721654155609631b))
+
+  - **DICE Protection Environment (Experimental)**
+
+    - add cert_id argument to dpe_derive_context() ([6a415bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a415bd1e71ac944c0ac67507b01f251e63361c3))
+    - add client API for DICE Protection Environment ([b03fe8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03fe8c025f1c8025e70e7289339ecbc6cf83aae))
+    - add DPE driver to measured boot ([0ae9c63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ae9c631eaa32a30df3ff10cb4f0abafccb6c409))
+    - add QCBOR library as a dependency of DPE ([c19977b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c19977be0c3654e12accd51d4aef7059411106a6))
+    - add typedefs from the Open DICE repo ([584052c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/584052c7f80b406666b9597447eeccef4d6deca4))
+
+  - **Context Management**
+
+    - report context memory usage ([bfef8b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfef8b908e3a3cc29656c1d30a6b53490c79539b))
+    - add documentation for context management library ([4efd219](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4efd2193621ab7b933f4edfa28888379f3e03cbd))
+
+  - **Firmware Handoff**
+
+    - add additional TE tags ([a312bfb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a312bfb34487774a0e3244266ee45f63af86e2e8))
+    - add support for RESET_TO_BL2 ([f019c80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f019c8013e9c5efeb85eec7792fe901543a5832c))
+    - add TE's for BL1 handoff interface ([0646c9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0646c9b293a2d8cdfd4626d15395385b5c1c2a6c))
+    - add TL source files to BL1 ([469b1d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/469b1d8412a748819f8c1bf51f695f2cb9f20489))
+    - enhance transfer list library ([40fd755](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40fd755bad9411d1e9e55984107186dde4137635))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - add explicit entries for key OIDs ([2b53106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b53106a0e91e0865bf855935de04b24ef1cfa02))
+
+    - **mbedTLS**
+
+      - update config for 3.6.0 ([55aed7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55aed7d798f3d48d6aa08d58eb46c4cda318bcfb))
+
+  - **Console**
+
+    - introduce EARLY_CONSOLE ([ae770fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae770fedf459d5643125d29f48659e3e936ebd2d))
+
+  - **FWU**
+
+    - modify the check for getting the FWU bank's state ([56724d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56724d09c2c55ee2b8486b7c706f5fb9d980df88))
+    - update the URL links for the FWU specification ([e106a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e106a78ef00df4c70a1594a89520af07b939cd92))
+
+  - **SCMI**
+
+    - add scmi sensor support ([e63819f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e63819f2bc307e7a42d43151242009f91ceeb06b))
+
+  - **Arm**
+
+    - **SMMU**
+
+      - fix to perform INV_ALL before enabling GPC ([70d849c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70d849c14de99e7320cc381b441af8bfe2a38375))
+      - separate out smmuv3_security_init from smmuv3_init ([a23710b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a23710b4b943a15a418a5d41236b2b57bd071de6))
+
+    - **MHU**
+
+      - add MHUv3 doorbell driver ([bc17476](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc174764f0daa82128bf60163653fc20db9a7e87))
+      - add MHUv3 wrapper APIs for RSS comm driver ([4b4f850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b4f8505e7c58ba80a00c47a11f5feaf6d6f44f2))
+      - use compile flag to choose mhu version ([996b3af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/996b3af84cc6aeca90bc0dd3559abffd8bdc0ed7))
+
+    - **RSE**
+
+      - add defines for 'type' range and use them in psa_call() ([002b106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/002b10604ba0b90ac6e85d445ce2184cab52e39b))
+      - adjust parameter packing to match TF-M changes ([5abcc83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5abcc83991770a2fdbcb57dfc01000c6354da915))
+
+  - **NXP**
+
+    - add Linflex driver ([306946b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306946b01490cfe0675300412cf738840bd099ef))
+
+  - **ST**
+
+    - **BSEC**
+
+      - add driver for the new IP version BSEC3 ([ae6542f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6542f6c7ac9224843448424d3a539733bd651b))
+      - use early traces ([cf237f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf237f8d55255da1aad4f8dccb3110bab6060eba))
+
+    - **Clock**
+
+      - add function to control MCU subsystem ([77b4ca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77b4ca0b2fd2c35e3bcb516078e1d9e3573172b3))
+
+    - **SDMMC2**
+
+      - set FIFO size to 1024 on STM32MP25 ([d5b4d5d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5b4d5d2e62e57acdcb2dbbcd4fe208bde92dc4c))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - add functions for TLBI RPALOS ([8754cc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8754cc5d1c1b33d645b321f465bcfe61bc3915d6))
+
+  - **DT Bindings**
+
+    - introduce CCA CoT, rename TBBR ([c4b35ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4b35cebffb0d034aa7bdba7cfdb65ba93939e35))
+
+  - **FDTs**
+
+    - **STM32MP2**
+
+      - add board ID OTP in STM32MP257F-EV1 ([88528f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88528f55771fdc0a94b2ddd7f49f495a83044a24))
+      - add OTP nodes in STM32MP251 SoC DT file ([c238a46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c238a46a76660cbfa9ed40da4b1d0e5d477c3dd7))
+
+  - **Security**
+
+    - add support for SLS mitigation ([538516f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/538516f5d3db6e2c30dfa9f0b82859389f529e78))
+
+- **Documentation**
+
+  - update maintainer list for neoverse_rd ([2d7902d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d7902d9bf0bafceee9f571225862c476de0cdce))
+
+- **Build System**
+
+  - check that .text section starts at page boundary ([3d6edc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d6edc325c52082ab63ffd003c55a4ed875a52c5))
+  - redirect stdin to nul during toolchain detection ([b9014f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9014f858d1fd963a466228ec15572b0892a8490))
+
+- **Tools**
+
+  - **Memory Mapping Tool**
+
+    - add RELA section display ([a6462e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6462e05cf1cd55da44002cdede04053a928cf0a))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - remove CTX_INCLUDE_MTE_REGS usage ([30788a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30788a8455779b70aebd38d53afc8aa19d776c6c))
+    - use ATA bit with FEAT_MTE2 ([ef0d0e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef0d0e5478a3f19cbe70a378b9b184036db38fe2))
+
+  - **Performance Monitors Extension (FEAT_PMUv3)**
+
+    - fix breakage on ARMv7 CPUs with SP_min as BL32 ([e6f8fc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6f8fc7437f6b9483ea0463315809d7ff6d5c0ec))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - invoke spe_disable during power domain off/suspend ([777f1f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/777f1f6897b57fe98c70d17c0d318aab3b86e119))
+
+- **Platforms**
+
+  - **Arm**
+
+    - move console flush/switch in common function ([6bdc856](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6bdc856bc9135db420196683501b4f201b30ae3a))
+    - only expose `arm_bl2_dyn_cfg_init` to BL2 ([3b48ca1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b48ca17f350d8b0999e89e8d9215993701e16a0))
+
+    - **FVP**
+
+      - added ranges for linux ([b7491c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7491c77d7ad2991b8c7c01f0311ebb3b0eca397))
+      - don't check MPIDRs with the power controller in BL1 ([6d8546f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d8546f9fc49a03a817b15b20a9d62fadda74b9c))
+      - permit enabling SME for SPD=spmd ([0b0fd0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b0fd0b47616b706e2f07c6da548cdc913fecd17))
+
+    - **FPGA**
+
+      - halve number of PEs per core ([70b9204](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70b9204e6f98f1ec4f0529e8c1c88e8ece490d22))
+
+    - **Neoverse-RD**
+
+      - **SGI**
+
+        - align to misra rule for braces ([cacee06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cacee0605684a75bbe8783c74fddba97b9abcffa))
+        - apply workarounds for N2 CPU erratum ([7934b68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7934b68af6b446783823a114f25c3be06244c0e4))
+        - increase BL31 carveout size ([0737bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0737bd33faba5c9e6a0e98969e015430e2782332))
+        - reduce cper buffer carveout size ([f10d3e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f10d3e4953741eb3be1f9e4c09e7420554a0f050))
+        - update spi_id max for sgi multichip platforms ([89d8577](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89d857780c50bddf94db26f158c008b4cc846edf))
+
+      - **RD-N1-Edge**
+
+        - update RD-N1-Edge's changelog title ([d239ede](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d239edea5644657ac72458cc13e3ce6bb5754ff8))
+
+      - **RD-N2**
+
+        - populate TOS_CONFIG only when SPMC_AT_EL3 is enabled ([10dcffe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10dcffedb36a658cf8a3389fbdeb499d4e7e4446))
+
+    - **TC**
+
+      - correct interrupts ([d2e44e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e44e7d71863e3b302b5e72c8262bb0f3964fe6))
+      - do not enable MPMM and Aux AMU counters always ([fc42f84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc42f84560d33c53b248e14913bbd6a69a8d310a))
+      - do not use r0 for HW_CONFIG ([a5a966b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5a966b12d9fe51a337db3204e7463ad95ba99c6))
+      - enable FEAT_MTE2 ([154eb0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/154eb0a22fa0a88d1f46e3674e3979626a83e063))
+      - guard PSA crypto headers under TF-M test-suite define ([d2ce6aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2ce6aa066ce1539908726de0d94a59c16634c4a))
+      - increase BL2 maximum size limit ([19258a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19258a5839cae9a81fb7256fbea34ff118220161))
+      - increase stack size when TRUSTED_BOARD_BOOT=0 ([44ddee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44ddee6f0a993ed5b3409e6626c0c70b7ed7d7a2))
+      - missing device regions in spmc manifest ([5e47112](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e4711208db622ff6150e69c87962b506742a544))
+      - remove timer interrupt from G1S ([9bf31a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9bf31a59d187f6537066f05677972d9767e96c82))
+
+  - **Intel**
+
+    - add HPS remapper to remap base address for SDM ([b727664](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b727664e0dcf62be39552521c451ecde02091917))
+    - bl31 overwrite OCRAM configuration ([cfbac59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfbac59590056e6b639aed56a1da480cd46f6f3e))
+    - fix hardcoded mpu frequency ticks ([150d2be](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/150d2be0d2d440011c91c9bf8013a1ab602b464c))
+    - read QSPI bank buffer data in bytes ([2f17ac0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f17ac01adf28edb90a5ec8f446be1be76971b5c))
+    - revert back to use L4 clock ([d0e400b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0e400b3c626be647b9a20bc4f4869e20cc15dde))
+    - revert sys counter to 400MHz ([460692a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/460692afb5b934720b69c410e3b02c540a3b1ddf))
+    - temporarily workaround for Zephyr SMP ([68820f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68820f642191cef67df38516ef1c2ed1411c579f))
+    - update DDR range checking for Agilex5 ([f4aaa9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4aaa9fd6e6b4edd03976680b94e1c24aa582a68))
+    - update fcs crypto init code to check for mode ([b0f4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0f447897d3e2ddd72b291cb450165f4d220663e))
+    - update fcs functions to check ddr range ([e8a3454](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8a3454cb74a9b55c0cb678d47a8553ece660439))
+    - update from INFO to VERBOSE when print debug message ([56c8d02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56c8d022b00ba212f3e21dcfab20c14f3a44eec4))
+    - update HPS bridges for Agilex5 SoC FPGA ([2973054](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2973054d9b4ba4fbcad7e04303ce8e0838b2f2b3))
+    - update individual return result for hps and fpga bridges ([82752c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82752c412362607549068d1c10cf7688f309d249))
+    - update nand driver to match GHRD design ([a773f41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a773f4121b3064fba24631e980c6226f23378e06))
+    - update stream id to non-secure for SDM ([8fbd307](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fbd3073cacfc7a23efdfda4eecfaf6607515306))
+    - update system counter back to 400MHz ([a72f86a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a72f86ac4208e2aae5da83229cdd9ac97f651e36))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - align 3200 MTps rate with U-Boot ([060fe63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/060fe63337097c6cadea76ef5d2d383f0d90ef01))
+        - fix CSU_SA_REG to work with all sa registers ([c13016b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c13016bac6a6960acbbfb3e0176e1894a7e9fa3a))
+        - handle 3734 in addition to 3733 and 3732 MTps rates ([cb60a87](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb60a876efc156c87afcd5ec53b9cf356f30211d))
+
+        - **i.MX 8M Plus**
+
+          - uncondtionally enable only the USB power domain ([ae6ce19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6ce196df5b932f38c543cd8c6d8d86ee600009))
+
+      - **i.MX 8ULP**
+
+        - add sw workaround for csi/hotplug test hang ([e1d5c3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1d5c3c8f435424394367e2ff19240b1b8a3073c))
+        - fix suspend/resume issue when DBD owner is s400 only ([68f132b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68f132b88bb24277ee34d5c3c94d16c26d7d4545))
+        - increase the mmap region num ([047d7d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/047d7d1ba2fc84d8377156f7f45d2d69c3cb5f84))
+
+  - **QEMU**
+
+    - disable FEAT_SB ([59bdb42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bdb426d300a6350334523a8dbc3fa6ae9f3bfc))
+    - increase max FIP size ([f465ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f465ac221001f82bed907be356917675645d92eb))
+
+  - **Raspberry Pi**
+
+    - consider MT when calculating core index from MPIDR ([6744d07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6744d07d9475adb49352fa57aa72fce17a95d757))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - fix implicit rule invocations in tools ([e068a7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e068a7ca860f35a171f608d55fb8a2a00ebd7561))
+
+      - **R-Car 3**
+
+        - change RAM protection configurations ([e9afde1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9afde1a2e311df0197a8e9102ef535382aef228))
+        - fix load address range check ([4f7e0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f7e0fa38fdb6a25b07afafff492985bcc4e63a0))
+
+  - **Rockchip**
+
+    - add support for building with LTO enabled ([e5e9ccd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5e9ccdb0c070d3066e7d778e5e2b563acd7ba98))
+    - fix documentation in how build bl31 in AARCH64 ([6611e81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6611e81e14ed4aa16844e3865fd8a9f6fa99a074))
+
+    - **RK3328**
+
+      - apply ERRATA_A53_1530924 erratum ([dd2c888](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd2c888606dcdd638354c6345e08d4415d9d09fd))
+
+  - **ST**
+
+    - **STM32MP2**
+
+      - add missing include ([cb0d6b5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb0d6b5b5f7530335eac3c387bbb82d86608b0ea))
+      - correct early/crash console init ([4da462d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4da462dcdc2e435c8b732f3ceff4c94ca28b4c43))
+
+  - **Texas Instruments**
+
+    - do not stop non-secure timer on world switch ([d2e1f6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e1f6a8811e52505556f7b91156499d82488751))
+
+    - **K3**
+
+      - increment while reading trail bytes ([0bdaf5c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0bdaf5c804f852fe21f6172e436524157c9f6919))
+
+  - **Xilinx**
+
+    - add console_flush() before shutdown ([7ec53af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ec53afaade308b35f546480990dbc9304e06e7d))
+    - add FIT image check in DT console ([e2d9dfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2d9dfe2bffe4fde28f2714058c8c882ea90102a))
+    - add FIT image check in prepare_dtb ([046e130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/046e1304721e8bbf3d304dac22aa290bcbb0d10c))
+    - check proc variable before use ([652c1ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/652c1ab1526877d3505218f87ea96e6a9b2ccc11))
+    - deprecate SiP service count query ([6a80c20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a80c20eff74054c28273b42f3fe8e1a8fc5add4))
+    - fix sending sgi to linux ([427e46d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/427e46ddea1e528d4c57b1d8215482055bd79c3e))
+    - follow MISRA-C standards for condition check ([655e62a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/655e62aa5bede7ace8f8c6df571707aca9d6e14f))
+    - rename macros to align with ARM ([7995319](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79953190bc856ac3f47281029a80e5129bb4437d))
+    - update correct return types ([8eb6a1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb6a1da1229b8f0bff33293cbb86ce20d09259d))
+
+    - **Versal**
+
+      - initialize cntfrq_el0 register ([f000744](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f000744e0f501c89fb2240b47e91c261e3082249))
+
+      - **Versal NET**
+
+        - setup counter frequency ([07625d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07625d9dd42d81c0e15f101fc0b6efa1c784b6f4))
+        - use arm common GIC handlers ([b225926](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b2259261815961042d2a994401929bc76a0d3ee9))
+
+    - **ZynqMP**
+
+      - resolve null pointer dereferencing ([20fa9fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20fa9fc82334c67834eb22e20a3f4a07bcbe069d))
+
+  - **Nuvoton**
+
+    - gfx frame buffer memory corruption during secondary boot ([ae2b4a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae2b4a5494f9b4985fc2434e543ab0921e3b5a34))
+    - prevent changing clock frequency ([fe8cc55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe8cc55a0cb5e47a0c0e28b147ee3e8dfdae07b2))
+
+- **Bootloader Images**
+
+  - **BL1**
+
+    - add missing `__RW_{START,END}__` symbols ([d701b48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d701b48eef4bb4b4b13ce5ef4091a37047e49a0b))
+    - add missing spinlock dependency ([e40b563](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e40b563e87fd4ff58474a289909a1827c8d2bca7))
+
+  - **BL2**
+
+    - make BL2 SRAM footprint flexible ([e0e03a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0e03a8d8b7eac45606812d1f2a9685b51e44515))
+
+- **Services**
+
+  - **FF-A**
+
+    - add NS memory node to fvp_spmc_optee_sp manifest ([92bba3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92bba3e711a21f2d31842bee64a1bd87e4b65414))
+
+  - **RME**
+
+    - **RMMD**
+
+      - avoid TRP when external RMM is defined ([57bc3c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57bc3c40560285e6029742b7360f8a0d0ac2346c))
+      - fix bug, raised by coverity, when zeroing manifest struct ([83a4e8e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83a4e8e0c69c64219e4d9de6c7f51fb10e3adc5a))
+
+  - **SPM**
+
+    - add device-regions used in tf-a-tests ([45716e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45716e377ecb30c17aa3b375ce1e232d15492b9c))
+    - not defining load-address in SP config ([04e7f80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04e7f80823e8a083138dd25963a5509bacd93257))
+    - reduce verbosity on passing tf-a-tests ([29872eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/29872eb330201334fcb8e418b7dc7ae8ff0dc192))
+    - silence warning in sp_mk_generator ([6a3225e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a3225e2277df18e5c3aceb6173579cccefece51))
+
+    - **EL3 SPMC**
+
+      - add datastore linker script markers ([ba33528](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba33528a00bb83f5562918131cb37574fc287193))
+      - fix dangling pointer in FFA_CONSOLE_LOG ([83129bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83129bcd8e75f1ffbfc9a3bae3d60749b1d22fe3))
+
+    - **SPMD**
+
+      - register group0 handler only if supported ([fca5f0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fca5f0ebe5c2b5cf1c9d5096db6001a60ff7e089))
+      - skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - workaround for Cortex-A520 erratum 2630792 ([f03bfc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f03bfc304599540d859c4a07ac85d1bd9ae2c4f0))
+    - workaround for Cortex-A520 erratum 2858100 ([34db353](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34db3531ba085f111274b3b8e18476c4a392c245))
+    - workaround for Cortex-A710 erratum 2778471 ([c9508d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9508d6a1062ec3de4baaa3bd79ceed13eb972ad))
+    - workaround for Cortex-A715 erratum 2331818 ([53b3cd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53b3cd2532dbdb794ddfedcc8a3985d2404eb6f7))
+    - workaround for Cortex-A715 erratum 2344187 ([33c665a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33c665ae955fe5f5ae255f56ef6cdf073a9f601f))
+    - workaround for Cortex-A715 erratum 2413290 ([15a0461](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15a04615bb6834d93ab0077b89726dc17e3ba8b0))
+    - workaround for Cortex-A715 erratum 2420947 ([1f73247](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f732471320cee7b4f355ecff7dcfab7018e48ae))
+    - workaround for Cortex-A715 erratum 2429384 ([262dc9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/262dc9f76086970dab3dc43815890bed0ea29c79))
+    - workaround for Cortex-A715 erratum 2561034 ([6a6b282](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a6b282378340dc61cf088ff5a06770cf68f44d8))
+    - workaround for Cortex-A715 erratum 2728106 ([10134e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10134e3556ca61e670017e681eb637889b1bd4f8))
+    - workaround for Cortex-A720 erratum 2926083 ([152f4cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152f4cfa16bc3d2786f598390450af38f4b2d0be))
+    - workaround for Cortex-A720 erratum 2940794 ([7385213](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7385213e602465d27530015a9b28ebc36a77b1c1))
+    - workaround for Cortex-A78C erratum 2683027 ([68cac6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68cac6a0f273dbe4f44563b467c996fafef07016))
+    - workaround for Cortex-A78C erratum 2743232 ([81d4094](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81d4094d637871ff34ddd7c2e2b3e842915f30f5))
+    - workaround for Cortex-X2 erratum 2778471 ([b01a93d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b01a93d7789a794ef0635e0a7b0e7e53cc8519e5))
+    - workaround for Cortex-X3 erratum 2266875 ([a65c5ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a65c5ba351178e6119299fa935a3576453cf900b))
+    - workaround for Cortex-X3 erratum 2302506 ([3f9df2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3f9df2c6ad053172c5dab74cd12d82a5b2c93c34))
+    - workaround for Cortex-X3 erratum 2372204 ([7f69a40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f69a40697c3cc64e3fc553f6b50c72b97238dc9))
+    - workaround for Cortex X3 erratum 2641945 ([c1aa3fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1aa3fa5555250dfbcae99fb6944ad24c4ee6a0b))
+    - workaround for Cortex X3 erratum 2743088 ([f43e9f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f43e9f57dc37a806bcd5e25a46b9f9bb1f365a64))
+    - workaround for Cortex-X3 erratum 2779509 ([355ce0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355ce0a43abc1559b072b9cd9905f5194a6f0b86))
+    - workaround for Cortex-X4 erratum 2701112 ([cc41b56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc41b56f41af14b00ce9f5c802e2f883786cef38))
+    - workaround for Cortex-X4 erratum 2740089 ([c833ca6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c833ca66a6fecbc54e038164e466be677559ec4e))
+    - workaround for Cortex-X4 erratum 2763018 ([4731211](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47312115dea140dd7ba26cf0512856a41f3e3067))
+    - workaround for Neoverse V1 erratum 2348377 ([71ed917](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71ed91733140c82a392161c81869fcadb445c01a))
+    - workaround for Neoverse V2 erratum 2618597 ([c0f8ce5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0f8ce5379a77e61e89d91e225784801e5bbd3e0))
+    - workaround for Neoverse V2 erratum 2662553 ([912c409](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/912c4090fff207b445dde4bff72cc9b6e057e8b7))
+    - workaround for Neoverse V2 erratum 3099206 ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+    - add Cortex-A520 definitions ([ae19093](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae19093f2aa6dd95cc7819accb0d05c0ebe4eeb3))
+    - workaround for Cortex-A715 erratum 2413290 re-factored with ENABLE_SPE_FOR_NS=1 ([bd2f7d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd2f7d325826f75acd729d4ee2719fd6130a7c5e))
+    - fix a defect in Cortex-A715 erratum 2561034 ([57ab6d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57ab6d897656f71d229268d80e41b26e62179400))
+    - add erratum 2701951 to Cortex-X3's list ([106c428](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/106c4283a564e4f37976ebc7dd8bc7d35f6592e4))
+    - update status of Cortex-X3 erratum 2615812 ([f589a2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f589a2a5f1b032ff3a09a419e49db0b97ccd8595))
+    - fix incorrect AMU trap settings for N2 CPU ([54b86d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54b86d47eb05f09330df57519b7d04b9968890e5))
+    - correct variant name for default Poseidon CPU ([61a2968](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/61a29682c66d0437806f81fb8ab0e3ff321dfe04))
+    - check for SCU before accessing DSU ([5b5562b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b5562b2e5855f949f1fc0579d7aff15e6b274ef))
+
+  - **EL3 Runtime**
+
+    - **Context Management**
+
+      - add more feature registers to EL1 context mgmt ([d6c76e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6c76e6c65429326e7572e10f521dd9108a3a1e3))
+      - add more system registers to EL1 context mgmt ([ed9bb82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed9bb824e4a3815e60acaa69ed66796279f4afbf))
+      - hide `cm_init_context_by_index` from BL1 ([a6b3643](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6b3643c2a1a95146e93c8b6f07c2e491a1230d6))
+      - remove ENABLE_FEAT_MTE usage ([a796d5a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a796d5aa11b25622841cd2283630ff9348eed699))
+      - save guarded control stack registers ([6aae3ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aae3acfd0d48e49e2367e6cd883dda7dca974c8))
+      - update gic el2 sysregs save/restore mechanism ([937d6fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/937d6fdb70cd24602fd2638a5dbd5c46d32559c1))
+      - couple el2 registers with dependent feature flags ([d6af234](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6af23443179f6d2239c7f5f190f0d8828bd68cf))
+      - move EL1 save/restore routines into C ([59f8882](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59f8882b44845ab865e354eeda8ce653f5d5fcf3))
+
+  - **FCONF**
+
+    - boot fails using ARM_ARCH_MINOR=8 ([0c86a84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c86a846d9149ee5af7e1ee4bb185c532ed9d0f8))
+
+  - **OP-TEE**
+
+    - set interrupt handler before kernel boot ([0ec69a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ec69a5bfbfcdf4566db8e96adaf29ad847d3d58))
+
+  - **PSCI**
+
+    - fix parent_idx in psci_validate_state_coordination ([412d92f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/412d92fdfd28d2f850a48e5f0aee95faa894a556))
+    - mask the Last in Level nibble in StateId ([0a9c244](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a9c244b05ef2d2d4b946ba81bb9b9584b479b48))
+
+  - **GPT**
+
+    - declare gpt_tlbi_by_pa_ll() ([832e4ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/832e4ed520d5ed7e64249fe98c1ffb4550db5eca))
+    - unify logging messages ([b99926e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b99926ef7b287738c4b4a87ee7ab4eaed1e4038f))
+    - use DC CIGDPAPA when MTE2 is implemented ([62d6465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62d64652134ca1d3ea68da65ea9e4ae136f6c44e))
+
+  - **C Standard Library**
+
+    - add memcpy_s source file to libc_asm mk ([99db13b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99db13bfaa5b11345730937c2e0e56cb670c01a5))
+    - memset inclusion to libc makefiles ([84eb3ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84eb3ef6c9f596e968b4f9b83a3a01deda2a8a9d))
+
+  - **PSA**
+
+    - fix static check failure ([bc0ff02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc0ff02cbb046388eff1a95efd0043757d6ac317))
+
+  - **Context Management**
+
+    - align the memory address of EL2 context registers ([8c56a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c56a78894ddc69167bc093fe19f173feced720c))
+
+  - **Firmware Handoff**
+
+    - correct representation of tag_id ([d594ace](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d594ace68d4fa62cf2f1d5d13503b737b85924e5))
+
+  - **Exception Handling Framework (EHF)**
+
+    - restrict secure world FIQ routing model to SPM_MM ([7671008](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7671008fcfc826dbc3166ff1bdbb9cd7fbc7f68b))
+
+  - **SMCCC**
+
+    - correctly find pmf version ([62865b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62865b4ee455806e37a9c5bd52255b8c09cf1a1a))
+
+- **Drivers**
+
+  - **Measured Boot**
+
+    - add missing image identifier string ([a8a09e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8a09e3141354b159e7699d7c9c325bdd817b1f5))
+
+  - **SCMI**
+
+    - induce a delay in monitoring SCMI channel status ([af1ac2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af1ac2d7db47717bc69afd69b56f398aa34b2fb6))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - **GIC-600**
+
+          - workaround for Part 1 of GIC600 erratum 2384374 ([24a4a0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24a4a0a5ec25e179f2e567a6e13a9b5c87db1b81))
+
+      - **GICv2**
+
+        - fix SGIR_NSATT bitshift ([eef240c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eef240cfdedcc59f09dd5cd942448c5dcecc75d6))
+
+    - **MHU**
+
+      - use MHUv2 if PLAT_MHU_VERSION undefined ([c34dd06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c34dd06a843d71cdba2fa1c3c9067f6f130a0c73))
+      - provide only the usable size of memory ([5cd1084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5cd10848be4f6ac19daa66803c3d512e3eea4266))
+
+    - **RSE**
+
+      - fix bound check during protocol selection ([f754bd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f754bd466749a9338561f991bfb85140dd034e03))
+
+  - **Renesas**
+
+    - **R-Car3**
+
+      - add integer overflow check ([ef38fb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef38fb1f5a5f2bdb897158e4244a1eddd2396eeb))
+      - add integer overflow check ([93b8952](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93b8952eefa14141c142070a71fc017736c8910c))
+      - check "rcar_image_number" variable before use ([b469880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b469880e3b6b26849c3d43d3fe88a755a25249bc))
+      - check for length underflow ([9778b27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9778b270e29bac3e16f57f9557098c45858c05de))
+      - check loaded NS image area ([ae4860b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae4860b0f5c283aeca4def1449f0293ef22ff508))
+
+  - **USB**
+
+    - add missing include ([f84f21f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f84f21fa8d17662dcdc6b0b8b0caca4a45cd9ccd))
+
+- **Miscellaneous**
+
+    - **TBBR**
+
+      - move rotpk definitions out of arm_def.h ([0f0fd49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f0fd499dedd799e19279f0aa1f4f686085a944a))
+
+    - code coverage optimization fix ([152ad11](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152ad112d73402523302f3cb252aee0efc145736))
+    - fix MISRA defects ([c42d0d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c42d0d8754ae8818a7e7a63e873ca7699a7f102b))
+    - static checks on spmc dts ([c35299d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c35299d6b4e8b2757e47dc4c5a3b2e0836f89a7d))
+
+- **Documentation**
+
+  - revise the description of REGISTER_CRYPTO_LIB ([5710229](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5710229f9e837f28e4bafee6b51e828f901bf3f1))
+  - typo in the romlib design ([3b57ae2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b57ae23e0891e44d5b648575b80cbad4fc10405))
+
+- **Build System**
+
+  - add forgotten BL_LDFLAGS to lto command line ([49ba1df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49ba1df52204e721f06a6da76ef0f8692ce1b2f8))
+  - don't generate build-id ([304ad94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/304ad94b34c2117823169a199558e7484139caa1))
+  - don't rely on that gcc-ar is in the same directory as gcc ([7ef0b83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ef0b8377fa7fb3697dda5adfa44dafd7e14150f))
+  - enforce single partition for LTO build ([31f80ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31f80efeefaee2c59db50a46cabe2b5fdf20e4ae))
+  - march handling with arch-features ([7275ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7275ac2af86277e2442ef4b0fee6c35cbe830056))
+  - move comment for VERSION_PATCH ([c25d1cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c25d1ccf1e205b2781ecd0de91e91d35e57b79bc))
+  - mute sp_mk_generator from build log ([fbd32ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbd32ac081c421929728f454427b7839235d2075))
+  - properly manage versions in .versionrc.js ([7f74030](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f74030b89136a1673e2a949564403709bc48f5d))
+  - wrap toolchain paths in double quotes ([4731c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4731c00bb60915c0d4b29c082a752e9925a244b4))
+
+- **Tools**
+
+  - **Certificate Creation Tool**
+
+    - add guardrails around brainpool usage ([c0c280d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0c280dfda7322dcaebb5c6341c0880bdf524e13))
+    - use a salt length equal to digest length for RSA-PSS ([e639ad2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e639ad23c8c7a1b320af9ebd519420ae7d431531))
+
+  - **Memory Mapping Tool**
+
+    - fix footprint free space calculation ([9e72d01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9e72d01ed29c350dfc0567c59bc482901211634b))
+    - fix memory map dump when SEPARATE_CODE_AND_RODATA=0 ([6dc8ee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dc8ee61ffeee8ea5aafdbef3121fa4e82b57932))
+
+  - **Marvell Tools**
+
+    - include mbedtls/version.h before use ([8eb4efe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb4efe70bd5b03917e2063ab8ff5646de88922a))
+
 ## [2.10.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.9.0..refs/tags/v2.10.0) (2023-11-21)
 
 ### âš  BREAKING CHANGES
@@ -2667,11 +3585,11 @@
       - route GIC IPI interrupts during setup ([04cc91b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04cc91b43c1d10fcba563e18f06336987e6e3a24))
       - use only one space for indentation ([dee5885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dee588591328b96d9b9ef908869c8b42bd2632f2))
 
-      - **Versal NET**
+    - **Versal NET**
 
-        - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
-        - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
-        - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
+      - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
+      - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
+      - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
 
     - **ZynqMP**
 
@@ -8839,7 +9757,7 @@
 
 ______________________________________________________________________
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 [mbed tls releases]: https://tls.mbed.org/tech-updates/releases
 [pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 9d85bef..78d2f12 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -1,17 +1,17 @@
 Granule Protection Tables Library
 =================================
 
-This document describes the design of the granule protection tables (GPT)
+This document describes the design of the Granule Protection Tables (GPT)
 library used by Trusted Firmware-A (TF-A). This library provides the APIs needed
 to initialize the GPTs based on a data structure containing information about
 the systems memory layout, configure the system registers to enable granule
 protection checks based on these tables, and transition granules between
 different PAS (physical address spaces) at runtime.
 
-Arm CCA adds two new security states for a total of four: root, realm, secure, and
-non-secure. In addition to new security states, corresponding physical address
-spaces have been added to control memory access for each state. The PAS access
-allowed to each security state can be seen in the table below.
+Arm CCA adds two new security states for a total of four: root, realm, secure,
+and non-secure. In addition to new security states, corresponding physical
+address spaces have been added to control memory access for each state. The PAS
+access allowed to each security state can be seen in the table below.
 
 .. list-table:: Security states and PAS access rights
    :widths: 25 25 25 25 25
@@ -45,12 +45,15 @@
 
 The GPT can function as either a 1 level or 2 level lookup depending on how a
 PAS region is configured. The first step is the level 0 table, each entry in the
-level 0 table controls access to a relatively large region in memory (block
+level 0 table controls access to a relatively large region in memory (GPT Block
 descriptor), and the entire region can belong to a single PAS when a one step
-mapping is used, or a level 0 entry can link to a level 1 table where relatively
-small regions (granules) of memory can be assigned to different PAS with a 2
-step mapping. The type of mapping used for each PAS is determined by the user
-when setting up the configuration structure.
+mapping is used. Level 0 entry can also link to a level 1 table (GPT Table
+descriptor) with a 2 step mapping. To change PAS of a region dynamically, the
+region must be mapped in Level 1 table.
+
+The Level 1 tables entries with the same PAS can be combined to form a
+contiguous block entry using GPT Contiguous descriptor. More details about this
+is explained in the following section.
 
 Design Concepts and Interfaces
 ------------------------------
@@ -73,7 +76,8 @@
 GPT setup is split into two parts: table creation and runtime initialization. In
 the table creation step, a data structure containing information about the
 desired PAS regions is passed into the library which validates the mappings,
-creates the tables in memory, and enables granule protection checks. In the
+creates the tables in memory, and enables granule protection checks. It also
+allocates memory for fine-grained locks adjacent to the L0 tables. In the
 runtime initialization step, the runtime firmware locates the existing tables in
 memory using the GPT register configuration and saves important data to a
 structure used by the granule transition service which will be covered more
@@ -85,6 +89,10 @@
 runtime initialization API calls can be seen in
 ``plat/arm/common/arm_bl31_setup.c``.
 
+During the table creation time, the GPT lib opportunistically fuses contiguous
+GPT L1 entries having the same PAS. The maximum size of
+supported contiguous blocks is defined by ``RME_GPT_MAX_BLOCK`` build option.
+
 Defining PAS regions
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -115,8 +123,13 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The GPT initialization APIs require memory to be passed in for the tables to be
-constructed, ``gpt_init_l0_tables`` takes a memory address and size for building
-the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for
+constructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
+building the level 0 tables and also memory for allocating the fine-grained bitlock
+data structure. The amount of memory needed for bitlock structure is controlled via
+``RME_GPT_BITLOCK_BLOCK`` config which defines the block size for each bit of the
+the bitlock.
+
+The ``gpt_init_pas_l1_tables`` API takes an address and size for
 building the level 1 tables which are linked from level 0 descriptors. The
 tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
 its level 0 table in SRAM and its level 1 table(s) in DRAM.
@@ -124,12 +137,28 @@
 Granule Transition Service
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE
-ownership to be changed using SMC calls. Non-secure granules can be transitioned
-to either realm or secure space, and realm and secure granules can be
-transitioned back to non-secure. This library only allows memory mapped as
-granules to be transitioned, memory mapped as blocks have their GPIs fixed after
-table creation.
+The Granule Transition Service allows memory mapped with
+``GPT_MAP_REGION_GRANULE`` ownership to be changed using SMC calls. Non-secure
+granules can be transitioned to either realm or secure space, and realm and
+secure granules can be transitioned back to non-secure. This library only
+allows Level 1 entries to be transitioned. The lib may either shatter
+contiguous blocks or fuse adjacent GPT entries to form a contiguous block
+opportunistically. Depending on the maximum block size, the fuse operation may
+propogate to higher block sizes as allowed by RME Architecture. Thus a higher
+maximum block size may have a higher runtime cost due to software operations
+that need to be performed for fuse to bigger block sizes. This cost may
+be offset by better TLB performance due to the higher block size and platforms
+need to make the trade-off decision based on their particular workload.
+
+Locking Scheme
+~~~~~~~~~~~~~~
+
+During Granule Transition access to L1 tables is controlled by a lock to ensure
+that no more than one CPU is allowed to make changes at any given time.
+The granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
+which defines the size of the memory block protected by one bit of ``bitlock``
+structure. Setting this option to 0 chooses a single spinlock for all GPT L1
+table entries.
 
 Library APIs
 ------------
@@ -196,7 +225,9 @@
   is greater. L0 table size is the total protected space (PPS) divided by the
   size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
   (8 bytes). ((PPS / L0GPTSZ) * 8)
-* The L0 memory size must be greater than or equal to the table size.
+* The L0 memory size must be greater than the table size and have enough space
+  to allocate array of ``bitlock`` structures at the end of L0 table if
+  required (``RME_GPT_BITLOCK_BLOCK`` is not 0).
 * The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
 
 The L1 memory also has some constraints.
@@ -223,6 +254,24 @@
 And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
 tables must be aligned to 4096 bytes.
 
+Sample calculation for bitlock array size
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PGS=GPCCR_PPS_256TB and RME_GPT_BITLOCK_BLOCK=1
+
+The size of bit lock array in bits is the total protected space (PPS) divided
+by the size of memory block per bit. The size of memory block
+is ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
+512MB (0x20000000). This is then divided by the number of bits in ``bitlock``
+structure (8) to get the size of bit array in bytes.
+
+In other words, we can find the total size of ``bitlock`` array
+in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 *  8).
+
+Substitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)
+
+And solve to get 0x10000 bytes.
+
 Sample calculation for L1 table size and alignment
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/conf.py b/docs/conf.py
index d4e5423..3f9655b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -14,8 +14,8 @@
 
 project = "Trusted Firmware-A"
 author = "Trusted Firmware-A contributors"
-version = "2.10.0"
-release = "2.10.0"
+version = "2.11.0"
+release = "2.11.0"
 
 # -- General configuration ---------------------------------------------------
 
diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst
index d88942e..f946b2e 100644
--- a/docs/design_documents/cmake_framework.rst
+++ b/docs/design_documents/cmake_framework.rst
@@ -11,11 +11,7 @@
 Abstract
 --------
 This document presents a proposal for a new buildsystem for TF-A using CMake,
-and as part of this a reusable CMake framework for embedded projects. For a
-summary about the proposal, please see the `Phabricator wiki page
-<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
-mentioned there, the proposal consists of two phases. The subject of this
-document is the first phase only.
+and as part of this a reusable CMake framework for embedded projects.
 
 Introduction
 ------------
@@ -162,4 +158,4 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/rse.rst b/docs/design_documents/rse.rst
index 7296a45..e0e0fb3 100644
--- a/docs/design_documents/rse.rst
+++ b/docs/design_documents/rse.rst
@@ -482,74 +482,101 @@
     INFO:    Get platform token start
     INFO:    Get platform token succeeds, len: 1086
     INFO:    Platform attestation token:
-    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19
-    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
-    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
-    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
-    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
-    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
-    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
-    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
-    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
-    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
-    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
-    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
-    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
-    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
-    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
-    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
-    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
-    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
-    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
-    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
-    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
-    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
-    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
-    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
-    INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
-    INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
-    INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
-    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 b0 f3 82 09
-    INFO:            12 97 d8 3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2
-    INFO:            49 59 f6 5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6a
-    INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
-    INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
-    INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
-    INFO:            20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec 32
-    INFO:            73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22 9a
-    INFO:            da 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
-    INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
-    INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
-    INFO:            e3 ee af 1b 05 a4 05 58 20 b0 f3 82 09 12 97 d8
-    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
-    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 65 42 4c 5f
-    INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
-    INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
-    INFO:            2d 30 28 05 c3 a4 05 58 20 b0 f3 82 09 12 97 d8
-    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
-    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6e 53 45 43
-    INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
-    INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
-    INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
-    INFO:            58 20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec
-    INFO:            32 73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22
-    INFO:            9a da 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
-    INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
-    INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
-    INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
-    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
-    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
-    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
-    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
-    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
-    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
-    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
-    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
-    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
-    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
-    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
+    INFO:            d2 84 44 a1 01 38 22 a0 59 05 7a a9 19 01 09 78
+    INFO:            1c 68 74 74 70 3a 2f 2f 61 72 6d 2e 63 6f 6d 2f
+    INFO:            43 43 41 2d 53 53 44 2f 31 2e 30 2e 30 0a 58 20
+    INFO:            b5 97 3c b6 8b aa 9f c5 55 58 78 6b 7e c6 7f 69
+    INFO:            e4 0d f5 ba 5a a9 21 cd 0c 27 f4 05 87 a0 11 ea
+    INFO:            19 09 5c 58 20 7f 45 4c 46 02 01 01 00 00 00 00
+    INFO:            00 00 00 00 00 03 00 3e 00 01 00 00 00 50 58 00
+    INFO:            00 00 00 00 00 19 01 00 58 21 01 07 06 05 04 03
+    INFO:            02 01 00 0f 0e 0d 0c 0b 0a 09 08 17 16 15 14 13
+    INFO:            12 11 10 1f 1e 1d 1c 1b 1a 19 18 19 09 61 44 cf
+    INFO:            cf cf cf 19 09 5b 19 30 03 19 09 62 67 73 68 61
+    INFO:            2d 32 35 36 19 09 60 78 3a 68 74 74 70 73 3a 2f
+    INFO:            2f 76 65 72 61 69 73 6f 6e 2e 65 78 61 6d 70 6c
+    INFO:            65 2f 2e 77 65 6c 6c 2d 6b 6e 6f 77 6e 2f 76 65
+    INFO:            72 61 69 73 6f 6e 2f 76 65 72 69 66 69 63 61 74
+    INFO:            69 6f 6e 19 09 5f 8d a4 01 69 52 53 45 5f 42 4c
+    INFO:            31 5f 32 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 9a 27 1f 2a 91 6b 0b
+    INFO:            6e e6 ce cb 24 26 f0 b3 20 6e f0 74 57 8b e5 5d
+    INFO:            9b c9 4f 6f 3f e3 ab 86 aa 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 52 53 45 5f 42 4c 32 05 58 20 53
+    INFO:            78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41
+    INFO:            41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02
+    INFO:            58 20 53 c2 34 e5 e8 47 2b 6a c5 1c 1a e1 ca b3
+    INFO:            fe 06 fa d0 53 be b8 eb fd 89 77 b0 10 65 5b fd
+    INFO:            d3 c3 06 67 73 68 61 2d 32 35 36 a4 01 65 52 53
+    INFO:            45 5f 53 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 11 21 cf cc d5 91 3f
+    INFO:            0a 63 fe c4 0a 6f fd 44 ea 64 f9 dc 13 5c 66 63
+    INFO:            4b a0 01 d1 0b cf 43 02 a2 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 66 41 50 5f 42 4c 31 05 58 20 53 78
+    INFO:            79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41
+    INFO:            9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58
+    INFO:            20 15 71 b5 ec 78 bd 68 51 2b f7 83 0b b6 a2 a4
+    INFO:            4b 20 47 c7 df 57 bc e7 9e b8 a1 c0 e5 be a0 a5
+    INFO:            01 06 67 73 68 61 2d 32 35 36 a4 01 66 41 50 5f
+    INFO:            42 4c 32 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 10 15 9b af 26 2b 43
+    INFO:            a9 2d 95 db 59 da e1 f7 2c 64 51 27 30 16 61 e0
+    INFO:            a3 ce 4e 38 b2 95 a9 7c 58 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 53 43 50 5f 42 4c 31 05 58 20 53
+    INFO:            78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41
+    INFO:            41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02
+    INFO:            58 20 10 12 2e 85 6b 3f cd 49 f0 63 63 63 17 47
+    INFO:            61 49 cb 73 0a 1a a1 cf aa d8 18 55 2b 72 f5 6d
+    INFO:            6f 68 06 67 73 68 61 2d 32 35 36 a4 01 67 53 43
+    INFO:            50 5f 42 4c 32 05 58 20 f1 4b 49 87 90 4b cb 58
+    INFO:            14 e4 45 9a 05 7e d4 d2 0f 58 a6 33 15 22 88 a7
+    INFO:            61 21 4d cd 28 78 0b 56 02 58 20 aa 67 a1 69 b0
+    INFO:            bb a2 17 aa 0a a8 8a 65 34 69 20 c8 4c 42 44 7c
+    INFO:            36 ba 5f 7e a6 5f 42 2c 1f e5 d8 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 67 41 50 5f 42 4c 33 31 05 58
+    INFO:            20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc
+    INFO:            56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a
+    INFO:            a3 02 58 20 2e 6d 31 a5 98 3a 91 25 1b fa e5 ae
+    INFO:            fa 1c 0a 19 d8 ba 3c f6 01 d0 e8 a7 06 b4 cf a9
+    INFO:            66 1a 6b 8a 06 67 73 68 61 2d 32 35 36 a4 01 63
+    INFO:            52 4d 4d 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 a1 fb 50 e6 c8 6f ae
+    INFO:            16 79 ef 33 51 29 6f d6 71 34 11 a0 8c f8 dd 17
+    INFO:            90 a4 fd 05 fa e8 68 81 64 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 69 48 57 5f 43 4f 4e 46 49 47 05 58
+    INFO:            20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc
+    INFO:            56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a
+    INFO:            a3 02 58 20 1a 25 24 02 97 2f 60 57 fa 53 cc 17
+    INFO:            2b 52 b9 ff ca 69 8e 18 31 1f ac d0 f3 b0 6e ca
+    INFO:            ae f7 9e 17 06 67 73 68 61 2d 32 35 36 a4 01 69
+    INFO:            46 57 5f 43 4f 4e 46 49 47 05 58 20 53 78 79 63
+    INFO:            07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d
+    INFO:            30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20 9a
+    INFO:            92 ad bc 0c ee 38 ef 65 8c 71 ce 1b 1b f8 c6 56
+    INFO:            68 f1 66 bf b2 13 64 4c 89 5c cb 1a d0 7a 25 06
+    INFO:            67 73 68 61 2d 32 35 36 a4 01 6c 54 42 5f 46 57
+    INFO:            5f 43 4f 4e 46 49 47 05 58 20 53 78 79 63 07 53
+    INFO:            5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60
+    INFO:            cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20 23 89 03
+    INFO:            18 0c c1 04 ec 2c 5d 8b 3f 20 c5 bc 61 b3 89 ec
+    INFO:            0a 96 7d f8 cc 20 8c dc 7c d4 54 17 4f 06 67 73
+    INFO:            68 61 2d 32 35 36 a4 01 6d 53 4f 43 5f 46 57 5f
+    INFO:            43 4f 4e 46 49 47 05 58 20 53 78 79 63 07 53 5d
+    INFO:            f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf
+    INFO:            e3 22 38 c0 fa 97 3f 7a a3 02 58 20 e6 c2 1e 8d
+    INFO:            26 0f e7 18 82 de bd b3 39 d2 40 2a 2c a7 64 85
+    INFO:            29 bc 23 03 f4 86 49 bc e0 38 00 17 06 67 73 68
+    INFO:            61 2d 32 35 36 58 60 21 51 20 92 d6 d0 2a e6 be
+    INFO:            2f e3 93 0e a5 1f d6 98 96 32 24 56 e9 df c7 32
+    INFO:            5e 0b 78 68 b6 90 73 2a 0c 0f 07 77 c1 15 40 4b
+    INFO:            e1 fc 83 9b 7d 30 4f 4f e6 fa 46 ae 12 a3 08 3a
+    INFO:            cf 24 06 67 91 06 bf ae 50 31 79 dd 50 33 49 12
+    INFO:            bf c6 da 33 6d d6 18 25 43 54 4d b5 88 d6 ae 67
+    INFO:            35 7a fd b0 5f 95 b7
     INFO:    DELEGATED ATTEST TEST END
 
 JSON format:
@@ -557,70 +584,94 @@
 .. code-block:: JSON
 
     {
-        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
-        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
-        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
-        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
+        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
+        "CCA_PLATFORM_CHALLENGE": "b'B5973CB68BAA9FC55558786B7EC67F69E40DF5BA5AA921CD0C27F40587A011EA'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'7F454C4602010100000000000000000003003E00010000005058000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
+        "CCA_PLATFORM_CONFIG": "b'CFCFCFCF'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3003",
+        "CCA_PLATFORM_HASH_ALGO_ID": "sha-256",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "https://veraison.example/.well-known/veraison/verification",
         "CCA_PLATFORM_SW_COMPONENTS": [
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.6.0+0",
-                "SW_COMPONENT_TYPE": "RT_0",
-                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
+                "SW_COMPONENT_TYPE": "RSE_BL1_2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A271F2A916B0B6EE6CECB2426F0B3206EF074578BE55D9BC94F6F3FE3AB86AA'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
-                "SW_COMPONENT_VERSION": "0.0.0+0",
-                "SW_COMPONENT_TYPE": "RT_1",
-                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
+                "SW_COMPONENT_TYPE": "RSE_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'53C234E5E8472B6AC51C1AE1CAB3FE06FAD053BEB8EBFD8977B010655BFDD3C3'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "RT_2",
-                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
+                "SW_COMPONENT_TYPE": "RSE_S",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1121CFCCD5913F0A63FEC40A6FFD44EA64F9DC135C66634BA001D10BCF4302A2'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "",
-                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
+                "SW_COMPONENT_TYPE": "AP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1571B5EC78BD68512BF7830BB6A2A44B2047C7DF57BCE79EB8A1C0E5BEA0A501'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
+                "SW_COMPONENT_TYPE": "AP_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10159BAF262B43A92D95DB59DAE1F72C645127301661E0A3CE4E38B295A97C58'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
+                "SW_COMPONENT_TYPE": "SCP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10122E856B3FCD49F063636317476149CB730A1AA1CFAAD818552B72F56D6F68'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "BL_2\u0000",
-                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
+                "SW_COMPONENT_TYPE": "SCP_BL2",
+                "SIGNER_ID": "b'F14B4987904BCB5814E4459A057ED4D20F58A633152288A761214DCD28780B56'",
+                "MEASUREMENT_VALUE": "b'AA67A169B0BBA217AA0AA88A65346920C84C42447C36BA5F7EA65F422C1FE5D8'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
-                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
+                "SW_COMPONENT_TYPE": "AP_BL31",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'2E6D31A5983A91251BFAE5AEFA1C0A19D8BA3CF601D0E8A706B4CFA9661A6B8A'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
+                "SW_COMPONENT_TYPE": "RMM",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'A1FB50E6C86FAE1679EF3351296FD6713411A08CF8DD1790A4FD05FAE8688164'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "HW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1A252402972F6057FA53CC172B52B9FFCA698E18311FACD0F3B06ECAAEF79E17'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A92ADBC0CEE38EF658C71CE1B1BF8C65668F166BFB213644C895CCB1AD07A25'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'238903180CC104EC2C5D8B3F20C5BC61B389EC0A967DF8CC208CDC7CD454174F'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "SOC_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'E6C21E8D260FE71882DEBDB339D2402A2CA7648529BC2303F48649BCE0380017'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             }
-        ],
-        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
-        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
-        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
-        "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
+        ]
     }
 
 RSE OTP Assets Management
@@ -688,3 +739,4 @@
 --------------
 
 *Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2024, Linaro Limited. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 6ab95f9..4c070ed 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -23,8 +23,9 @@
    is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
 
 -  ``AMU_RESTRICT_COUNTERS``: Register reads to the group 1 counters will return
-   zero at all but the highest implemented exception level.  Reads from the
-   memory mapped view are unaffected by this control.
+   zero at all but the highest implemented exception level. External
+   memory-mapped debug accesses are unaffected by this control.
+   The default value is 1 for all platforms.
 
 -  ``ARCH`` : Choose the target build architecture for TF-A. It can take either
    ``aarch64`` or ``aarch32`` as values. By default, it is defined to
@@ -320,6 +321,12 @@
    The flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
+- ``ENABLE_FEAT_DEBUGV8P9``: Numeric value to enable ``FEAT_DEBUGV8P9``
+   extension which allows the ability to implement more than 16 breakpoints
+   and/or watchpoints. This feature is mandatory from v8.9 and is optional
+   from v8.8. This flag can take the values of 0 to 2, to align with the
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
    Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
    ``FEAT_DIT`` is a mandatory  architectural feature and is enabled from v8.4
@@ -340,6 +347,13 @@
    This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_FGT2``: Numeric value to enable support for FGT2
+   (Fine Grain Traps 2) feature allowing for access to Fine-grained trap 2 registers
+   during  EL2 to EL3 context save/restore operations.
+   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_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to
    allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as
    well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a
@@ -701,13 +715,6 @@
 
    This option defaults to 0.
 
--  ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
-   backend when ``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 DICE Protection Environment for storage
-   and processing. A certificate chain, which represents the boot state of the
-   device, can be queried from the DPE.
-
 -  ``MARCH_DIRECTIVE``: used to pass a -march option from the platform build
    options to the compiler. An example usage:
 
@@ -812,6 +819,21 @@
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
    entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
 
+-  ``RME_GPT_BITLOCK_BLOCK``: This defines the block size (in number of 512MB
+-  blocks) covered by a single bit of the bitlock structure during RME GPT
+-  operations. The lower the block size, the better opportunity for
+-  parallelising GPT operations but at the cost of more bits being needed
+-  for the bitlock structure. This numeric parameter can take the values
+-  from 0 to 512 and must be a power of 2. The value of 0 is special and
+-  and it chooses a single spinlock for all GPT L1 table entries. Default
+-  value is 1 which corresponds to block size of 512MB per bit of bitlock
+-  structure.
+
+-  ``RME_GPT_MAX_BLOCK``: Numeric value in MB to define the maximum size of
+   supported contiguous blocks in GPT Library. This parameter can take the
+   values 0, 2, 32 and 512. Setting this value to 0 disables use of Contigious
+   descriptors. Default value is 2.
+
 -  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
    file that contains the ROT private key in PEM format or a PKCS11 URI and
    enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is
@@ -1257,6 +1279,13 @@
 Common build options
 ~~~~~~~~~~~~~~~~~~~~
 
+-  ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+   backend when ``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 DICE Protection Environment for storage
+   and processing. A certificate chain, which represents the boot state of the
+   device, can be queried from the DPE.
+
 -  ``DRTM_SUPPORT``: Boolean flag to enable support for Dynamic Root of Trust
    for Measurement (DRTM). This feature has trust dependency on BL31 for taking
    the measurements and recording them as per `PSA DRTM specification`_. For
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index bab1086..43a7d59 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.9-rc0`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.11-rc0`_
+- `TFTF v2.11-rc0`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
 <Runtime Instrumentation Methodology>`
@@ -73,23 +73,23 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
+        parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   104.58  | 241.20 |     5.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   384.24  | 22.50  |    138.76   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   244.56  | 22.18  |     5.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   670.56  | 18.58  |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   809.36  | 269.28 |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   984.96  | 219.70 |    79.62    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-------------------+--------------------+-------------+
+    | Cluster | Core |     Powerdown     |       Wakeup       | Cache Flush |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  0   |  112.98 (-53.44%) |  26.16 (-89.33%)   |     5.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  1   |       411.18      | 438.88 (+1572.56%) |    138.54   |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  0   | 261.82 (+150.88%) | 474.06 (+1649.30%) |     5.6     |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  1   |  714.76 (+86.84%) |       26.44        |     4.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  2   |       862.66      |  149.34 (-45.00%)  |     4.38    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  3   |      1045.12      |  98.12 (-55.76%)   |    79.74    |
+    +---------+------+-------------------+--------------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         parallel (v2.10)
@@ -111,22 +111,22 @@
     +---------+------+-------------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
+        serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.56  | 23.24  |    138.18   |
+    |    0    |  0   |   244.42  | 27.42  |    138.12   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   236.86  | 23.28  |    138.10   |
+    |    0    |  1   |   245.02  | 27.34  |    138.08   |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   281.04  | 22.80  |    77.24    |
+    |    1    |  0   |   297.66  |  26.2  |    77.68    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.28  | 18.52  |     4.54    |
+    |    1    |  1   |   108.02  | 21.94  |     4.52    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.12  | 18.78  |     4.50    |
+    |    1    |  2   |   107.48  | 21.88  |     4.46    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.36  | 18.94  |     4.44    |
+    |    1    |  3   |   107.52  | 21.86  |     4.46    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
@@ -152,23 +152,23 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
+        parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   662.34  | 15.22  |     8.08    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   802.00  | 15.50  |     8.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   385.22  | 15.74  |     7.88    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   106.16  | 16.06  |     7.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   524.38  | 15.64  |     7.34    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   246.00  | 15.78  |     7.72    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-------------------+--------+-------------+
+    | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
+    +---------+------+-------------------+--------+-------------+
+    |    0    |  0   |       704.46      | 19.28  |     7.86    |
+    +---------+------+-------------------+--------+-------------+
+    |    0    |  1   |       853.66      | 18.78  |     7.82    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  0   | 556.52 (+425.51%) | 19.06  |     7.82    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  1   |  113.28 (-70.47%) | 19.28  |     7.48    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  2   |  260.62 (-50.22%) |  19.8  |     7.26    |
+    +---------+------+-------------------+--------+-------------+
+    |    1    |  3   |  408.16 (+66.94%) | 19.82  |     7.38    |
+    +---------+------+-------------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
         parallel (v2.10)
@@ -189,22 +189,22 @@
     |    1    |  3   |       244.5       | 20.16  |     7.56    |
     +---------+------+-------------------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   99.80   | 15.94  |     5.42    |
+    |    0    |  0   |   106.78  |  19.2  |     5.32    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   99.76   | 15.80  |     5.24    |
+    |    0    |  1   |   107.44  | 19.64  |     5.44    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   278.26  | 16.16  |     4.58    |
+    |    1    |  0   |   295.82  | 19.14  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   96.88   | 16.00  |     4.52    |
+    |    1    |  1   |   104.34  | 19.18  |     4.28    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   96.80   | 16.12  |     4.54    |
+    |    1    |  2   |   103.96  | 19.34  |     4.4     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   96.88   | 16.12  |     4.54    |
+    |    1    |  3   |   104.32  | 19.18  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
@@ -231,22 +231,22 @@
 ``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.9)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   235.76  | 26.14  |    137.80   |
+    |    0    |  0   |   243.62  | 29.84  |    137.66   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   235.40  | 25.72  |    137.62   |
+    |    0    |  1   |   243.88  | 29.54  |    137.8    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   174.70  | 22.40  |    77.26    |
+    |    1    |  0   |   183.26  | 26.22  |    77.76    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.92  | 24.04  |     4.52    |
+    |    1    |  1   |   107.64  | 26.74  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.68  | 22.44  |     4.36    |
+    |    1    |  2   |   107.52  |  25.9  |     4.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   101.36  | 22.70  |     4.52    |
+    |    1    |  3   |   107.74  |  25.8  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
@@ -272,23 +272,23 @@
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.9)
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.11)
 
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     1.48    |
-    +-------------+--------+-------------+
-    |      0      |   1    |     1.04    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.56    |
-    +-------------+--------+-------------+
-    |      1      |   1    |     0.92    |
-    +-------------+--------+-------------+
-    |      1      |   2    |     0.96    |
-    +-------------+--------+-------------+
-    |      1      |   3    |     0.96    |
-    +-------------+--------+-------------+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     1.26     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     0.96     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.54     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     0.92     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     1.02     |
+    +-------------+--------+--------------+
 
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.10)
 
@@ -526,8 +526,9 @@
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _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
-.. _v2.9-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.9-rc0
+.. _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
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
index fd3c9c9..c1c4dd6 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.9-rc0-16-g666aec401`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.11-rc0`_
+- `TFTF v2.11-rc0`_
 - SCP/MCP `Prebuilt Images`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
@@ -92,20 +92,19 @@
 ``CPU_SUSPEND`` to deepest power level
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.80   | 10.08  |     0.80    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    4.14   | 15.92  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.68   | 12.96  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.36   | 18.58  |     0.18    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+----------------+--------+----------------+
+    | Cluster | Core |   Powerdown    | Wakeup |  Cache Flush   |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   | 3.0 (+41.51%)  | 23.14  | 1.2 (+185.71%) |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   |      4.6       | 35.86  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.68 (+33.33%) | 33.36  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.7 (+40.15%)  |  38.1  |      0.28      |
+    +---------+------+----------------+--------+----------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
         parallel (v2.10)
@@ -122,19 +121,18 @@
     |    1    |  0   |      2.64      | 44.56 (+139.83%) | 0.36 (+100.00%) |
     +---------+------+----------------+------------------+-----------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.86   |  9.92  |     0.32    |
+    |    0    |  0   |    1.7    | 22.46  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.70   | 10.48  |     0.36    |
+    |    0    |  0   |    2.28   |  22.5  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.78   |  9.72  |     0.16    |
+    |    1    |  0   |    2.14   |  21.5  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.94   | 10.44  |     0.16    |
+    |    1    |  0   |    2.24   | 22.66  |     0.3     |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
@@ -155,22 +153,19 @@
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.11)
 
-    +---------------------------------------------------+
-    |          test_rt_instr_cpu_susp_parallel          |
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    0.88   | 12.32  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.12   | 14.62  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.86   | 14.14  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.92   |  9.44  |     0.18    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+----------------+--------+-------------+
+    | Cluster | Core |   Powerdown    | Wakeup | Cache Flush |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   | 0.94 (-37.33%) | 30.36  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   |      2.12      | 33.12  |     0.28    |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.08      | 32.56  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.14      | 21.92  |     0.28    |
+    +---------+------+----------------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
         parallel (v2.10)
@@ -187,20 +182,18 @@
     |    1    |  0   |      2.04     | 23.1 (+144.70%)  |      0.24      |
     +---------+------+---------------+------------------+----------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
-    +---------------------------------------------------+
-    |           test_rt_instr_cpu_susp_serial           |
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.52   |  9.40  |     0.30    |
+    |    0    |  0   |    1.64   | 21.88  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.92   |  9.80  |     0.18    |
+    |    0    |  0   |    2.42   | 21.76  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    2.20   |  9.60  |     0.14    |
+    |    1    |  0   |    2.02   | 21.14  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.82   |  9.78  |     0.18    |
+    |    1    |  0   |    2.18   |  22.3  |     0.34    |
     +---------+------+-----------+--------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
@@ -223,19 +216,19 @@
 ``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.9)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.84   |  9.94  |     0.32    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   14.20   | 13.10  |     0.50    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   13.88   | 12.36  |     0.42    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   14.40   | 13.26  |     0.52    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.96   | 22.44  |      0.38      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |   13.76   | 30.34  |      0.26      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.46   | 28.28  |      0.24      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.84   | 30.06  | 0.28 (-60.00%) |
+    +---------+------+-----------+--------+----------------+
 
 .. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
 
@@ -254,21 +247,19 @@
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.9)
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.11)
 
-    +------------------------------------+
-    | test_rt_instr_psci_version_parallel|
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.08    |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.26    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.20    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.26    |
-    +-------------+--------+-------------+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.12     |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.24     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.2      |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.26     |
+    +-------------+--------+--------------+
 
 .. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.10)
 
@@ -288,10 +279,10 @@
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
-.. _v2.9-rc0-16-g666aec401: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/v2.9-rc0-16-g666aec401
-.. _v2.9-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.9-rc0
+.. _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
 .. _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/
 .. _N1SDP: https://developer.arm.com/documentation/101489/latest
diff --git a/docs/plat/amd-versal2.rst b/docs/plat/amd-versal2.rst
new file mode 100644
index 0000000..876ab3c
--- /dev/null
+++ b/docs/plat/amd-versal2.rst
@@ -0,0 +1,87 @@
+AMD Versal Gen 2
+================
+
+Trusted Firmware-A implements the EL3 firmware layer for AMD Versal Gen 2.
+The platform only uses the runtime part of TF-A as AMD Versal Gen 2 already
+has a BootROM (BL1) and PMC FW (BL2).
+
+BL31 is TF-A.
+BL32 is an optional Secure Payload.
+BL33 is the non-secure world software (U-Boot, Linux etc).
+
+To build:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31
+```
+
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 CONSOLE=dcc bl31
+```
+
+To build TF-A with Errata management interface
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 ERRATA_ABI_SUPPORT=1
+```
+
+To build TF-A with IPI CRC check:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 IPI_CRC_CHECK=1
+```
+
+AMD Versal Gen 2 platform specific build options
+-------------------------------------------------
+
+*   `MEM_BASE`: Specifies the base address of the bl31 binary.
+*   `MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
+*   `BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
+*   `BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
+
+*   `CONSOLE`: Select the console driver. Options:
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
+    -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
+
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/arm/fvp/fvp-support.rst b/docs/plat/arm/fvp/fvp-support.rst
index cc1b500..5292d68 100644
--- a/docs/plat/arm/fvp/fvp-support.rst
+++ b/docs/plat/arm/fvp/fvp-support.rst
@@ -9,25 +9,21 @@
 (64-bit host machine only).
 
 .. note::
-   The FVP models used are Version 11.22 Build 14, unless otherwise stated.
+   The FVP models used are Version 11.26 Build 11, unless otherwise stated.
 
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` (Version 11.17/21)
--  ``FVP_Base_AEMv8A-GIC600AE`` (Version 11.17/21)
 -  ``FVP_Base_AEMvA``
 -  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4`` (Version 11.12/38)
+-  ``FVP_Base_Cortex-A32x4``
 -  ``FVP_Base_Cortex-A35x4``
 -  ``FVP_Base_Cortex-A53x4``
 -  ``FVP_Base_Cortex-A55``
--  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
--  ``FVP_Base_Cortex-A55x4+Cortex-A76x2``
 -  ``FVP_Base_Cortex-A57x1-A53x1``
 -  ``FVP_Base_Cortex-A57x2-A53x4``
 -  ``FVP_Base_Cortex-A57x4``
 -  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A65``
--  ``FVP_Base_Cortex-A65AE``
--  ``FVP_Base_Cortex-A710x4`` (Version 11.17/21)
+-  ``FVP_Base_Cortex-A65`` (Version 11.24/24)
+-  ``FVP_Base_Cortex-A65AE`` (Version 11.24/24)
+-  ``FVP_Base_Cortex-A710``
 -  ``FVP_Base_Cortex-A72x4``
 -  ``FVP_Base_Cortex-A72x4-A53x4``
 -  ``FVP_Base_Cortex-A73x4``
@@ -39,15 +35,15 @@
 -  ``FVP_Base_Cortex-A78``
 -  ``FVP_Base_Cortex-A78AE``
 -  ``FVP_Base_Cortex-A78C``
--  ``FVP_Base_Cortex-X2x4`` (Version 11.17/21)
--  ``FVP_Base_Neoverse-E1``
+-  ``FVP_Base_Cortex-X2``
+-  ``FVP_Base_Neoverse-E1`` (Version 11.24/24)
 -  ``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_TC1``
 -  ``FVP_TC2`` (Version 11.23/17)
 
 The latest version of the AArch32 build of TF-A has been tested on the
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 5c1ded0..85c97e5 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -7,6 +7,7 @@
    :hidden:
 
    allwinner
+   amd-versal2
    arm/index
    ast2700
    meson-axg
diff --git a/docs/plat/mt8195.rst b/docs/plat/mt8195.rst
index b2aeea2..9810f9e 100644
--- a/docs/plat/mt8195.rst
+++ b/docs/plat/mt8195.rst
@@ -2,8 +2,8 @@
 =============
 
 MediaTek 8195 (MT8195) is a 64-bit ARM SoC introduced by MediaTek in 2021.
-The chip incorporates eight cores - four Cortex-A55 little cores and Cortex-A76.
-Cortex-A76 can operate at up to 2.2 GHz.
+The chip incorporates eight cores - four Cortex-A55 little cores and Cortex-A78.
+Cortex-A78 can operate at up to 2.6 GHz.
 Cortex-A55 can operate at up to 2.0 GHz.
 
 Boot Sequence
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 01cf176..53f63b5 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -10,6 +10,7 @@
 -  rk3328: Quad-Core Cortex-A53
 -  rk3368: Octa-Core Cortex-A53
 -  rk3399: Hexa-Core Cortex-A53/A72
+-  rk3566/rk3568: Quad-Core Cortex-A55
 
 
 Boot Sequence
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 43e131d..5d4ab4e 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -4,6 +4,8 @@
 STM32MP2 is a microprocessor designed by STMicroelectronics
 based on Arm Cortex-A35.
 
+More information can be found on `STM32MP2 Series`_ page.
+
 For TF-A common configuration of STM32 MPUs, please check
 :ref:`STM32 MPUs` page.
 
@@ -19,11 +21,13 @@
 
 Each line comes with a security option (cryptography & secure boot) and a Cortex-A frequency option:
 
-- A      Basic + Cortex-A35 @ 1GHz
-- C      Secure Boot + HW Crypto + Cortex-A35 @ 1GHz
+- A      Basic + Cortex-A35 @ 1.2GHz
+- C      Secure Boot + HW Crypto + Cortex-A35 @ 1.2GHz
 - D      Basic + Cortex-A35 @ 1.5GHz
 - F      Secure Boot + HW Crypto + Cortex-A35 @ 1.5GHz
 
+The `STM32MP2 part number codification`_ page gives more information about part numbers.
+
 Memory mapping
 --------------
 
@@ -130,4 +134,7 @@
         BL32_EXTRA1=<optee_directory>/tee-pager_v2.bin
         fip
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+.. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html
+.. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification
+
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index a7600ec..5643ea1 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1518,6 +1518,40 @@
 - The function must not clobber x1, x2 and x3. It's also not safe to rely on
   stack. Otherwise obey AAPCS.
 
+Struct: plat_try_images_ops [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This optional structure holds platform hooks for alternative images load.
+It has to be defined in platform code and registered by calling
+plat_setup_try_img_ops() function, passing it the address of the
+plat_try_images_ops struct.
+
+Function : plat_setup_try_img_ops [optional]
+............................................
+
+::
+
+    Argument : const struct plat_try_images_ops *
+    Return   : void
+
+This optional function is called to register platform try images ops, given
+as argument.
+
+Function : plat_try_images_ops.next_instance [optional]
+.......................................................
+
+::
+
+    Argument : unsigned int image_id
+    Return   : int
+
+This optional function tries to load images from alternative places.
+In case PSA FWU is not used, it can be any instance or media. If PSA FWU is
+used, it is mandatory that the backup image is on the same media.
+This is required for MTD devices like NAND.
+The argument is the ID of the image for which we are looking for an alternative
+place. It returns 0 in case of success and a negative errno value otherwise.
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
@@ -1607,9 +1641,6 @@
 for performing any remaining platform-specific setup that can occur after the
 MMU and data cache have been enabled.
 
-if support for multiple boot sources is required, it initializes the boot
-sequence used by plat_try_next_boot_source().
-
 In Arm standard platforms, this function initializes the storage abstraction
 layer used to load the next bootloader image.
 
@@ -1892,25 +1923,7 @@
 
 This optional function performs any BL2 platform initialization
 required before image loading, that is not done later in
-bl2_platform_setup(). Specifically, if support for multiple
-boot sources is required, it initializes the boot sequence used by
-plat_try_next_boot_source().
-
-Function : plat_try_next_boot_source() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : int
-
-This optional function passes to the next boot source in the redundancy
-sequence.
-
-This function moves the current boot redundancy source to the next
-element in the boot sequence. If there are no more boot sources then it
-must return 0, otherwise it must return 1. The default implementation
-of this always returns 0.
+bl2_platform_setup().
 
 Boot Loader Stage 2 (BL2) at EL3
 --------------------------------
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index 33b3533..11bec7e 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -4,8 +4,8 @@
 Getting Started
 ===============
 
--  Make sure you have a Github account and you are logged on both
-   `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_.
+-  Make sure you have a Github account and you are logged on to
+   `review.trustedfirmware.org`_.
 
    Also make sure that you have registered your full name and email address in
    your `review.trustedfirmware.org`_ profile. Otherwise, the Gerrit server
@@ -334,7 +334,6 @@
 
 *Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
-.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
 .. _review.trustedfirmware.org: https://review.trustedfirmware.org
 .. _Git guidelines: http://git-scm.com/book/ch5-2.html
 .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
diff --git a/docs/resources/diagrams/secure_sw_stack_sp.png b/docs/resources/diagrams/secure_sw_stack_sp.png
index 5cb2ca7..dc18cb4 100644
--- a/docs/resources/diagrams/secure_sw_stack_sp.png
+++ b/docs/resources/diagrams/secure_sw_stack_sp.png
Binary files differ
diff --git a/docs/resources/diagrams/secure_sw_stack_tos.png b/docs/resources/diagrams/secure_sw_stack_tos.png
index 1f2d555..2b42019 100644
--- a/docs/resources/diagrams/secure_sw_stack_tos.png
+++ b/docs/resources/diagrams/secure_sw_stack_tos.png
Binary files differ
diff --git a/docs/tools/index.rst b/docs/tools/index.rst
index 2dee2c0..91651bf 100644
--- a/docs/tools/index.rst
+++ b/docs/tools/index.rst
@@ -6,7 +6,8 @@
    :caption: Contents
 
    memory-layout-tool
+   transfer-list-compiler
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
diff --git a/docs/tools/transfer-list-compiler.rst b/docs/tools/transfer-list-compiler.rst
new file mode 100644
index 0000000..fa660dc
--- /dev/null
+++ b/docs/tools/transfer-list-compiler.rst
@@ -0,0 +1,311 @@
+Transfer List Compiler
+======================
+
+The Transfer List Compiler (tlc) is a host tool used by TF-A to generate transfer
+lists compliant with the v0.9 of the `Firmware Handoff specification`_. It enables
+developers to statically generate transfer list blobs containing any number of
+transfer entries.
+
+Getting Started
+~~~~~~~~~~~~~~~
+
+``tlc`` is installed by default with TF-A's poetry environment. All of it's
+dependencies are listed in `tools/tlc/pyproject.toml`_.
+
+To install ``tlc`` seperately, run the following command:
+
+.. code::
+
+    make -C tools/tlc install
+
+Creating a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To create an empty TL, you can use the ``create`` command.
+
+.. code::
+
+    tlc create tl.bin
+
+This commands generates a binary blob representing an empty TL, shown in the
+hexdump below.
+
+.. code::
+
+    $ hexdump tl.bin | head
+    0000000 b10b 4a0f 01a6 0318 0018 0000 1000 0000
+    0000010 0001 0000 0000 0000
+
+A common use-case this tool supports is the addition of TE's via the option
+``--entry``. This takes as input the tag ID and path to a binary blob to be
+included in the transfer list. The snippet below shows how to include an FDT in
+the TL.
+
+.. code::
+
+    tlc create --entry 1 fdt.dtb tl.bin
+
+Alternatively, addition of a device tree is supported through the option
+``--fdt``. This has the same effect as passing the device tree and it's tag ID
+through the ``--entry`` option.
+
+.. code::
+
+    tlc create --fdt fdt.dtb tl.bin
+
+.. note::
+
+    ``tlc`` makes no effort to verify the contents of a binary blob against the
+    provided tag ID. It only checks that the tags provided as input are within
+    range and that there is sufficient memory to include their TE's.
+
+You can also create a TL from a YAML config file.
+
+.. code ::
+
+    tlc create --from-yaml config.yaml tl.bin
+
+Printing the contents of a TL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Support is provided for dumping the contents of a TL via the ``info`` command.
+This prints the header of the TL and all included TE's.
+
+.. code::
+
+    $ tlc info tl.bin
+    signature  0x4a0fb10b
+    checksum   0xe1
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x2a6f
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x1
+    data_size  0x2a47
+    hdr_size   0x8
+    offset     0x18
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x2a68
+
+The example above shows the dump produced by ``tlc`` for a 20Kb TL containing a
+device tree (tag_id=1) and a NULL entry (tag_id=0).
+
+Modifying the contents of an existing TL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`tlc` supports removal of one or more entries from a TL through the ``remove``
+command. It takes as argument the filename, and one or more tag ID's, passed
+through the ``--tags`` option.  It produces a valid TL blob without those
+entries.
+
+
+For example, using the same blob as in the section above, we can remove the FDT
+TE with the command.
+
+.. code::
+
+    $ tlc remove --tags 1 tl.bin
+
+Using the ``info`` command, shows the the TE has been remove:
+
+.. code::
+
+    $ tlc info tl.bin
+
+    signature  0x4a0fb10b
+    checksum   0x38
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x20
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x18
+
+Note that more than one entry can be removed at a time. The ``--tags`` option
+accepts multiple tag ID's.
+
+Conversely, TE's can be added to an existing TL. This is achieved through the
+`add` command.
+
+.. code::
+
+    $ tlc add --entry 1 fdt.dtb tl.bin
+
+
+The result of this modification is shown below:
+
+.. code::
+
+    $ tlc info tl.bin
+
+    signature  0x4a0fb10b
+    checksum   0xe1
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x2a6f
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x18
+    ----
+    id         0x1
+    data_size  0x2a47
+    hdr_size   0x8
+    offset     0x20
+
+Unpacking a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Given a transfer list, ``tlc`` also provides a mechanism for extracting TE data.
+Running the command ``unpack``, yields binary files containing data from all the TE's.
+
+.. code::
+
+    $ tlc create --size 20000 --fdt build/fvp/debug/fdts/fvp-base-gicv3-psci.dtb tl.bin
+    $ tlc unpack tl.bin
+    $ file te_1.bin
+    te_1.bin: Device Tree Blob version 17, size=10823, boot CPU=0, string block size=851, DT structure block size=9900
+
+Validate a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+``tlc validate`` provides a quick and simple mechanism for checking wether the TL
+is compliant with version of the specification supported by the tool. It
+performs the following checks:
+
+#. Validates the signature.
+#. Ensures that the specified version is greater than or equal to the tool’s current version.
+#. Verifies alignment criteria for all TE’s.
+
+YAML Config File Format
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Example YAML config file:
+
+.. code::
+
+    execution_state: aarch32
+    has_checksum: true
+    max_size: 4096
+    entries:
+            - tag_id: 258  # entry point info
+              ep_info:
+                      args:
+                              - 67112968
+                              - 67112960
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                      h:
+                              attr: 8
+                              type: 1
+                              version: 2
+                      pc: 67239936
+                      spsr: 467
+            - tag_id: 3  # memory layout
+              addr: 8
+              size: 8
+            - tag_id: 1,  # fdt
+              blob_file_path: "fdt.bin",
+
+`max_size` defaults to `0x1000`, `execution_state` defaults to `aarch64`, and `has_checksum`
+defaults to `true`.
+
+The fields of the YAML file should match the fields in the specification for the transfer list. You
+don't need to give the hdr_size or data_size fields. For example, a memory layout entry would have
+an entry like:
+
+.. code::
+
+    tag_id: 3
+    addr: 8
+    size: 8
+
+You can input blob files by giving paths to the current working directory. You can do this for any
+TE type. For example, an FDT layout would have an entry like:
+
+.. code::
+
+    tag_id: 1,
+    blob_file_path: "fdt.bin",
+
+You can input C-types by giving its fields. For example, an entry point
+info entry would have an entry like:
+
+.. code::
+
+    tag_id: 258
+    ep_info:
+            args:
+                    - 67112968
+                    - 67112960
+                    - 0
+                    - 0
+            h:
+                    attr: 8
+                    type: 1
+                    version: 2
+            lr_svc: 0
+            pc: 67239936
+            spsr: 467
+
+You can give the name of the tag instead of the tag id number. The valid tag names are in the
+`transfer_entry_formats` dict in `tools/tlc/tlc/tl.py`_. Some examples are:
+
+* empty
+* fdt
+* hob_block
+* hob_list
+
+You can input the attr field of entry_point_info as a string of flag
+names separated by `|`. The names are taken from ep_info_exp.h in TF-A.
+For example:
+
+.. code::
+
+    has_checksum: true
+    max_size: 4096
+    entries:
+    - tag_id: 0x102
+      ep_info:
+        args:
+        - 67112976
+        - 67112960
+        - 0
+        - 0
+        - 0
+        - 0
+        - 0
+        - 0
+        h:
+          attr: EP_NON_SECURE | EP_ST_ENABLE
+          type: 1
+          version: 2
+        pc: 67239936
+        spsr: 965
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/
+.. _tools/tlc/pyproject.toml: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/pyproject.toml
+.. _tools/tlc/tlc/tl.py: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/tlc/tl.py
diff --git a/drivers/arm/mhu/mhu_wrapper_v3_x.c b/drivers/arm/mhu/mhu_wrapper_v3_x.c
index b3d51e3..3efd701 100644
--- a/drivers/arm/mhu/mhu_wrapper_v3_x.c
+++ b/drivers/arm/mhu/mhu_wrapper_v3_x.c
@@ -445,7 +445,7 @@
 
 size_t mhu_get_max_message_size(void)
 {
-	enum mhu_v3_x_error_t err;
+	enum mhu_v3_x_error_t err __maybe_unused;
 	uint8_t num_channels;
 
 	err = mhu_v3_x_get_num_channel_implemented(&mhu_seh_dev,
diff --git a/drivers/arm/rse/rse_comms.mk b/drivers/arm/rse/rse_comms.mk
index a1abc6a..3b87fe2 100644
--- a/drivers/arm/rse/rse_comms.mk
+++ b/drivers/arm/rse/rse_comms.mk
@@ -31,4 +31,5 @@
 endif
 
 PLAT_INCLUDES		+=	-Idrivers/arm/rse		\
-				-Idrivers/arm/mhu
+				-Idrivers/arm/mhu		\
+				-Iinclude/lib/psa
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 99242e3..53f8adf 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -104,231 +104,6 @@
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 
-static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg,
-					   mbedtls_md_type_t md_alg,
-					   psa_ecc_family_t psa_ecc_family,
-					   psa_algorithm_t *psa_alg,
-					   psa_key_type_t *psa_key_type)
-{
-	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
-
-	switch (pk_alg) {
-	case MBEDTLS_PK_RSASSA_PSS:
-		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
-		*psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
-		break;
-	case MBEDTLS_PK_ECDSA:
-		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
-		*psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family);
-		break;
-	default:
-		*psa_alg = PSA_ALG_NONE;
-		*psa_key_type = PSA_KEY_TYPE_NONE;
-		break;
-	}
-}
-
-
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
-TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-
-/*
- * This is a helper function to detect padding byte (if the MSB bit of the
- * first data byte is set to 1, for example 0x80) and on detection, ignore the
- * padded byte(0x00) and increase the buffer pointer beyond padded byte and
- * decrease the length of the buffer by 1.
- *
- * On Success returns 0, error otherwise.
- **/
-static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start,
-					       size_t *buf_len)
-{
-	unsigned char *local_buf = *buf_start;
-
-	/* Check for negative number */
-	if ((local_buf[0] & 0x80U) != 0U) {
-		return -1;
-	}
-
-	if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) &&
-	    (*buf_len > 1U)) {
-		*buf_start = &local_buf[1];
-		(*buf_len)--;
-	}
-
-	return 0;
-}
-
-/*
- * This is a helper function that gets a pointer to the encoded ECDSA publicKey
- * and its length (as per RFC5280) and returns corresponding decoded publicKey
- * and its length. As well, it retrieves the family of ECC key in the PSA
- * format.
- *
- * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
- * otherwise success(0).
- **/
-static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start,
-				      unsigned int *pk_len,
-				      psa_ecc_family_t *psa_ecc_family)
-{
-	mbedtls_asn1_buf alg_oid, alg_params;
-	mbedtls_ecp_group_id grp_id;
-	int rc;
-	unsigned char *pk_end;
-	size_t len;
-	size_t curve_bits;
-	unsigned char *pk_ptr = *pk_start;
-
-	pk_end = pk_ptr + *pk_len;
-	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	pk_end = pk_ptr + len;
-	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	if (alg_params.tag == MBEDTLS_ASN1_OID) {
-		if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) {
-			return CRYPTO_ERR_SIGNATURE;
-		}
-		*psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id,
-							   &curve_bits);
-	} else {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
-		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
-	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	*pk_start = pk_ptr;
-	*pk_len = len;
-
-	return rc;
-}
-
-/*
- * Ecdsa-Sig-Value  ::=  SEQUENCE  {
- *   r     INTEGER,
- *   s     INTEGER
- * }
- *
- * This helper function that gets a pointer to the encoded ECDSA signature and
- * its length (as per RFC5280) and returns corresponding decoded signature
- * (R_S pair) and its size.
- *
- * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
- * otherwise success(0).
- **/
-static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr,
-					 size_t *sig_len,
-					 unsigned char *r_s_pair)
-{
-	int rc;
-	unsigned char *sig_end;
-	size_t len, r_len, s_len;
-
-	sig_end = sig_ptr + *sig_len;
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	sig_end = sig_ptr + len;
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len,
-				  MBEDTLS_ASN1_INTEGER);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	(void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len);
-
-	sig_ptr = sig_ptr + r_len;
-	sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN +
-		  SIZE_OF_ASN1_TAG));
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len,
-				  MBEDTLS_ASN1_INTEGER);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	(void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len);
-
-	*sig_len = s_len + r_len;
-
-	return 0;
-}
-#endif /*
-	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
-	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-	**/
-
-/*
- * This is a helper function that adjusts the start of the pk_start to point to
- * the subjectPublicKey bytes within the SubjectPublicKeyInfo block.
- *
- *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
- *       algorithm            AlgorithmIdentifier,
- *       subjectPublicKey     BIT STRING }
- *
- * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
- * otherwise success(0).
- **/
-static int pk_bytes_from_subpubkey(unsigned char **pk_start,
-				   unsigned int *pk_len)
-{
-	mbedtls_asn1_buf alg_oid, alg_params;
-	int rc;
-	unsigned char *pk_end;
-	size_t len;
-	unsigned char *pk_ptr = *pk_start;
-
-	pk_end = pk_ptr + *pk_len;
-	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	pk_end = pk_ptr + len;
-	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
-		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
-	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	*pk_start = pk_ptr;
-	*pk_len = len;
-
-	return rc;
-}
-
 /*
  * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
  * advised that it's better to copy out the declaration than it would be to
@@ -339,6 +114,73 @@
 			     mbedtls_md_type_t *md_alg,
 			     mbedtls_pk_type_t *pk_alg,
 			     void **sig_opts);
+
+/*
+ * This is a helper function which parses a SignatureAlgorithm OID.
+ * It extracts the pk algorithm and constructs a psa_algorithm_t object
+ * to be used by PSA calls.
+ */
+static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
+			     mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
+{
+	int rc;
+	mbedtls_md_type_t md_alg;
+	void *sig_opts = NULL;
+	mbedtls_asn1_buf sig_alg_oid, params;
+	unsigned char *p = (unsigned char *) sig_alg;
+	unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
+
+	rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
+	}
+
+	rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
+	}
+
+	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
+
+	switch (*pk_alg) {
+	case MBEDTLS_PK_RSASSA_PSS:
+		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
+		rc = CRYPTO_SUCCESS;
+		break;
+	case MBEDTLS_PK_ECDSA:
+		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
+		rc = CRYPTO_SUCCESS;
+		break;
+	default:
+		*psa_alg = PSA_ALG_NONE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		break;
+	}
+
+end:
+	mbedtls_free(sig_opts);
+	return rc;
+}
+
+/*
+ * Helper functions for mbedtls PK contexts.
+ */
+static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
+{
+	mbedtls_pk_init(pk);
+	*pk_initialized = true;
+}
+
+static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
+{
+	if (*pk_initialized) {
+		mbedtls_pk_free(pk);
+		*pk_initialized = false;
+	}
+}
+
 /*
  * Verify a signature.
  *
@@ -350,139 +192,99 @@
 			    void *sig_alg, unsigned int sig_alg_len,
 			    void *pk_ptr, unsigned int pk_len)
 {
-	mbedtls_asn1_buf sig_oid, sig_params;
-	mbedtls_asn1_buf signature;
-	mbedtls_md_type_t md_alg;
-	mbedtls_pk_type_t pk_alg;
-	int rc;
-	void *sig_opts = NULL;
 	unsigned char *p, *end;
+	mbedtls_pk_context pk;
+	bool pk_initialized = false;
+	int rc = CRYPTO_ERR_SIGNATURE;
+	psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
+	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
+	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};
 	unsigned char *local_sig_ptr;
 	size_t local_sig_len;
-	psa_ecc_family_t psa_ecc_family = 0U;
-	__unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
 
-	/* construct PSA key algo and type */
-	psa_status_t status = PSA_SUCCESS;
-	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
-	psa_key_id_t psa_key_id = PSA_KEY_ID_NULL;
-	psa_key_type_t psa_key_type;
-	psa_algorithm_t psa_alg;
+	/* Load the key into the PSA key store. */
+	initialize_pk_context(&pk, &pk_initialized);
 
-	/* Get pointers to signature OID and parameters */
-	p = (unsigned char *)sig_alg;
-	end = (unsigned char *)(p + sig_alg_len);
-	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
+	p = (unsigned char *) pk_ptr;
+	end = p + pk_len;
+	rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	/* Get the actual signature algorithm (MD + PK) */
-	rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	/* Get the signature (bitstring) */
-	p = (unsigned char *)sig_ptr;
-	end = (unsigned char *)(p + sig_len);
-	signature.tag = *p;
-	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
-	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end2;
 	}
 
+	rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
+	}
+
+	rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
+	if (rc != CRYPTO_SUCCESS) {
+		goto end2;
+	}
+	psa_set_key_algorithm(&psa_key_attr, psa_alg);
+
+	rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
+	}
+
+	/* Optimize mbedtls heap usage by freeing the pk context now.  */
+	cleanup_pk_context(&pk, &pk_initialized);
+
+	/* Extract the signature from sig_ptr. */
+	p = (unsigned char *) sig_ptr;
+	end = p + sig_len;
+	rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end1;
+	}
 	local_sig_ptr = p;
-	local_sig_len = signature.len;
 
 #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
 TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
 	if (pk_alg == MBEDTLS_PK_ECDSA) {
-		rc = get_ecdsa_signature_from_asn1(local_sig_ptr,
-						   &local_sig_len,
-						   reformatted_sig);
-		if (rc != 0) {
-			goto end2;
-		}
+		/* Convert the DER ASN.1 signature to raw format. */
+		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,
+					      &local_sig_len);
+		if (rc != 0) {
+			rc = CRYPTO_ERR_SIGNATURE;
+			goto end1;
+		}
 		local_sig_ptr = reformatted_sig;
-
-		rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr,
-						&pk_len,
-						&psa_ecc_family);
-		if (rc != 0) {
-			goto end2;
-		}
 	}
 #endif /*
 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
 	**/
 
-	/* Convert this pk_alg and md_alg to PSA key type and key algorithm */
-	construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family,
-				       &psa_alg, &psa_key_type);
-
-
-	if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) {
-		rc = CRYPTO_ERR_SIGNATURE;
-		goto end2;
-	}
-
-	/* filled-in key_attributes */
-	psa_set_key_algorithm(&psa_key_attr, psa_alg);
-	psa_set_key_type(&psa_key_attr, psa_key_type);
-	psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
-
-	/*
-	 * Note: In the implementation of the psa_import_key function in
-	 * version 3.6.0, the function expects the starting pointer of the
-	 * subject public key instead of the starting point of
-	 * SubjectPublicKeyInfo.
-	 * This is only needed while dealing with RSASSA_PSS (RSA Signature
-	 * scheme with Appendix based on Probabilistic Signature Scheme)
-	 * algorithm.
-	 */
-	if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
-		rc = pk_bytes_from_subpubkey((unsigned char **) &pk_ptr, &pk_len);
-		goto end2;
-	}
-
-	/* Get the key_id using import API */
-	status = psa_import_key(&psa_key_attr,
-				pk_ptr,
-				(size_t)pk_len,
-				&psa_key_id);
-
-	if (status != PSA_SUCCESS) {
-		rc = CRYPTO_ERR_SIGNATURE;
-		goto end2;
-	}
-
-	/*
-	 * Hash calculation and Signature verification of the given data payload
-	 * is wrapped under the psa_verify_message function.
-	 */
-	status = psa_verify_message(psa_key_id, psa_alg,
+	/* Verify the signature. */
+	psa_status = psa_verify_message(psa_key_id, psa_alg,
 				    data_ptr, data_len,
 				    local_sig_ptr, local_sig_len);
-
-	if (status != PSA_SUCCESS) {
+	if (psa_status == PSA_SUCCESS) {
+		/* The signature has been successfully verified. */
+		rc = CRYPTO_SUCCESS;
+	} else {
 		rc = CRYPTO_ERR_SIGNATURE;
-		goto end1;
 	}
 
-	/* Signature verification success */
-	rc = CRYPTO_SUCCESS;
-
 end1:
-	/*
-	 * Destroy the key if it is created successfully
-	 */
+	/* Destroy the key from the PSA subsystem. */
 	psa_destroy_key(psa_key_id);
 end2:
-	mbedtls_free(sig_opts);
+	/* Free the pk context, if it is initialized. */
+	cleanup_pk_context(&pk, &pk_initialized);
+
 	return rc;
 }
 
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
index 21942b4..8bab6e8 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -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
  */
@@ -173,7 +173,6 @@
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
 	[BL2_IMAGE_ID]				=	&bl2_image,
-	[HW_CONFIG_ID]				=	&hw_config,
 	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
 	[FW_CONFIG_ID]				=	&fw_config,
 	[FWU_CERT_ID]				=	&fwu_cert,
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index ce2aa7e..8dccaec 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -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
  */
@@ -84,6 +84,22 @@
 		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
 #endif /* SPD_spmd */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
+
 /*
  * Trusted key certificate
  */
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
index 8c37248..619b241 100644
--- a/drivers/auth/tbbr/tbbr_cot_common.c
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -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
  */
@@ -52,7 +52,7 @@
 	AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
 auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
 
 /* trusted_boot_fw_cert */
@@ -109,19 +109,3 @@
 		}
 	}
 };
-
-/* HW Config */
-const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 4cbc0f7..3e87efc 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -34,6 +34,20 @@
 	return ops->get_rate(id);
 }
 
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate)
+{
+	unsigned long lrate;
+
+	assert((ops != NULL) && (ops->set_rate != NULL));
+
+	if (orate != NULL) {
+		return ops->set_rate(id, rate, orate);
+	}
+
+	/* In case the caller is not interested in the output rate */
+	return ops->set_rate(id, rate, &lrate);
+}
+
 int clk_get_parent(unsigned long id)
 {
 	assert((ops != NULL) && (ops->get_parent != NULL));
@@ -41,6 +55,13 @@
 	return ops->get_parent(id);
 }
 
+int clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	assert((ops != NULL) && (ops->set_parent != NULL));
+
+	return ops->set_parent(id, parent_id);
+}
+
 bool clk_is_enabled(unsigned long id)
 {
 	assert((ops != NULL) && (ops->is_enabled != NULL));
diff --git a/drivers/measured_boot/rse/dice_prot_env.c b/drivers/measured_boot/rse/dice_prot_env.c
index 8e9185a..dad30b2 100644
--- a/drivers/measured_boot/rse/dice_prot_env.c
+++ b/drivers/measured_boot/rse/dice_prot_env.c
@@ -115,7 +115,7 @@
 				 metadata->allow_new_context_to_derive,
 				 metadata->create_certificate,
 				 &dice_inputs,
-				 0, /* target_locality */
+				 metadata->target_locality,
 				 false, /* return_certificate */
 				 true, /* allow_new_context_to_export */
 				 false, /* export_cdi */
@@ -131,7 +131,8 @@
 			 */
 			VERBOSE("Share new_context_handle with child: 0x%x\n",
 				new_context_handle);
-			plat_dpe_share_context_handle(&new_context_handle);
+			plat_dpe_share_context_handle(&new_context_handle,
+						      &new_parent_context_handle);
 		}
 	} else {
 		ERROR("dpe_derive_context failed: %d\n", ret);
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
index 1af51f8..12e22e9 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
+++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
@@ -26,8 +26,8 @@
 # CST_BL31
 define CST_BL31_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL31_INPUT_FILE}
 endef
 
@@ -36,8 +36,8 @@
 # CST_BL32
 define CST_BL32_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL32_INPUT_FILE}
 endef
 
@@ -46,8 +46,8 @@
 # CST_BL33
 define CST_BL33_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL33_INPUT_FILE}
 endef
 
@@ -56,8 +56,8 @@
 # CST_SCP_BL2
 define CST_SCP_BL2_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${FUSE_INPUT_FILE}
 endef
 
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
new file mode 100644
index 0000000..7ae9624
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_CLK_REGS_H
+#define S32CC_CLK_REGS_H
+
+#include <lib/utils_def.h>
+
+#define FXOSC_BASE_ADDR			(0x40050000UL)
+
+/* FXOSC */
+#define FXOSC_CTRL(FXOSC)		((FXOSC) + 0x0UL)
+#define FXOSC_CTRL_OSC_BYP		BIT_32(31U)
+#define FXOSC_CTRL_COMP_EN		BIT_32(24U)
+#define FXOSC_CTRL_EOCV_OFFSET		16U
+#define FXOSC_CTRL_EOCV_MASK		GENMASK_32(23U, FXOSC_CTRL_EOCV_OFFSET)
+#define FXOSC_CTRL_EOCV(VAL)		(FXOSC_CTRL_EOCV_MASK & \
+					 ((uint32_t)(VAL) << FXOSC_CTRL_EOCV_OFFSET))
+#define FXOSC_CTRL_GM_SEL_OFFSET	4U
+#define FXOSC_CTRL_GM_SEL_MASK		GENMASK_32(7U, FXOSC_CTRL_GM_SEL_OFFSET)
+#define FXOSC_CTRL_GM_SEL(VAL)		(FXOSC_CTRL_GM_SEL_MASK & \
+					 ((uint32_t)(VAL) << FXOSC_CTRL_GM_SEL_OFFSET))
+#define FXOSC_CTRL_OSCON		BIT_32(0U)
+
+#define FXOSC_STAT(FXOSC)		((FXOSC) + 0x4UL)
+#define FXOSC_STAT_OSC_STAT		BIT_32(31U)
+
+#endif /* S32CC_CLK_REGS_H */
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
new file mode 100644
index 0000000..7a65ea6
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -0,0 +1,20 @@
+#
+# Copyright 2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		+= \
+	-I${PLAT_DRIVERS_INCLUDE_PATH}/clk/s32cc \
+	-I${PLAT_DRIVERS_PATH}/clk/s32cc/include \
+
+CLK_SOURCES		:= \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_modules.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_utils.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_early_clks.c \
+	drivers/clk/clk.c \
+
+ifeq (${BL_COMM_CLK_NEEDED},yes)
+BL2_SOURCES		+= ${CLK_SOURCES}
+endif
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
new file mode 100644
index 0000000..f35a469
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <s32cc-clk-regs.h>
+
+#include <common/debug.h>
+#include <drivers/clk.h>
+#include <lib/mmio.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-utils.h>
+
+#define MAX_STACK_DEPTH		(15U)
+
+struct s32cc_clk_drv {
+	uintptr_t fxosc_base;
+};
+
+static int update_stack_depth(unsigned int *depth)
+{
+	if (*depth == 0U) {
+		return -ENOMEM;
+	}
+
+	(*depth)--;
+	return 0;
+}
+
+static struct s32cc_clk_drv *get_drv(void)
+{
+	static struct s32cc_clk_drv driver = {
+		.fxosc_base = FXOSC_BASE_ADDR,
+	};
+
+	return &driver;
+}
+
+static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth);
+
+static int enable_clk_module(const struct s32cc_clk_obj *module,
+			     const struct s32cc_clk_drv *drv,
+			     unsigned int *depth)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	if (clk->module != NULL) {
+		return enable_module(clk->module, depth);
+	}
+
+	if (clk->pclock != NULL) {
+		return enable_clk_module(&clk->pclock->desc, drv, depth);
+	}
+
+	return -EINVAL;
+}
+
+static void enable_fxosc(const struct s32cc_clk_drv *drv)
+{
+	uintptr_t fxosc_base = drv->fxosc_base;
+	uint32_t ctrl;
+
+	ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base));
+	if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) {
+		return;
+	}
+
+	ctrl = FXOSC_CTRL_COMP_EN;
+	ctrl &= ~FXOSC_CTRL_OSC_BYP;
+	ctrl |= FXOSC_CTRL_EOCV(0x1);
+	ctrl |= FXOSC_CTRL_GM_SEL(0x7);
+	mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl);
+
+	/* Switch ON the crystal oscillator. */
+	mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON);
+
+	/* Wait until the clock is stable. */
+	while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) {
+	}
+}
+
+static int enable_osc(const struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int *depth)
+{
+	const struct s32cc_osc *osc = s32cc_obj2osc(module);
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	switch (osc->source) {
+	case S32CC_FXOSC:
+		enable_fxosc(drv);
+		break;
+	/* FIRC and SIRC oscillators are enabled by default */
+	case S32CC_FIRC:
+		break;
+	case S32CC_SIRC:
+		break;
+	default:
+		ERROR("Invalid oscillator %d\n", osc->source);
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth)
+{
+	const struct s32cc_clk_drv *drv = get_drv();
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (drv == NULL) {
+		return -EINVAL;
+	}
+
+	switch (module->type) {
+	case s32cc_osc_t:
+		ret = enable_osc(module, drv, depth);
+		break;
+	case s32cc_clk_t:
+		ret = enable_clk_module(module, drv, depth);
+		break;
+	case s32cc_clkmux_t:
+		ret = -ENOTSUP;
+		break;
+	case s32cc_shared_clkmux_t:
+		ret = -ENOTSUP;
+		break;
+	case s32cc_pll_t:
+		ret = -ENOTSUP;
+		break;
+	case s32cc_pll_out_div_t:
+	case s32cc_fixed_div_t:
+		ret = -ENOTSUP;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_enable(unsigned long id)
+{
+	unsigned int depth = MAX_STACK_DEPTH;
+	const struct s32cc_clk *clk;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	return enable_module(&clk->desc, &depth);
+}
+
+static void s32cc_clk_disable(unsigned long id)
+{
+}
+
+static bool s32cc_clk_is_enabled(unsigned long id)
+{
+	return false;
+}
+
+static unsigned long s32cc_clk_get_rate(unsigned long id)
+{
+	return 0;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth);
+
+static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_osc *osc = s32cc_obj2osc(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((osc->freq != 0UL) && (rate != osc->freq)) {
+		ERROR("Already initialized oscillator. freq = %lu\n",
+		      osc->freq);
+		return -EINVAL;
+	}
+
+	osc->freq = rate;
+	*orate = osc->freq;
+
+	return 0;
+}
+
+static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) &&
+	    ((rate < clk->min_freq) || (rate > clk->max_freq))) {
+		ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n",
+		      rate, clk->min_freq, clk->max_freq);
+		return -EINVAL;
+	}
+
+	if (clk->module != NULL) {
+		return set_module_rate(clk->module, rate, orate, depth);
+	}
+
+	if (clk->pclock != NULL) {
+		return set_clk_freq(&clk->pclock->desc, rate, orate, depth);
+	}
+
+	return -EINVAL;
+}
+
+static int set_pll_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_pll *pll = s32cc_obj2pll(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((pll->vco_freq != 0UL) && (pll->vco_freq != rate)) {
+		ERROR("PLL frequency was already set\n");
+		return -EINVAL;
+	}
+
+	pll->vco_freq = rate;
+	*orate = pll->vco_freq;
+
+	return 0;
+}
+
+static int set_pll_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			    unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+	const struct s32cc_pll *pll;
+	unsigned long prate, dc;
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (pdiv->parent == NULL) {
+		ERROR("Failed to identify PLL divider's parent\n");
+		return -EINVAL;
+	}
+
+	pll = s32cc_obj2pll(pdiv->parent);
+	if (pll == NULL) {
+		ERROR("The parent of the PLL DIV is invalid\n");
+		return -EINVAL;
+	}
+
+	prate = pll->vco_freq;
+
+	/**
+	 * The PLL is not initialized yet, so let's take a risk
+	 * and accept the proposed rate.
+	 */
+	if (prate == 0UL) {
+		pdiv->freq = rate;
+		*orate = rate;
+		return 0;
+	}
+
+	/* Decline in case the rate cannot fit PLL's requirements. */
+	dc = prate / rate;
+	if ((prate / dc) != rate) {
+		return -EINVAL;
+	}
+
+	pdiv->freq = rate;
+	*orate = pdiv->freq;
+
+	return 0;
+}
+
+static int set_fixed_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			      unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_fixed_div *fdiv = s32cc_obj2fixeddiv(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (fdiv->parent == NULL) {
+		ERROR("The divider doesn't have a valid parent\b");
+		return -EINVAL;
+	}
+
+	ret = set_module_rate(fdiv->parent, rate * fdiv->rate_div, orate, depth);
+
+	/* Update the output rate based on the parent's rate */
+	*orate /= fdiv->rate_div;
+
+	return ret;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth)
+{
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	switch (module->type) {
+	case s32cc_clk_t:
+		ret = set_clk_freq(module, rate, orate, depth);
+		break;
+	case s32cc_osc_t:
+		ret = set_osc_freq(module, rate, orate, depth);
+		break;
+	case s32cc_pll_t:
+		ret = set_pll_freq(module, rate, orate, depth);
+		break;
+	case s32cc_pll_out_div_t:
+		ret = set_pll_div_freq(module, rate, orate, depth);
+		break;
+	case s32cc_fixed_div_t:
+		ret = set_fixed_div_freq(module, rate, orate, depth);
+		break;
+	case s32cc_clkmux_t:
+	case s32cc_shared_clkmux_t:
+		ret = -ENOTSUP;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_set_rate(unsigned long id, unsigned long rate,
+			      unsigned long *orate)
+{
+	unsigned int depth = MAX_STACK_DEPTH;
+	const struct s32cc_clk *clk;
+	int ret;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	ret = set_module_rate(&clk->desc, rate, orate, &depth);
+	if (ret != 0) {
+		ERROR("Failed to set frequency (%lu MHz) for clock %lu\n",
+		      rate, id);
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_get_parent(unsigned long id)
+{
+	return -ENOTSUP;
+}
+
+static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	const struct s32cc_clk *parent;
+	const struct s32cc_clk *clk;
+	bool valid_source = false;
+	struct s32cc_clkmux *mux;
+	uint8_t i;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	parent = s32cc_get_arch_clk(parent_id);
+	if (parent == NULL) {
+		return -EINVAL;
+	}
+
+	if (!is_s32cc_clk_mux(clk)) {
+		ERROR("Clock %lu is not a mux\n", id);
+		return -EINVAL;
+	}
+
+	mux = s32cc_clk2mux(clk);
+	if (mux == NULL) {
+		ERROR("Failed to cast clock %lu to clock mux\n", id);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < mux->nclks; i++) {
+		if (mux->clkids[i] == parent_id) {
+			valid_source = true;
+			break;
+		}
+	}
+
+	if (!valid_source) {
+		ERROR("Clock %lu is not a valid clock for mux %lu\n",
+		      parent_id, id);
+		return -EINVAL;
+	}
+
+	mux->source_id = parent_id;
+
+	return 0;
+}
+
+void s32cc_clk_register_drv(void)
+{
+	static const struct clk_ops s32cc_clk_ops = {
+		.enable		= s32cc_clk_enable,
+		.disable	= s32cc_clk_disable,
+		.is_enabled	= s32cc_clk_is_enabled,
+		.get_rate	= s32cc_clk_get_rate,
+		.set_rate	= s32cc_clk_set_rate,
+		.get_parent	= s32cc_clk_get_parent,
+		.set_parent	= s32cc_clk_set_parent,
+	};
+
+	clk_register(&s32cc_clk_ops);
+}
+
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
new file mode 100644
index 0000000..039db2a
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-utils.h>
+
+#define S32CC_A53_MIN_FREQ	(48UL * MHZ)
+#define S32CC_A53_MAX_FREQ	(1000UL * MHZ)
+
+/* Oscillators */
+static struct s32cc_osc fxosc =
+	S32CC_OSC_INIT(S32CC_FXOSC);
+static struct s32cc_clk fxosc_clk =
+	S32CC_MODULE_CLK(fxosc);
+
+static struct s32cc_osc firc =
+	S32CC_OSC_INIT(S32CC_FIRC);
+static struct s32cc_clk firc_clk =
+	S32CC_MODULE_CLK(firc);
+
+static struct s32cc_osc sirc =
+	S32CC_OSC_INIT(S32CC_SIRC);
+static struct s32cc_clk sirc_clk =
+	S32CC_MODULE_CLK(sirc);
+
+/* ARM PLL */
+static struct s32cc_clkmux arm_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_ARM_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk arm_pll_mux_clk =
+	S32CC_MODULE_CLK(arm_pll_mux);
+static struct s32cc_pll armpll =
+	S32CC_PLL_INIT(arm_pll_mux_clk, S32CC_ARM_PLL, 2);
+static struct s32cc_clk arm_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(armpll, 1400 * MHZ, 2000 * MHZ);
+
+static struct s32cc_pll_out_div arm_pll_phi0_div =
+	S32CC_PLL_OUT_DIV_INIT(armpll, 0);
+static struct s32cc_clk arm_pll_phi0_clk =
+	S32CC_FREQ_MODULE_CLK(arm_pll_phi0_div, 0, GHZ);
+
+/* MC_CGM1 */
+static struct s32cc_clkmux cgm1_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM1, 0, 3,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_ARM_PLL_PHI0,
+				 S32CC_CLK_ARM_PLL_DFS2, 0, 0);
+static struct s32cc_clk cgm1_mux0_clk = S32CC_MODULE_CLK(cgm1_mux0);
+
+/* A53_CORE */
+static struct s32cc_clk a53_core_clk =
+	S32CC_FREQ_MODULE_CLK(cgm1_mux0_clk, S32CC_A53_MIN_FREQ,
+			      S32CC_A53_MAX_FREQ);
+/* A53_CORE_DIV2 */
+static struct s32cc_fixed_div a53_core_div2 =
+		S32CC_FIXED_DIV_INIT(cgm1_mux0_clk, 2);
+static struct s32cc_clk a53_core_div2_clk =
+	S32CC_FREQ_MODULE_CLK(a53_core_div2, S32CC_A53_MIN_FREQ / 2,
+			      S32CC_A53_MAX_FREQ / 2);
+/* A53_CORE_DIV10 */
+static struct s32cc_fixed_div a53_core_div10 =
+	S32CC_FIXED_DIV_INIT(cgm1_mux0_clk, 10);
+static struct s32cc_clk a53_core_div10_clk =
+	S32CC_FREQ_MODULE_CLK(a53_core_div10, S32CC_A53_MIN_FREQ / 10,
+			      S32CC_A53_MAX_FREQ / 10);
+
+static struct s32cc_clk *s32cc_hw_clk_list[5] = {
+	/* Oscillators */
+	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_FXOSC)] = &fxosc_clk,
+	/* ARM PLL */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk,
+};
+
+static struct s32cc_clk_array s32cc_hw_clocks = {
+	.type_mask = S32CC_CLK_TYPE(S32CC_CLK_FIRC),
+	.clks = &s32cc_hw_clk_list[0],
+	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
+};
+
+static struct s32cc_clk *s32cc_arch_clk_list[6] = {
+	/* ARM PLL */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk,
+	/* MC_CGM1 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM1_MUX0)] = &cgm1_mux0_clk,
+	/* A53 */
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE)] = &a53_core_clk,
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE_DIV2)] = &a53_core_div2_clk,
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE_DIV10)] = &a53_core_div10_clk,
+};
+
+static struct s32cc_clk_array s32cc_arch_clocks = {
+	.type_mask = S32CC_CLK_TYPE(S32CC_CLK_ARM_PLL_MUX),
+	.clks = &s32cc_arch_clk_list[0],
+	.n_clks = ARRAY_SIZE(s32cc_arch_clk_list),
+};
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id)
+{
+	static const struct s32cc_clk_array *clk_table[2] = {
+		&s32cc_hw_clocks,
+		&s32cc_arch_clocks,
+	};
+
+	return s32cc_get_clk_from_table(clk_table, ARRAY_SIZE(clk_table), id);
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_utils.c b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
new file mode 100644
index 0000000..14ab674
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+static struct s32cc_clk *s32cc_clk_get_from_array(const struct s32cc_clk_array *arr,
+						  unsigned long clk_id)
+{
+	unsigned long type, id;
+
+	type = S32CC_CLK_TYPE(clk_id);
+
+	if (type != arr->type_mask) {
+		return NULL;
+	}
+
+	id = S32CC_CLK_ID(clk_id);
+
+	if (id >= arr->n_clks) {
+		return NULL;
+	}
+
+	return arr->clks[id];
+}
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id)
+{
+	struct s32cc_clk *clk;
+	size_t i;
+
+	for (i = 0; i < size; i++) {
+		clk = s32cc_clk_get_from_array(clk_arr[i], clk_id);
+		if (clk != NULL) {
+			return clk;
+		}
+	}
+
+	return NULL;
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
new file mode 100644
index 0000000..ac1f7d0
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <drivers/clk.h>
+#include <s32cc-clk-drv.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+#define S32CC_FXOSC_FREQ	(40U * MHZ)
+#define S32CC_ARM_PLL_VCO_FREQ	(2U * GHZ)
+#define S32CC_ARM_PLL_PHI0_FREQ	(1U * GHZ)
+
+int s32cc_init_early_clks(void)
+{
+	int ret;
+
+	s32cc_clk_register_drv();
+
+	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/drivers/nxp/ddr/phy-gen2/ddrphy.mk b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
index ba5c774..a09a278 100644
--- a/drivers/nxp/ddr/phy-gen2/ddrphy.mk
+++ b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
@@ -12,9 +12,9 @@
 DDR_PHY_H  =
 
 $(DDR_PHY_C): $(DDR_PHY_H) $(COMMON_HDRS) src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 $(DDR_PHY_H): src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 #------------------------------------------------
diff --git a/drivers/nxp/drivers.mk b/drivers/nxp/drivers.mk
index d77e985..761571d 100644
--- a/drivers/nxp/drivers.mk
+++ b/drivers/nxp/drivers.mk
@@ -97,3 +97,7 @@
 ifeq (${IFC_NAND_NEEDED},yes)
 include ${PLAT_DRIVERS_PATH}/ifc/nand/ifc_nand.mk
 endif
+
+ifeq (${CLK_NEEDED},yes)
+include ${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk.mk
+endif
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 888a824..c4f7493 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -50,7 +50,7 @@
 {
 	size_t bytes_read;
 	int result;
-	mbr_entry_t *tmp;
+	mbr_entry_t tmp;
 
 	assert(mbr_entry != NULL);
 	/* MBR partition table is in LBA0. */
@@ -73,19 +73,19 @@
 		return -ENOENT;
 	}
 
-	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);
+	memcpy(&tmp, mbr_sector + MBR_PRIMARY_ENTRY_OFFSET, sizeof(tmp));
 
-	if (tmp->first_lba != 1) {
+	if (tmp.first_lba != 1) {
 		VERBOSE("MBR header may have an invalid first LBA\n");
 		return -EINVAL;
 	}
 
-	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
+	if ((tmp.sector_nums == 0) || (tmp.sector_nums == UINT32_MAX)) {
 		VERBOSE("MBR header entry has an invalid number of sectors\n");
 		return -EINVAL;
 	}
 
-	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
+	memcpy(mbr_entry, &tmp, sizeof(mbr_entry_t));
 	return 0;
 }
 
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index 9fe8c8c..6787d50 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 	return stm32_clock_data;
 }
 
-static void stm32mp1_clk_lock(struct spinlock *lock)
+static void _clk_lock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		/* Assume interrupts are masked */
@@ -36,21 +36,21 @@
 	}
 }
 
-static void stm32mp1_clk_unlock(struct spinlock *lock)
+static void _clk_unlock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		spin_unlock(lock);
 	}
 }
 
-void stm32mp1_clk_rcc_regs_lock(void)
+void clk_stm32_rcc_regs_lock(void)
 {
-	stm32mp1_clk_lock(&reg_lock);
+	_clk_lock(&reg_lock);
 }
 
-void stm32mp1_clk_rcc_regs_unlock(void)
+void clk_stm32_rcc_regs_unlock(void)
 {
-	stm32mp1_clk_unlock(&reg_lock);
+	_clk_unlock(&reg_lock);
 }
 
 #define TIMEOUT_US_1S	U(1000000)
@@ -224,6 +224,15 @@
 	return NULL;
 }
 
+static const struct stm32_clk_ops *_clk_get_ops(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+
+	assert(clk->ops != NO_OPS);
+
+	return priv->ops_array[clk->ops];
+}
+
 #define clk_div_mask(_width) GENMASK(((_width) - 1U), 0U)
 
 static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -377,7 +386,7 @@
 
 int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, clk_id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, clk_id);
 	const struct parent_cfg *parent;
 	uint16_t mux_id;
 	int sel;
@@ -394,8 +403,8 @@
 	mux_id &= MUX_PARENT_MASK;
 	parent = &priv->parents[mux_id];
 
-	if (clk->ops->get_parent != NULL) {
-		sel = clk->ops->get_parent(priv, clk_id);
+	if (ops->get_parent != NULL) {
+		sel = ops->get_parent(priv, clk_id);
 	} else {
 		sel = clk_mux_get_parent(priv, mux_id);
 	}
@@ -464,7 +473,7 @@
 
 unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 	int parent;
 
 	if ((unsigned int)id >= priv->num) {
@@ -476,14 +485,14 @@
 		return 0UL;
 	}
 
-	if (clk->ops->recalc_rate != NULL) {
+	if (ops->recalc_rate != NULL) {
 		unsigned long prate = 0UL;
 
 		if (parent != CLK_IS_ROOT) {
 			prate = _clk_stm32_get_rate(priv, parent);
 		}
 
-		return clk->ops->recalc_rate(priv, id, prate);
+		return ops->recalc_rate(priv, id, prate);
 	}
 
 	if (parent == CLK_IS_ROOT) {
@@ -520,10 +529,10 @@
 
 int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->enable != NULL) {
-		clk->ops->enable(priv, id);
+	if (ops->enable != NULL) {
+		ops->enable(priv, id);
 	}
 
 	return 0;
@@ -550,7 +559,7 @@
 
 	priv->gate_refcounts[id]++;
 
-	if (priv->gate_refcounts[id] == UINT_MAX) {
+	if (priv->gate_refcounts[id] == UINT8_MAX) {
 		ERROR("%s: %d max enable count !", __func__, id);
 		panic();
 	}
@@ -562,19 +571,19 @@
 {
 	int ret;
 
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 	ret = _clk_stm32_enable_core(priv, id);
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 
 	return ret;
 }
 
 void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->disable != NULL) {
-		clk->ops->disable(priv, id);
+	if (ops->disable != NULL) {
+		ops->disable(priv, id);
 	}
 }
 
@@ -610,19 +619,19 @@
 
 void _clk_stm32_disable(struct stm32_clk_priv *priv, int id)
 {
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 
 	_clk_stm32_disable_core(priv, id);
 
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 }
 
 bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->is_enabled != NULL) {
-		return clk->ops->is_enabled(priv, id);
+	if (ops->is_enabled != NULL) {
+		return ops->is_enabled(priv, id);
 	}
 
 	return priv->gate_refcounts[id];
@@ -957,6 +966,10 @@
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return 0;
+	}
+
 	_clk_stm32_gate_enable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, true) != 0U) {
@@ -971,6 +984,10 @@
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return;
+	}
+
 	_clk_stm32_gate_disable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, false) != 0U) {
@@ -1073,12 +1090,10 @@
 	priv->base = base;
 
 	for (i = 0U; i < priv->num; i++) {
-		const struct clk_stm32 *clk = _clk_get(priv, i);
+		const struct stm32_clk_ops *ops = _clk_get_ops(priv, i);
 
-		assert(clk->ops != NULL);
-
-		if (clk->ops->init != NULL) {
-			clk->ops->init(priv, i);
+		if (ops->init != NULL) {
+			ops->init(priv, i);
 		}
 	}
 
diff --git a/drivers/st/clk/clk-stm32-core.h b/drivers/st/clk/clk-stm32-core.h
index 8bfb513..bfb5f11 100644
--- a/drivers/st/clk/clk-stm32-core.h
+++ b/drivers/st/clk/clk-stm32-core.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -21,23 +21,23 @@
 };
 
 struct clk_div_table {
-	unsigned int val;
-	unsigned int div;
+	uint16_t val;
+	uint16_t div;
 };
 
 struct div_cfg {
+	const struct clk_div_table *table;
 	uint16_t offset;
 	uint8_t shift;
 	uint8_t width;
 	uint8_t flags;
 	uint8_t bitrdy;
-	const struct clk_div_table *table;
 };
 
 struct parent_cfg {
-	uint8_t num_parents;
 	const uint16_t *id_parents;
 	struct mux_cfg *mux;
+	uint8_t num_parents;
 };
 
 struct stm32_clk_priv;
@@ -56,9 +56,9 @@
 struct clk_stm32 {
 	uint16_t binding;
 	uint16_t parent;
+	uint8_t ops;
 	uint8_t flags;
 	void *clock_cfg;
-	const struct stm32_clk_ops *ops;
 };
 
 struct stm32_clk_priv {
@@ -73,8 +73,9 @@
 	const uint32_t nb_div;
 	struct clk_oscillator_data *osci_data;
 	const uint32_t nb_osci_data;
-	uint32_t *gate_refcounts;
+	uint8_t *gate_refcounts;
 	void *pdata;
+	const struct stm32_clk_ops **ops_array;
 };
 
 struct stm32_clk_bypass {
@@ -97,18 +98,14 @@
 
 struct clk_oscillator_data {
 	const char *name;
-	uint16_t id_clk;
-	unsigned long frequency;
-	uint16_t gate_id;
-	uint16_t gate_rdy_id;
 	struct stm32_clk_bypass *bypass;
 	struct stm32_clk_css *css;
 	struct stm32_clk_drive *drive;
-};
+	unsigned long frequency;
+	uint16_t id_clk;
+	uint16_t gate_id;
+	uint16_t gate_rdy_id;
 
-struct clk_fixed_rate {
-	const char *name;
-	unsigned long fixed_rate;
 };
 
 struct clk_gate_cfg {
@@ -144,6 +141,9 @@
 #define MASK_WIDTH_SHIFT(_width, _shift) \
 	GENMASK(((_width) + (_shift) - 1U), (_shift))
 
+void clk_stm32_rcc_regs_lock(void);
+void clk_stm32_rcc_regs_unlock(void);
+
 int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base);
 void clk_stm32_enable_critical_clocks(void);
 
@@ -218,7 +218,7 @@
 #endif
 
 struct clk_stm32_div_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
@@ -229,11 +229,11 @@
 		.clock_cfg	= &(struct clk_stm32_div_cfg){\
 			.id	= (_div_id),\
 		},\
-		.ops		= &clk_stm32_divider_ops,\
+		.ops		= STM32_DIVIDER_OPS,\
 	}
 
 struct clk_stm32_gate_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
@@ -244,12 +244,12 @@
 		.clock_cfg	= &(struct clk_stm32_gate_cfg){\
 			.id	= (_gate_id),\
 		},\
-		.ops		= &clk_stm32_gate_ops,\
+		.ops		= STM32_GATE_OPS,\
 	}
 
 struct fixed_factor_cfg {
-	unsigned int mult;
-	unsigned int div;
+	uint8_t mult;
+	uint8_t div;
 };
 
 unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
@@ -263,7 +263,7 @@
 			.mult	= (_mult),\
 			.div	= (_div),\
 		},\
-		.ops		= &clk_fixed_factor_ops,\
+		.ops		= FIXED_FACTOR_OPS,\
 	}
 
 #define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
@@ -275,7 +275,7 @@
 			.offset		= (_offset),\
 			.bit_idx	= (_bit_idx),\
 		},\
-		.ops		= &clk_gate_ops,\
+		.ops		= GATE_OPS,\
 	}
 
 #define STM32_MUX(idx, _binding, _mux_id, _flags) \
@@ -284,7 +284,7 @@
 		.parent		= (MUX(_mux_id)),\
 		.flags		= (_flags),\
 		.clock_cfg	= NULL,\
-		.ops		= (&clk_mux_ops),\
+		.ops		= STM32_MUX_OPS\
 	}
 
 struct clk_timer_cfg {
@@ -301,7 +301,7 @@
 			.apbdiv = (_apbdiv),\
 			.timpre = (_timpre),\
 		},\
-		.ops		= &clk_timer_ops,\
+		.ops		= STM32_TIMER_OPS,\
 	}
 
 struct clk_stm32_fixed_rate_cfg {
@@ -315,7 +315,7 @@
 		.clock_cfg	= &(struct clk_stm32_fixed_rate_cfg){\
 			.rate	= (_rate),\
 		},\
-		.ops		= &clk_stm32_fixed_rate_ops,\
+		.ops		= STM32_FIXED_RATE_OPS,\
 	}
 
 #define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
@@ -355,7 +355,7 @@
 void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
 
 struct stm32_osc_cfg {
-	int osc_id;
+	uint8_t osc_id;
 };
 
 #define CLK_OSC(idx, _idx, _parent, _osc_id) \
@@ -366,7 +366,7 @@
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id = (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_ops,\
+		.ops		= STM32_OSC_OPS,\
 	}
 
 #define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
@@ -377,7 +377,7 @@
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id	= (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_nogate_ops,\
+		.ops		= STM32_OSC_NOGATE_OPS,\
 	}
 
 extern const struct stm32_clk_ops clk_mux_ops;
@@ -390,4 +390,19 @@
 extern const struct stm32_clk_ops clk_stm32_osc_ops;
 extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
 
+enum {
+	NO_OPS,
+	FIXED_FACTOR_OPS,
+	GATE_OPS,
+	STM32_MUX_OPS,
+	STM32_DIVIDER_OPS,
+	STM32_GATE_OPS,
+	STM32_TIMER_OPS,
+	STM32_FIXED_RATE_OPS,
+	STM32_OSC_OPS,
+	STM32_OSC_NOGATE_OPS,
+
+	STM32_LAST_OPS
+};
+
 #endif /* CLK_STM32_CORE_H */
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
index 01d1764..fd62049 100644
--- a/drivers/st/clk/clk-stm32mp13.c
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -186,65 +186,7 @@
 	_MCE,
 	_FMC_K,
 	_QSPI_K,
-#if defined(IMAGE_BL32)
-	_LTDC,
-	_DMA1,
-	_DMA2,
-	_MDMA,
-	_ETH1MAC,
-	_USBH,
-	_TIM2,
-	_TIM3,
-	_TIM4,
-	_TIM5,
-	_TIM6,
-	_TIM7,
-	_LPTIM1_K,
-	_SPI2_K,
-	_SPI3_K,
-	_SPDIF_K,
-	_TIM1,
-	_TIM8,
-	_SPI1_K,
-	_SAI1_K,
-	_SAI2_K,
-	_DFSDM,
-	_FDCAN_K,
-	_TIM13,
-	_TIM14,
-	_TIM16,
-	_TIM17,
-	_SPI4_K,
-	_SPI5_K,
-	_I2C1_K,
-	_I2C2_K,
-	_ADFSDM,
-	_LPTIM2_K,
-	_LPTIM3_K,
-	_LPTIM4_K,
-	_LPTIM5_K,
-	_VREF,
-	_DTS,
-	_PMBCTRL,
-	_HDP,
-	_STGENRO,
-	_DCMIPP_K,
-	_DMAMUX1,
-	_DMAMUX2,
-	_DMA3,
-	_ADC1_K,
-	_ADC2_K,
-	_TSC,
-	_AXIMC,
-	_ETH1CK,
-	_ETH1TX,
-	_ETH1RX,
-	_CRC1,
-	_ETH2CK,
-	_ETH2TX,
-	_ETH2RX,
-	_ETH2MAC,
-#endif
+
 	CK_LAST
 };
 
@@ -947,7 +889,7 @@
 #endif
 
 /* RCC clock device driver private */
-static unsigned int refcounts_mp13[CK_LAST];
+static uint8_t refcounts_mp13[CK_LAST];
 
 static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
 
@@ -1007,6 +949,11 @@
 		return;
 	}
 
+	/* Do not reconfigure LSE if already enabled */
+	if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
+		return;
+	}
+
 	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
 
 	clk_oscillator_set_drive(priv, _CK_LSE, drive);
@@ -1027,8 +974,8 @@
 	timeout = timeout_init_us(HSIDIV_TIMEOUT);
 	while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
-			      address, mmio_read_32(address));
+			EARLY_ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
+				    address, mmio_read_32(address));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1050,7 +997,7 @@
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -EINVAL;
 	}
 
@@ -1292,7 +1239,7 @@
 	uint32_t value = 0;
 
 	if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
-		ERROR("Invalid Vref clock !\n");
+		EARLY_ERROR("Invalid Vref clock !\n");
 		panic();
 	}
 
@@ -1352,6 +1299,123 @@
 	return &pdata->pll[pll_idx];
 }
 
+/* Define characteristic for PLL1 : PLL_2000 */
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		992000000U
+#define VCO_MAX		2000000000U
+
+static int clk_compute_pll1_settings(uint32_t freq_khz)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_pll_dt_cfg *pll1 = clk_stm32_pll_get_pdata(_PLL1);
+	struct stm32_pll_dt_cfg *pll2 = clk_stm32_pll_get_pdata(_PLL2);
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
+	unsigned long input_freq = 0UL;
+	uint32_t src =  pll2->vco.src;
+
+	/* PLL1 share the same clock source than PLL2 */
+	switch (src) {
+	case CLK_PLL12_HSI:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSE);
+		break;
+	default:
+		break;
+	}
+
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	/* Following parameters have always the same value */
+	pll1->output.output[PLL_CFG_Q] = 0U;
+	pll1->output.output[PLL_CFG_R] = 0U;
+
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
+
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
+			continue;
+		}
+
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
+
+			freq = output_freq * divm * (divp + 1U);
+
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
+
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pll1->vco.src = src;
+					pll1->vco.status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_PLLON;
+					pll1->vco.div_mn[PLL_CFG_M] = divm - 1U;
+					pll1->vco.div_mn[PLL_CFG_N] = (uint32_t)divn;
+					pll1->vco.frac = (uint32_t)frac;
+					pll1->output.output[PLL_CFG_P] = divp;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
+		}
+	}
+
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
 {
 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
@@ -1388,8 +1452,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock start failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1406,8 +1470,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock stop failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1629,7 +1693,7 @@
 }
 
 struct stm32_pll_cfg {
-	int pll_id;
+	uint8_t pll_id;
 };
 
 static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv,  int id,
@@ -1711,12 +1775,12 @@
 	.clock_cfg	= &(struct stm32_pll_cfg) {\
 		.pll_id = _pll_id,\
 	},\
-	.ops = &clk_stm32_pll_ops,\
+	.ops = STM32_PLL_OPS,\
 }
 
 struct clk_stm32_composite_cfg {
-	int gate_id;
-	int div_id;
+	uint8_t gate_id;
+	uint8_t div_id;
 };
 
 static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
@@ -1768,9 +1832,32 @@
 		.gate_id	= (_gate_id),\
 		.div_id	= (_div_id),\
 	},\
-	.ops = &clk_stm32_composite_ops,\
+	.ops = STM32_COMPOSITE_OPS,\
 }
 
+enum {
+	STM32_PLL_OPS = STM32_LAST_OPS,
+	STM32_COMPOSITE_OPS,
+
+	MP13_LAST_OPS
+};
+
+static const struct stm32_clk_ops *ops_array_mp13[MP13_LAST_OPS] = {
+	[NO_OPS] =  NULL,
+	[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
+	[GATE_OPS] = &clk_gate_ops,
+	[STM32_MUX_OPS] = &clk_mux_ops,
+	[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
+	[STM32_GATE_OPS] = &clk_stm32_gate_ops,
+	[STM32_TIMER_OPS] = &clk_timer_ops,
+	[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
+	[STM32_OSC_OPS] = &clk_stm32_osc_ops,
+	[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
+
+	[STM32_PLL_OPS] = &clk_stm32_pll_ops,
+	[STM32_COMPOSITE_OPS] = &clk_stm32_composite_ops
+};
+
 static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
 	/* ROOT CLOCKS */
 	CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
@@ -1882,7 +1969,6 @@
 	STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
 	STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
 
-/* TODO: CHECK CLOCK FOR BL2/BL32 AND IF ONLY FOR TEST OR NOT */
 	STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
 	STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
 	STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
@@ -1896,61 +1982,6 @@
 	STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
 	STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
 	STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
-
-#if defined(IMAGE_BL32)
-	STM32_GATE(_TIM2, TIM2_K, _CKTIMG1, 0, GATE_TIM2),
-	STM32_GATE(_TIM3, TIM3_K, _CKTIMG1, 0, GATE_TIM3),
-	STM32_GATE(_TIM4, TIM4_K, _CKTIMG1, 0, GATE_TIM4),
-	STM32_GATE(_TIM5, TIM5_K, _CKTIMG1, 0, GATE_TIM5),
-	STM32_GATE(_TIM6, TIM6_K, _CKTIMG1, 0, GATE_TIM6),
-	STM32_GATE(_TIM7, TIM7_K, _CKTIMG1, 0, GATE_TIM7),
-	STM32_GATE(_TIM13, TIM13_K, _CKTIMG3, 0, GATE_TIM13),
-	STM32_GATE(_TIM14, TIM14_K, _CKTIMG3, 0, GATE_TIM14),
-	STM32_GATE(_LPTIM1_K, LPTIM1_K, MUX(MUX_LPTIM1), 0, GATE_LPTIM1),
-	STM32_GATE(_SPI2_K, SPI2_K, MUX(MUX_SPI23), 0, GATE_SPI2),
-	STM32_GATE(_SPI3_K, SPI3_K, MUX(MUX_SPI23), 0, GATE_SPI3),
-	STM32_GATE(_SPDIF_K, SPDIF_K, MUX(MUX_SPDIF), 0, GATE_SPDIF),
-	STM32_GATE(_TIM1, TIM1_K, _CKTIMG2, 0, GATE_TIM1),
-	STM32_GATE(_TIM8, TIM8_K, _CKTIMG2, 0, GATE_TIM8),
-	STM32_GATE(_TIM16, TIM16_K, _CKTIMG3, 0, GATE_TIM16),
-	STM32_GATE(_TIM17, TIM17_K, _CKTIMG3, 0, GATE_TIM17),
-	STM32_GATE(_SPI1_K, SPI1_K, MUX(MUX_SPI1), 0, GATE_SPI1),
-	STM32_GATE(_SPI4_K, SPI4_K, MUX(MUX_SPI4), 0, GATE_SPI4),
-	STM32_GATE(_SPI5_K, SPI5_K, MUX(MUX_SPI5), 0, GATE_SPI5),
-	STM32_GATE(_SAI1_K, SAI1_K, MUX(MUX_SAI1), 0, GATE_SAI1),
-	STM32_GATE(_SAI2_K, SAI2_K, MUX(MUX_SAI2), 0, GATE_SAI2),
-	STM32_GATE(_DFSDM, DFSDM_K, MUX(MUX_SAI1), 0, GATE_DFSDM),
-	STM32_GATE(_FDCAN_K, FDCAN_K, MUX(MUX_FDCAN), 0, GATE_FDCAN),
-	STM32_GATE(_USBH, USBH, _CKAXI, 0, GATE_USBH),
-	STM32_GATE(_I2C1_K, I2C1_K, MUX(MUX_I2C12), 0, GATE_I2C1),
-	STM32_GATE(_I2C2_K, I2C2_K, MUX(MUX_I2C12), 0, GATE_I2C2),
-	STM32_GATE(_ADFSDM, ADFSDM_K, MUX(MUX_SAI1), 0, GATE_ADFSDM),
-	STM32_GATE(_LPTIM2_K, LPTIM2_K, MUX(MUX_LPTIM2), 0, GATE_LPTIM2),
-	STM32_GATE(_LPTIM3_K, LPTIM3_K, MUX(MUX_LPTIM3), 0, GATE_LPTIM3),
-	STM32_GATE(_LPTIM4_K, LPTIM4_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM4),
-	STM32_GATE(_LPTIM5_K, LPTIM5_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM5),
-	STM32_GATE(_VREF, VREF, _PCLK3, 0, GATE_VREF),
-	STM32_GATE(_DTS, TMPSENS, _PCLK3, 0, GATE_DTS),
-	STM32_GATE(_PMBCTRL, PMBCTRL, _PCLK3, 0, GATE_HDP),
-	STM32_GATE(_HDP, HDP, _PCLK3, 0, GATE_PMBCTRL),
-	STM32_GATE(_STGENRO, STGENRO, _PCLK4, 0, GATE_DCMIPP),
-	STM32_GATE(_DCMIPP_K, DCMIPP_K, MUX(MUX_DCMIPP), 0, GATE_DCMIPP),
-	STM32_GATE(_DMAMUX1, DMAMUX1, _CKAXI, 0, GATE_DMAMUX1),
-	STM32_GATE(_DMAMUX2, DMAMUX2, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_DMA3, DMA3, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_ADC1_K, ADC1_K, MUX(MUX_ADC1), 0, GATE_ADC1),
-	STM32_GATE(_ADC2_K, ADC2_K, MUX(MUX_ADC2), 0, GATE_ADC2),
-	STM32_GATE(_TSC, TSC, _CKAXI, 0, GATE_TSC),
-	STM32_GATE(_AXIMC, AXIMC, _CKAXI, 0, GATE_AXIMC),
-	STM32_GATE(_CRC1, CRC1, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1CK, ETH1CK_K, MUX(MUX_ETH1), 0, GATE_ETH1CK),
-	STM32_GATE(_ETH1TX, ETH1TX, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1RX, ETH1RX, _CKAXI, 0, GATE_ETH1RX),
-	STM32_GATE(_ETH2CK, ETH2CK_K, MUX(MUX_ETH2), 0, GATE_ETH2CK),
-	STM32_GATE(_ETH2TX, ETH2TX, _CKAXI, 0, GATE_ETH2TX),
-	STM32_GATE(_ETH2RX, ETH2RX, _CKAXI, 0, GATE_ETH2RX),
-	STM32_GATE(_ETH2MAC, ETH2MAC, _CKAXI, 0, GATE_ETH2MAC),
-#endif
 };
 
 static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
@@ -1986,6 +2017,7 @@
 	.nb_osci_data	= ARRAY_SIZE(stm32mp13_osc_data),
 	.gate_refcounts	= refcounts_mp13,
 	.pdata		= &stm32mp13_clock_pdata,
+	.ops_array	= ops_array_mp13,
 };
 
 static int stm32mp1_init_clock_tree(void)
@@ -2072,8 +2104,6 @@
 	return 0;
 }
 
-#define LSEDRV_MEDIUM_HIGH 2
-
 static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
 					  struct stm32_osci_dt_cfg *osci)
 {
@@ -2241,7 +2271,8 @@
 {
 	size_t i = 0U;
 
-	for (i = _PLL1; i < pdata->npll; i++) {
+	/* PLL1 is not configurable with device tree */
+	for (i = _PLL2; i < pdata->npll; i++) {
 		struct stm32_pll_dt_cfg *pll = &pdata->pll[i];
 		char name[RCC_PLL_NAME_SIZE];
 		int subnode = 0;
@@ -2301,8 +2332,33 @@
 	return 0;
 }
 
+void stm32mp1_clk_rcc_regs_lock(void)
+{
+	clk_stm32_rcc_regs_lock();
+}
+
+void stm32mp1_clk_rcc_regs_unlock(void)
+{
+	clk_stm32_rcc_regs_unlock();
+}
+
 int stm32mp1_clk_init(void)
 {
+	int ret;
+
+	/* compute the PLL1 settings, not read in device tree */
+	ret = clk_compute_pll1_settings(PLL1_NOMINAL_FREQ_IN_KHZ);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = stm32mp1_init_clock_tree();
+	if (ret != 0) {
+		return ret;
+	}
+
+	clk_stm32_enable_critical_clocks();
+
 	return 0;
 }
 
@@ -2317,16 +2373,6 @@
 	}
 
 	ret = clk_stm32_init(&stm32mp13_clock_data, base);
-	if (ret != 0) {
-		return ret;
-	}
 
-	ret = stm32mp1_init_clock_tree();
-	if (ret != 0) {
-		return ret;
-	}
-
-	clk_stm32_enable_critical_clocks();
-
-	return 0;
+	return ret;
 }
diff --git a/drivers/st/clk/clk-stm32mp2.c b/drivers/st/clk/clk-stm32mp2.c
new file mode 100644
index 0000000..12839f1
--- /dev/null
+++ b/drivers/st/clk/clk-stm32mp2.c
@@ -0,0 +1,2357 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "clk-stm32-core.h"
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/st/stm32mp2_clk.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+struct stm32_osci_dt_cfg {
+	unsigned long freq;
+	uint32_t drive;
+	bool bypass;
+	bool digbyp;
+	bool css;
+};
+
+struct stm32_pll_dt_cfg {
+	uint32_t src;
+	uint32_t frac;
+	uint32_t cfg[PLLCFG_NB];
+	uint32_t csg[PLLCSG_NB];
+	bool csg_enabled;
+	bool enabled;
+};
+
+struct stm32_clk_platdata {
+	uintptr_t rcc_base;
+	uint32_t nosci;
+	struct stm32_osci_dt_cfg *osci;
+	uint32_t npll;
+	struct stm32_pll_dt_cfg *pll;
+	uint32_t nflexgen;
+	uint32_t *flexgen;
+	uint32_t nbusclk;
+	uint32_t *busclk;
+	uint32_t nkernelclk;
+	uint32_t *kernelclk;
+};
+
+/* A35 Sub-System which manages its own PLL (PLL1) */
+#define A35_SS_CHGCLKREQ	0x0000
+#define A35_SS_PLL_FREQ1	0x0080
+#define A35_SS_PLL_FREQ2	0x0090
+#define A35_SS_PLL_ENABLE	0x00a0
+
+#define A35_SS_CHGCLKREQ_ARM_CHGCLKREQ		BIT(0)
+#define A35_SS_CHGCLKREQ_ARM_CHGCLKACK		BIT(1)
+
+#define A35_SS_PLL_FREQ1_FBDIV_MASK		GENMASK(11, 0)
+#define A35_SS_PLL_FREQ1_FBDIV_SHIFT		0
+#define A35_SS_PLL_FREQ1_REFDIV_MASK		GENMASK(21, 16)
+#define A35_SS_PLL_FREQ1_REFDIV_SHIFT		16
+
+#define A35_SS_PLL_FREQ2_POSTDIV1_MASK		GENMASK(2, 0)
+#define A35_SS_PLL_FREQ2_POSTDIV1_SHIFT		0
+#define A35_SS_PLL_FREQ2_POSTDIV2_MASK		GENMASK(5, 3)
+#define A35_SS_PLL_FREQ2_POSTDIV2_SHIFT		3
+
+#define A35_SS_PLL_ENABLE_PD			BIT(0)
+#define A35_SS_PLL_ENABLE_LOCKP			BIT(1)
+#define A35_SS_PLL_ENABLE_NRESET_SWPLL_FF	BIT(2)
+
+#define TIMEOUT_US_200MS	U(200000)
+#define TIMEOUT_US_1S		U(1000000)
+
+#define PLLRDY_TIMEOUT		TIMEOUT_US_200MS
+#define CLKSRC_TIMEOUT		TIMEOUT_US_200MS
+#define CLKDIV_TIMEOUT		TIMEOUT_US_200MS
+#define OSCRDY_TIMEOUT		TIMEOUT_US_1S
+
+/* PLL minimal frequencies for clock sources */
+#define PLL_REFCLK_MIN			UL(5000000)
+#define PLL_FRAC_REFCLK_MIN		UL(10000000)
+
+#define XBAR_CHANNEL_NB			64
+
+/* Warning, should be start to 1 */
+enum clock {
+	_CK_0_MHZ,
+
+	/* ROOT CLOCKS */
+	_CK_HSI,
+	_CK_HSE,
+	_CK_MSI,
+	_CK_LSI,
+	_CK_LSE,
+	_I2SCKIN,
+	_SPDIFSYMB,
+	_CK_PLL1,
+	_CK_PLL2,
+	_CK_PLL3,
+	_CK_PLL4,
+	_CK_PLL5,
+	_CK_PLL6,
+	_CK_PLL7,
+	_CK_PLL8,
+	_CK_HSE_RTC,
+	_CK_RTCCK,
+	_CK_ICN_HS_MCU,
+	_CK_ICN_SDMMC,
+	_CK_ICN_DDR,
+	_CK_ICN_HSL,
+	_CK_ICN_NIC,
+	_CK_ICN_LS_MCU,
+	_CK_FLEXGEN_07,
+	_CK_FLEXGEN_08,
+	_CK_FLEXGEN_09,
+	_CK_FLEXGEN_10,
+	_CK_FLEXGEN_11,
+	_CK_FLEXGEN_12,
+	_CK_FLEXGEN_13,
+	_CK_FLEXGEN_14,
+	_CK_FLEXGEN_15,
+	_CK_FLEXGEN_16,
+	_CK_FLEXGEN_17,
+	_CK_FLEXGEN_18,
+	_CK_FLEXGEN_19,
+	_CK_FLEXGEN_20,
+	_CK_FLEXGEN_21,
+	_CK_FLEXGEN_22,
+	_CK_FLEXGEN_23,
+	_CK_FLEXGEN_24,
+	_CK_FLEXGEN_25,
+	_CK_FLEXGEN_26,
+	_CK_FLEXGEN_27,
+	_CK_FLEXGEN_28,
+	_CK_FLEXGEN_29,
+	_CK_FLEXGEN_30,
+	_CK_FLEXGEN_31,
+	_CK_FLEXGEN_32,
+	_CK_FLEXGEN_33,
+	_CK_FLEXGEN_34,
+	_CK_FLEXGEN_35,
+	_CK_FLEXGEN_36,
+	_CK_FLEXGEN_37,
+	_CK_FLEXGEN_38,
+	_CK_FLEXGEN_39,
+	_CK_FLEXGEN_40,
+	_CK_FLEXGEN_41,
+	_CK_FLEXGEN_42,
+	_CK_FLEXGEN_43,
+	_CK_FLEXGEN_44,
+	_CK_FLEXGEN_45,
+	_CK_FLEXGEN_46,
+	_CK_FLEXGEN_47,
+	_CK_FLEXGEN_48,
+	_CK_FLEXGEN_49,
+	_CK_FLEXGEN_50,
+	_CK_FLEXGEN_51,
+	_CK_FLEXGEN_52,
+	_CK_FLEXGEN_53,
+	_CK_FLEXGEN_54,
+	_CK_FLEXGEN_55,
+	_CK_FLEXGEN_56,
+	_CK_FLEXGEN_57,
+	_CK_FLEXGEN_58,
+	_CK_FLEXGEN_59,
+	_CK_FLEXGEN_60,
+	_CK_FLEXGEN_61,
+	_CK_FLEXGEN_62,
+	_CK_FLEXGEN_63,
+	_CK_ICN_APB1,
+	_CK_ICN_APB2,
+	_CK_ICN_APB3,
+	_CK_ICN_APB4,
+	_CK_ICN_APBDBG,
+	_CK_BKPSRAM,
+	_CK_BSEC,
+	_CK_CRC,
+	_CK_CRYP1,
+	_CK_CRYP2,
+	_CK_DDR,
+	_CK_DDRCAPB,
+	_CK_DDRCP,
+	_CK_DDRPHYC,
+	_CK_FMC,
+	_CK_GPIOA,
+	_CK_GPIOB,
+	_CK_GPIOC,
+	_CK_GPIOD,
+	_CK_GPIOE,
+	_CK_GPIOF,
+	_CK_GPIOG,
+	_CK_GPIOH,
+	_CK_GPIOI,
+	_CK_GPIOJ,
+	_CK_GPIOK,
+	_CK_GPIOZ,
+	_CK_HASH,
+	_CK_I2C1,
+	_CK_I2C2,
+	_CK_I2C3,
+	_CK_I2C4,
+	_CK_I2C5,
+	_CK_I2C6,
+	_CK_I2C7,
+	_CK_I2C8,
+	_CK_IWDG1,
+	_CK_IWDG2,
+	_CK_OSPI1,
+	_CK_OSPI2,
+	_CK_OSPIIOM,
+	_CK_PKA,
+	_CK_RETRAM,
+	_CK_RNG,
+	_CK_RTC,
+	_CK_SAES,
+	_CK_SDMMC1,
+	_CK_SDMMC2,
+	_CK_SRAM1,
+	_CK_SRAM2,
+	_CK_STGEN,
+	_CK_SYSCPU1,
+	_CK_SYSRAM,
+	_CK_UART4,
+	_CK_UART5,
+	_CK_UART7,
+	_CK_UART8,
+	_CK_UART9,
+	_CK_USART1,
+	_CK_USART2,
+	_CK_USART3,
+	_CK_USART6,
+	_CK_USB2EHCI,
+	_CK_USB2OHCI,
+	_CK_USB2PHY1,
+	_CK_USB2PHY2,
+	_CK_USB3DR,
+	_CK_USB3PCIEPHY,
+	_CK_USBTC,
+
+	CK_LAST
+};
+
+static const uint16_t muxsel_src[] = {
+	_CK_HSI, _CK_HSE, _CK_MSI, _CK_0_MHZ
+};
+
+static const uint16_t xbarsel_src[] = {
+	_CK_PLL4, _CK_PLL5, _CK_PLL6, _CK_PLL7, _CK_PLL8,
+	_CK_HSI, _CK_HSE, _CK_MSI, _CK_HSI, _CK_HSE, _CK_MSI,
+	_SPDIFSYMB, _I2SCKIN, _CK_LSI, _CK_LSE
+};
+
+static const uint16_t rtc_src[] = {
+	_CK_0_MHZ, _CK_LSE, _CK_LSI, _CK_HSE_RTC
+};
+
+static const uint16_t usb2phy1_src[] = {
+	_CK_FLEXGEN_57, _CK_HSE
+};
+
+static const uint16_t usb2phy2_src[] = {
+	_CK_FLEXGEN_58, _CK_HSE
+};
+
+static const uint16_t usb3pciphy_src[] = {
+	_CK_FLEXGEN_34, _CK_HSE
+};
+
+static const uint16_t d3per_src[] = {
+	_CK_MSI, _CK_LSI, _CK_LSE
+};
+
+#define MUX_CONF(id, src, _offset, _shift, _witdh)[id] = {\
+	.id_parents	= src,\
+	.num_parents	= ARRAY_SIZE(src),\
+	.mux		= &(struct mux_cfg) {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_witdh),\
+		.bitrdy = UINT8_MAX,\
+	},\
+}
+
+static const struct parent_cfg parent_mp25[] = {
+	MUX_CONF(MUX_MUXSEL0, muxsel_src, RCC_MUXSELCFGR, 0, 2),
+	MUX_CONF(MUX_MUXSEL1, muxsel_src, RCC_MUXSELCFGR, 4, 2),
+	MUX_CONF(MUX_MUXSEL2, muxsel_src, RCC_MUXSELCFGR, 8, 2),
+	MUX_CONF(MUX_MUXSEL3, muxsel_src, RCC_MUXSELCFGR, 12, 2),
+	MUX_CONF(MUX_MUXSEL4, muxsel_src, RCC_MUXSELCFGR, 16, 2),
+	MUX_CONF(MUX_MUXSEL5, muxsel_src, RCC_MUXSELCFGR, 20, 2),
+	MUX_CONF(MUX_MUXSEL6, muxsel_src, RCC_MUXSELCFGR, 24, 2),
+	MUX_CONF(MUX_MUXSEL7, muxsel_src, RCC_MUXSELCFGR, 28, 2),
+	MUX_CONF(MUX_XBARSEL, xbarsel_src, RCC_XBAR0CFGR, 0, 4),
+	MUX_CONF(MUX_RTC, rtc_src, RCC_BDCR, 16, 2),
+	MUX_CONF(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1),
+	MUX_CONF(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1),
+	MUX_CONF(MUX_USB3PCIEPHY, usb3pciphy_src, RCC_USB3PCIEPHYCFGR, 15, 1),
+	MUX_CONF(MUX_D3PER, d3per_src, RCC_D3DCR, 16, 2),
+};
+
+/* GATES */
+enum enum_gate_cfg {
+	GATE_ZERO, /* reserved for no gate */
+	GATE_LSE,
+	GATE_RTCCK,
+	GATE_LSI,
+	GATE_HSI,
+	GATE_MSI,
+	GATE_HSE,
+	GATE_LSI_RDY,
+	GATE_MSI_RDY,
+	GATE_LSE_RDY,
+	GATE_HSE_RDY,
+	GATE_HSI_RDY,
+	GATE_SYSRAM,
+	GATE_RETRAM,
+	GATE_SRAM1,
+	GATE_SRAM2,
+
+	GATE_DDRPHYC,
+	GATE_SYSCPU1,
+	GATE_CRC,
+	GATE_OSPIIOM,
+	GATE_BKPSRAM,
+	GATE_HASH,
+	GATE_RNG,
+	GATE_CRYP1,
+	GATE_CRYP2,
+	GATE_SAES,
+	GATE_PKA,
+
+	GATE_GPIOA,
+	GATE_GPIOB,
+	GATE_GPIOC,
+	GATE_GPIOD,
+	GATE_GPIOE,
+	GATE_GPIOF,
+	GATE_GPIOG,
+	GATE_GPIOH,
+	GATE_GPIOI,
+	GATE_GPIOJ,
+	GATE_GPIOK,
+	GATE_GPIOZ,
+	GATE_RTC,
+
+	GATE_DDRCP,
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	GATE_USB2OHCI,
+	GATE_USB2EHCI,
+
+	GATE_USB3DR,
+
+	GATE_BSEC,
+	GATE_IWDG1,
+	GATE_IWDG2,
+
+	GATE_DDRCAPB,
+	GATE_DDR,
+
+	GATE_USART2,
+	GATE_UART4,
+	GATE_USART3,
+	GATE_UART5,
+	GATE_I2C1,
+	GATE_I2C2,
+	GATE_I2C3,
+	GATE_I2C5,
+	GATE_I2C4,
+	GATE_I2C6,
+	GATE_I2C7,
+	GATE_USART1,
+	GATE_USART6,
+	GATE_UART7,
+	GATE_UART8,
+	GATE_UART9,
+	GATE_STGEN,
+	GATE_USB3PCIEPHY,
+	GATE_USBTC,
+	GATE_I2C8,
+	GATE_OSPI1,
+	GATE_OSPI2,
+	GATE_FMC,
+	GATE_SDMMC1,
+	GATE_SDMMC2,
+	GATE_USB2PHY1,
+	GATE_USB2PHY2,
+	LAST_GATE
+};
+
+#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
+	.offset		= (_offset),\
+	.bit_idx	= (_bit_idx),\
+	.set_clr	= (_offset_clr),\
+}
+
+static const struct gate_cfg gates_mp25[LAST_GATE] = {
+	GATE_CFG(GATE_LSE,		RCC_BDCR,		0,	0),
+	GATE_CFG(GATE_LSI,		RCC_BDCR,		9,	0),
+	GATE_CFG(GATE_RTCCK,		RCC_BDCR,		20,	0),
+	GATE_CFG(GATE_HSI,		RCC_OCENSETR,		0,	1),
+	GATE_CFG(GATE_HSE,		RCC_OCENSETR,		8,	1),
+	GATE_CFG(GATE_MSI,		RCC_D3DCR,		0,	0),
+
+	GATE_CFG(GATE_LSI_RDY,		RCC_BDCR,		10,	0),
+	GATE_CFG(GATE_LSE_RDY,		RCC_BDCR,		2,	0),
+	GATE_CFG(GATE_MSI_RDY,		RCC_D3DCR,		2,	0),
+	GATE_CFG(GATE_HSE_RDY,		RCC_OCRDYR,		8,	0),
+	GATE_CFG(GATE_HSI_RDY,		RCC_OCRDYR,		0,	0),
+	GATE_CFG(GATE_SYSRAM,		RCC_SYSRAMCFGR,		1,	0),
+	GATE_CFG(GATE_RETRAM,		RCC_RETRAMCFGR,		1,	0),
+	GATE_CFG(GATE_SRAM1,		RCC_SRAM1CFGR,		1,	0),
+	GATE_CFG(GATE_SRAM2,		RCC_SRAM2CFGR,		1,	0),
+	GATE_CFG(GATE_DDRPHYC,		RCC_DDRPHYCAPBCFGR,	1,	0),
+	GATE_CFG(GATE_SYSCPU1,		RCC_SYSCPU1CFGR,	1,	0),
+	GATE_CFG(GATE_CRC,		RCC_CRCCFGR,		1,	0),
+	GATE_CFG(GATE_OSPIIOM,		RCC_OSPIIOMCFGR,	1,	0),
+	GATE_CFG(GATE_BKPSRAM,		RCC_BKPSRAMCFGR,	1,	0),
+	GATE_CFG(GATE_HASH,		RCC_HASHCFGR,		1,	0),
+	GATE_CFG(GATE_RNG,		RCC_RNGCFGR,		1,	0),
+	GATE_CFG(GATE_CRYP1,		RCC_CRYP1CFGR,		1,	0),
+	GATE_CFG(GATE_CRYP2,		RCC_CRYP2CFGR,		1,	0),
+	GATE_CFG(GATE_SAES,		RCC_SAESCFGR,		1,	0),
+	GATE_CFG(GATE_PKA,		RCC_PKACFGR,		1,	0),
+	GATE_CFG(GATE_GPIOA,		RCC_GPIOACFGR,		1,	0),
+	GATE_CFG(GATE_GPIOB,		RCC_GPIOBCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOC,		RCC_GPIOCCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOD,		RCC_GPIODCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOE,		RCC_GPIOECFGR,		1,	0),
+	GATE_CFG(GATE_GPIOF,		RCC_GPIOFCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOG,		RCC_GPIOGCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOH,		RCC_GPIOHCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOI,		RCC_GPIOICFGR,		1,	0),
+	GATE_CFG(GATE_GPIOJ,		RCC_GPIOJCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOK,		RCC_GPIOKCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOZ,		RCC_GPIOZCFGR,		1,	0),
+	GATE_CFG(GATE_RTC,		RCC_RTCCFGR,		1,	0),
+	GATE_CFG(GATE_DDRCP,		RCC_DDRCPCFGR,		1,	0),
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	GATE_CFG(GATE_USB2OHCI,		RCC_USB2CFGR,		1,	0),
+	GATE_CFG(GATE_USB2EHCI,		RCC_USB2CFGR,		1,	0),
+	GATE_CFG(GATE_USB3DR,		RCC_USB3DRCFGR,		1,	0),
+	GATE_CFG(GATE_BSEC,		RCC_BSECCFGR,		1,	0),
+	GATE_CFG(GATE_IWDG1,		RCC_IWDG1CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG2,		RCC_IWDG2CFGR,		1,	0),
+	GATE_CFG(GATE_DDRCAPB,		RCC_DDRCAPBCFGR,	1,	0),
+	GATE_CFG(GATE_DDR,		RCC_DDRCFGR,		1,	0),
+	GATE_CFG(GATE_USART2,		RCC_USART2CFGR,		1,	0),
+	GATE_CFG(GATE_UART4,		RCC_UART4CFGR,		1,	0),
+	GATE_CFG(GATE_USART3,		RCC_USART3CFGR,		1,	0),
+	GATE_CFG(GATE_UART5,		RCC_UART5CFGR,		1,	0),
+	GATE_CFG(GATE_I2C1,		RCC_I2C1CFGR,		1,	0),
+	GATE_CFG(GATE_I2C2,		RCC_I2C2CFGR,		1,	0),
+	GATE_CFG(GATE_I2C3,		RCC_I2C3CFGR,		1,	0),
+	GATE_CFG(GATE_I2C5,		RCC_I2C5CFGR,		1,	0),
+	GATE_CFG(GATE_I2C4,		RCC_I2C4CFGR,		1,	0),
+	GATE_CFG(GATE_I2C6,		RCC_I2C6CFGR,		1,	0),
+	GATE_CFG(GATE_I2C7,		RCC_I2C7CFGR,		1,	0),
+	GATE_CFG(GATE_USART1,		RCC_USART1CFGR,		1,	0),
+	GATE_CFG(GATE_USART6,		RCC_USART6CFGR,		1,	0),
+	GATE_CFG(GATE_UART7,		RCC_UART7CFGR,		1,	0),
+	GATE_CFG(GATE_UART8,		RCC_UART8CFGR,		1,	0),
+	GATE_CFG(GATE_UART9,		RCC_UART9CFGR,		1,	0),
+	GATE_CFG(GATE_STGEN,		RCC_STGENCFGR,		1,	0),
+	GATE_CFG(GATE_USB3PCIEPHY,	RCC_USB3PCIEPHYCFGR,	1,	0),
+	GATE_CFG(GATE_USBTC,		RCC_USBTCCFGR,		1,	0),
+	GATE_CFG(GATE_I2C8,		RCC_I2C8CFGR,		1,	0),
+	GATE_CFG(GATE_OSPI1,		RCC_OSPI1CFGR,		1,	0),
+	GATE_CFG(GATE_OSPI2,		RCC_OSPI2CFGR,		1,	0),
+	GATE_CFG(GATE_FMC,		RCC_FMCCFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC1,		RCC_SDMMC1CFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC2,		RCC_SDMMC2CFGR,		1,	0),
+	GATE_CFG(GATE_USB2PHY1,		RCC_USB2PHY1CFGR,	1,	0),
+	GATE_CFG(GATE_USB2PHY2,		RCC_USB2PHY2CFGR,	1,	0),
+};
+
+static const struct clk_div_table apb_div_table[] = {
+	{ 0, 1 },  { 1, 2 },  { 2, 4 },  { 3, 8 }, { 4, 16 },
+	{ 5, 16 }, { 6, 16 }, { 7, 16 }, { 0 },
+};
+
+#undef DIV_CFG
+#define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
+		.offset	= _offset,\
+		.shift	= _shift,\
+		.width	= _width,\
+		.flags	= _flags,\
+		.table	= _table,\
+		.bitrdy	= _bitrdy,\
+}
+
+static const struct div_cfg dividers_mp25[] = {
+	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APBDBG, RCC_APBDBGDIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_LSMCU, RCC_LSMCUDIVR, 0, 1, 0, NULL, 31),
+	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, 0),
+};
+
+enum stm32_osc {
+	OSC_HSI,
+	OSC_HSE,
+	OSC_MSI,
+	OSC_LSI,
+	OSC_LSE,
+	OSC_I2SCKIN,
+	OSC_SPDIFSYMB,
+	NB_OSCILLATOR
+};
+
+static struct clk_oscillator_data stm32mp25_osc_data[] = {
+	OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_MSI, _CK_MSI, "clk-msi", GATE_MSI, GATE_MSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
+		   BYPASS(RCC_OCENSETR, 10, 7),
+		   CSS(RCC_OCENSETR, 11),
+		   NULL),
+
+	OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
+		   BYPASS(RCC_BDCR, 1, 3),
+		   CSS(RCC_BDCR, 8),
+		   DRIVE(RCC_BDCR, 4, 2, 2)),
+
+	OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_SPDIFSYMB, _SPDIFSYMB, "spdif_symb", NO_GATE, NO_GATE,
+		   NULL, NULL, NULL),
+};
+
+#ifdef IMAGE_BL2
+static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
+{
+	if (id < NB_OSCILLATOR) {
+		return stm32mp25_osc_data[id].name;
+	}
+
+	return NULL;
+}
+#endif
+
+enum pll_id {
+	_PLL1,
+	_PLL2,
+	_PLL3,
+	_PLL4,
+	_PLL5,
+	_PLL6,
+	_PLL7,
+	_PLL8,
+	_PLL_NB
+};
+
+/* PLL configuration registers offsets from RCC_PLLxCFGR1 */
+#define RCC_OFFSET_PLLXCFGR1		0x00
+#define RCC_OFFSET_PLLXCFGR2		0x04
+#define RCC_OFFSET_PLLXCFGR3		0x08
+#define RCC_OFFSET_PLLXCFGR4		0x0C
+#define RCC_OFFSET_PLLXCFGR5		0x10
+#define RCC_OFFSET_PLLXCFGR6		0x18
+#define RCC_OFFSET_PLLXCFGR7		0x1C
+
+struct stm32_clk_pll {
+	uint16_t clk_id;
+	uint16_t reg_pllxcfgr1;
+};
+
+#define CLK_PLL_CFG(_idx, _clk_id, _reg)\
+	[(_idx)] = {\
+		.clk_id = (_clk_id),\
+		.reg_pllxcfgr1 = (_reg),\
+	}
+
+static const struct stm32_clk_pll stm32mp25_clk_pll[_PLL_NB] = {
+	CLK_PLL_CFG(_PLL1, _CK_PLL1, A35_SS_CHGCLKREQ),
+	CLK_PLL_CFG(_PLL2, _CK_PLL2, RCC_PLL2CFGR1),
+	CLK_PLL_CFG(_PLL3, _CK_PLL3, RCC_PLL3CFGR1),
+	CLK_PLL_CFG(_PLL4, _CK_PLL4, RCC_PLL4CFGR1),
+	CLK_PLL_CFG(_PLL5, _CK_PLL5, RCC_PLL5CFGR1),
+	CLK_PLL_CFG(_PLL6, _CK_PLL6, RCC_PLL6CFGR1),
+	CLK_PLL_CFG(_PLL7, _CK_PLL7, RCC_PLL7CFGR1),
+	CLK_PLL_CFG(_PLL8, _CK_PLL8, RCC_PLL8CFGR1),
+};
+
+static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx)
+{
+	return &stm32mp25_clk_pll[idx];
+}
+
+static unsigned long clk_get_pll_fvco(struct stm32_clk_priv *priv,
+				      const struct stm32_clk_pll *pll,
+				      unsigned long prate)
+{
+	unsigned long refclk, fvco;
+	uint32_t fracin, fbdiv, refdiv;
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+
+	refclk = prate;
+
+	fracin = mmio_read_32(pllxcfgr3) & RCC_PLLxCFGR3_FRACIN_MASK;
+	fbdiv = (mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FBDIV_MASK) >>
+		RCC_PLLxCFGR2_FBDIV_SHIFT;
+	refdiv = mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FREFDIV_MASK;
+
+	if (fracin != 0U) {
+		uint64_t numerator, denominator;
+
+		numerator = ((uint64_t)fbdiv << 24) + fracin;
+		numerator = refclk * numerator;
+		denominator = (uint64_t)refdiv << 24;
+		fvco = (unsigned long)(numerator / denominator);
+	} else {
+		fvco = (unsigned long)(refclk * fbdiv / refdiv);
+	}
+
+	return fvco;
+}
+
+struct stm32_pll_cfg {
+	uint16_t pll_id;
+};
+
+static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	return ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLEN) != 0U);
+}
+
+static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+}
+
+static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	/* Stop PLL */
+	mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+}
+
+static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
+					const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	/* Wait PLL lock */
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcfgr1,
+			      mmio_read_32(pllxcfgr1));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
+					 const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	/* Wait PLL stopped */
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			ERROR("PLL%d stop failed @ 0x%lx: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pllxcfgr1, mmio_read_32(pllxcfgr1));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	if (_clk_stm32_pll_is_enabled(priv, pll)) {
+		return 0;
+	}
+
+	_clk_stm32_pll_set_on(priv, pll);
+
+	return _clk_stm32_pll_wait_ready_on(priv, pll);
+}
+
+static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	if (!_clk_stm32_pll_is_enabled(priv, pll)) {
+		return;
+	}
+
+	_clk_stm32_pll_set_off(priv, pll);
+
+	_clk_stm32_pll_wait_ready_off(priv, pll);
+}
+
+static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	return _clk_stm32_pll_is_enabled(priv, pll);
+}
+
+static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	return _clk_stm32_pll_enable(priv, pll);
+}
+
+static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	_clk_stm32_pll_disable(priv, pll);
+}
+
+static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
+					       unsigned long prate)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
+	uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
+	unsigned long dfout;
+	uint32_t postdiv1, postdiv2;
+
+	postdiv1 = mmio_read_32(pllxcfgr6) & RCC_PLLxCFGR6_POSTDIV1_MASK;
+	postdiv2 = mmio_read_32(pllxcfgr7) & RCC_PLLxCFGR7_POSTDIV2_MASK;
+
+	if ((mmio_read_32(pllxcfgr4) & RCC_PLLxCFGR4_BYPASS) != 0U) {
+		dfout = prate;
+	} else {
+		if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
+			dfout = prate;
+		} else {
+			dfout = clk_get_pll_fvco(priv, pll, prate) / (postdiv1 * postdiv2);
+		}
+	}
+
+	return dfout;
+}
+
+static const struct stm32_clk_ops clk_stm32_pll_ops = {
+	.recalc_rate	= clk_stm32_pll_recalc_rate,
+	.enable		= clk_stm32_pll_enable,
+	.disable	= clk_stm32_pll_disable,
+	.is_enabled	= clk_stm32_pll_is_enabled,
+};
+
+#define CLK_PLL(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
+	.binding	= _idx,\
+	.parent		= _parent,\
+	.flags		= (_flags),\
+	.clock_cfg	= &(struct stm32_pll_cfg) {\
+		.pll_id	= _pll_id,\
+	},\
+	.ops		= STM32_PLL_OPS,\
+}
+
+static unsigned long clk_get_pll1_fvco(unsigned long refclk)
+{
+	uintptr_t pll_freq1_reg = A35SSC_BASE + A35_SS_PLL_FREQ1;
+	uint32_t reg, fbdiv, refdiv;
+
+	reg = mmio_read_32(pll_freq1_reg);
+
+	fbdiv = (reg & A35_SS_PLL_FREQ1_FBDIV_MASK) >> A35_SS_PLL_FREQ1_FBDIV_SHIFT;
+	refdiv = (reg & A35_SS_PLL_FREQ1_REFDIV_MASK) >> A35_SS_PLL_FREQ1_REFDIV_SHIFT;
+
+	return (unsigned long)(refclk * fbdiv / refdiv);
+}
+
+static unsigned long clk_stm32_pll1_recalc_rate(struct stm32_clk_priv *priv,
+						int id, unsigned long prate)
+{
+	uintptr_t pll_freq2_reg = A35SSC_BASE + A35_SS_PLL_FREQ2;
+	uint32_t postdiv1, postdiv2;
+	unsigned long dfout;
+
+	postdiv1 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV1_MASK) >>
+		   A35_SS_PLL_FREQ2_POSTDIV1_SHIFT;
+	postdiv2 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV2_MASK) >>
+		   A35_SS_PLL_FREQ2_POSTDIV2_SHIFT;
+
+	if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
+		dfout = prate;
+	} else {
+		dfout = clk_get_pll1_fvco(prate) / (postdiv1 * postdiv2);
+	}
+
+	return dfout;
+}
+
+static const struct stm32_clk_ops clk_stm32_pll1_ops = {
+	.recalc_rate = clk_stm32_pll1_recalc_rate,
+};
+
+#define CLK_PLL1(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
+	.binding	= _idx,\
+	.parent		= _parent,\
+	.flags		= (_flags),\
+	.clock_cfg	= &(struct stm32_pll_cfg) {\
+		.pll_id	= _pll_id,\
+	},\
+	.ops		= STM32_PLL1_OPS,\
+}
+
+struct stm32_clk_flexgen_cfg {
+	uint8_t id;
+};
+
+static unsigned long clk_flexgen_recalc(struct stm32_clk_priv *priv, int idx,
+					unsigned long prate)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint32_t prediv, findiv;
+	uint8_t channel = cfg->id;
+	unsigned long freq = prate;
+
+	prediv = mmio_read_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel)) &
+		RCC_PREDIVxCFGR_PREDIVx_MASK;
+	findiv = mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
+		RCC_FINDIVxCFGR_FINDIVx_MASK;
+
+	if (freq == 0UL) {
+		return 0U;
+	}
+
+	switch (prediv) {
+	case 0x0:
+	case 0x1:
+	case 0x3:
+	case 0x3FF:
+		break;
+
+	default:
+		ERROR("Unsupported PREDIV value (%x)\n", prediv);
+		panic();
+		break;
+	}
+
+	freq /= (prediv + 1U);
+	freq /= (findiv + 1U);
+
+	return freq;
+}
+
+static int clk_flexgen_get_parent(struct stm32_clk_priv *priv, int idx)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uint32_t sel;
+	uint32_t address;
+	uintptr_t rcc_base = priv->base;
+
+	address = RCC_XBAR0CFGR + (cfg->id * 4);
+
+	sel = mmio_read_32(rcc_base + address) & RCC_XBARxCFGR_XBARxSEL_MASK;
+
+	return sel;
+}
+
+static int clk_flexgen_gate_enable(struct stm32_clk_priv *priv, int idx)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	mmio_setbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			RCC_FINDIVxCFGR_FINDIVxEN);
+
+	return 0;
+}
+
+static void clk_flexgen_gate_disable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	mmio_clrbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			RCC_FINDIVxCFGR_FINDIVxEN);
+}
+
+static bool clk_flexgen_gate_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	return !!(mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
+		RCC_FINDIVxCFGR_FINDIVxEN);
+}
+
+static const struct stm32_clk_ops clk_stm32_flexgen_ops = {
+	.recalc_rate = clk_flexgen_recalc,
+	.get_parent = clk_flexgen_get_parent,
+	.enable = clk_flexgen_gate_enable,
+	.disable = clk_flexgen_gate_disable,
+	.is_enabled = clk_flexgen_gate_is_enabled,
+};
+
+#define FLEXGEN(idx, _idx, _flags, _id)[idx] = {\
+	.binding = _idx,\
+	.parent =  MUX(MUX_XBARSEL),\
+	.flags = (_flags),\
+	.clock_cfg	= &(struct stm32_clk_flexgen_cfg) {\
+		.id	= _id,\
+	},\
+	.ops = STM32_FLEXGEN_OPS,\
+}
+
+#define RCC_0_MHZ	UL(0)
+#define RCC_4_MHZ	UL(4000000)
+#define RCC_16_MHZ	UL(16000000)
+
+#ifdef IMAGE_BL2
+static int clk_stm32_osc_msi_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate,
+				      unsigned long prate)
+{
+	uintptr_t address = priv->base + RCC_BDCR;
+	uint32_t mask = RCC_BDCR_MSIFREQSEL;
+	int ret = -1;
+
+	switch (rate) {
+	case RCC_4_MHZ:
+		mmio_clrbits_32(address, mask);
+		ret = 0;
+		break;
+
+	case RCC_16_MHZ:
+		mmio_setbits_32(address, mask);
+		ret = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
+}
+#endif /* IMAGE_BL2 */
+
+static unsigned long clk_stm32_osc_msi_recalc_rate(struct stm32_clk_priv *priv,
+						   int id __unused,
+						   unsigned long prate __unused)
+{
+	uintptr_t address = priv->base + RCC_BDCR;
+
+	if ((mmio_read_32(address) & RCC_BDCR_MSIFREQSEL) == 0U) {
+		return RCC_4_MHZ;
+	} else {
+		return RCC_16_MHZ;
+	}
+}
+
+static const struct stm32_clk_ops clk_stm32_osc_msi_ops = {
+	.recalc_rate	= clk_stm32_osc_msi_recalc_rate,
+	.is_enabled	= clk_stm32_osc_gate_is_enabled,
+	.enable		= clk_stm32_osc_gate_enable,
+	.disable	= clk_stm32_osc_gate_disable,
+	.init		= clk_stm32_osc_init,
+};
+
+#define CLK_OSC_MSI(idx, _idx, _parent, _osc_id) \
+	[(idx)] = (struct clk_stm32){ \
+		.binding	= (_idx),\
+		.parent		= (_parent),\
+		.flags		= CLK_IS_CRITICAL,\
+		.clock_cfg	= &(struct stm32_osc_cfg){\
+			.osc_id = (_osc_id),\
+		},\
+		.ops		= STM32_OSC_MSI_OPS,\
+	}
+
+static const struct stm32_clk_ops clk_stm32_rtc_ops = {
+	.enable = clk_stm32_gate_enable,
+	.disable = clk_stm32_gate_disable,
+	.is_enabled = clk_stm32_gate_is_enabled,
+};
+
+#define CLK_RTC(idx, _binding, _parent, _flags, _gate_id)[idx] = {\
+	.binding = (_binding),\
+	.parent =  (_parent),\
+	.flags = (_flags),\
+	.clock_cfg	= &(struct clk_stm32_gate_cfg) {\
+		.id	= (_gate_id),\
+	},\
+	.ops = STM32_RTC_OPS,\
+}
+
+enum {
+	STM32_PLL_OPS = STM32_LAST_OPS,
+	STM32_PLL1_OPS,
+	STM32_FLEXGEN_OPS,
+	STM32_OSC_MSI_OPS,
+	STM32_RTC_OPS,
+
+	MP25_LAST_OPS
+};
+
+static const struct stm32_clk_ops *ops_array_mp25[MP25_LAST_OPS] = {
+	[NO_OPS] =  NULL,
+	[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
+	[GATE_OPS] = &clk_gate_ops,
+	[STM32_MUX_OPS] = &clk_mux_ops,
+	[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
+	[STM32_GATE_OPS] = &clk_stm32_gate_ops,
+	[STM32_TIMER_OPS] = &clk_timer_ops,
+	[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
+	[STM32_OSC_OPS] = &clk_stm32_osc_ops,
+	[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
+
+	[STM32_PLL_OPS] = &clk_stm32_pll_ops,
+	[STM32_PLL1_OPS] = &clk_stm32_pll1_ops,
+	[STM32_FLEXGEN_OPS] = &clk_stm32_flexgen_ops,
+	[STM32_OSC_MSI_OPS] = &clk_stm32_osc_msi_ops,
+	[STM32_RTC_OPS] = &clk_stm32_rtc_ops
+};
+
+static const struct clk_stm32 stm32mp25_clk[CK_LAST] = {
+	CLK_FIXED_RATE(_CK_0_MHZ, _NO_ID, RCC_0_MHZ),
+
+	/* ROOT CLOCKS */
+	CLK_OSC(_CK_HSE, HSE_CK, CLK_IS_ROOT, OSC_HSE),
+	CLK_OSC(_CK_LSE, LSE_CK, CLK_IS_ROOT, OSC_LSE),
+	CLK_OSC(_CK_HSI, HSI_CK, CLK_IS_ROOT, OSC_HSI),
+	CLK_OSC(_CK_LSI, LSI_CK, CLK_IS_ROOT, OSC_LSI),
+	CLK_OSC_MSI(_CK_MSI, MSI_CK, CLK_IS_ROOT, OSC_MSI),
+
+	CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
+	CLK_OSC_FIXED(_SPDIFSYMB, _NO_ID, CLK_IS_ROOT, OSC_SPDIFSYMB),
+
+	STM32_DIV(_CK_HSE_RTC, _NO_ID, _CK_HSE, 0, DIV_RTC),
+
+	CLK_RTC(_CK_RTCCK, RTC_CK, MUX(MUX_RTC), 0, GATE_RTCCK),
+
+	CLK_PLL1(_CK_PLL1, PLL1_CK, MUX(MUX_MUXSEL5), _PLL1, 0),
+
+	CLK_PLL(_CK_PLL2, PLL2_CK, MUX(MUX_MUXSEL6), _PLL2, 0),
+	CLK_PLL(_CK_PLL3, PLL3_CK, MUX(MUX_MUXSEL7), _PLL3, 0),
+	CLK_PLL(_CK_PLL4, PLL4_CK, MUX(MUX_MUXSEL0), _PLL4, 0),
+	CLK_PLL(_CK_PLL5, PLL5_CK, MUX(MUX_MUXSEL1), _PLL5, 0),
+	CLK_PLL(_CK_PLL6, PLL6_CK, MUX(MUX_MUXSEL2), _PLL6, 0),
+	CLK_PLL(_CK_PLL7, PLL7_CK, MUX(MUX_MUXSEL3), _PLL7, 0),
+	CLK_PLL(_CK_PLL8, PLL8_CK, MUX(MUX_MUXSEL4), _PLL8, 0),
+
+	FLEXGEN(_CK_ICN_HS_MCU,	CK_ICN_HS_MCU, CLK_IS_CRITICAL, 0),
+	FLEXGEN(_CK_ICN_SDMMC, CK_ICN_SDMMC, CLK_IS_CRITICAL, 1),
+	FLEXGEN(_CK_ICN_DDR, CK_ICN_DDR, CLK_IS_CRITICAL, 2),
+	FLEXGEN(_CK_ICN_HSL, CK_ICN_HSL, CLK_IS_CRITICAL, 4),
+	FLEXGEN(_CK_ICN_NIC, CK_ICN_NIC, CLK_IS_CRITICAL, 5),
+
+	STM32_DIV(_CK_ICN_LS_MCU, CK_ICN_LS_MCU, _CK_ICN_HS_MCU, 0, DIV_LSMCU),
+
+	FLEXGEN(_CK_FLEXGEN_07, CK_FLEXGEN_07, 0, 7),
+	FLEXGEN(_CK_FLEXGEN_08, CK_FLEXGEN_08, 0, 8),
+	FLEXGEN(_CK_FLEXGEN_09, CK_FLEXGEN_09, 0, 9),
+	FLEXGEN(_CK_FLEXGEN_10, CK_FLEXGEN_10, 0, 10),
+	FLEXGEN(_CK_FLEXGEN_11, CK_FLEXGEN_11, 0, 11),
+	FLEXGEN(_CK_FLEXGEN_12, CK_FLEXGEN_12, 0, 12),
+	FLEXGEN(_CK_FLEXGEN_13, CK_FLEXGEN_13, 0, 13),
+	FLEXGEN(_CK_FLEXGEN_14, CK_FLEXGEN_14, 0, 14),
+	FLEXGEN(_CK_FLEXGEN_15, CK_FLEXGEN_15, 0, 15),
+	FLEXGEN(_CK_FLEXGEN_16, CK_FLEXGEN_16, 0, 16),
+	FLEXGEN(_CK_FLEXGEN_17, CK_FLEXGEN_17, 0, 17),
+	FLEXGEN(_CK_FLEXGEN_18, CK_FLEXGEN_18, 0, 18),
+	FLEXGEN(_CK_FLEXGEN_19, CK_FLEXGEN_19, 0, 19),
+	FLEXGEN(_CK_FLEXGEN_20, CK_FLEXGEN_20, 0, 20),
+	FLEXGEN(_CK_FLEXGEN_21, CK_FLEXGEN_21, 0, 21),
+	FLEXGEN(_CK_FLEXGEN_22, CK_FLEXGEN_22, 0, 22),
+	FLEXGEN(_CK_FLEXGEN_23, CK_FLEXGEN_23, 0, 23),
+	FLEXGEN(_CK_FLEXGEN_24, CK_FLEXGEN_24, 0, 24),
+	FLEXGEN(_CK_FLEXGEN_25, CK_FLEXGEN_25, 0, 25),
+	FLEXGEN(_CK_FLEXGEN_26, CK_FLEXGEN_26, 0, 26),
+	FLEXGEN(_CK_FLEXGEN_27, CK_FLEXGEN_27, 0, 27),
+	FLEXGEN(_CK_FLEXGEN_28, CK_FLEXGEN_28, 0, 28),
+	FLEXGEN(_CK_FLEXGEN_29, CK_FLEXGEN_29, 0, 29),
+	FLEXGEN(_CK_FLEXGEN_30, CK_FLEXGEN_30, 0, 30),
+	FLEXGEN(_CK_FLEXGEN_31, CK_FLEXGEN_31, 0, 31),
+	FLEXGEN(_CK_FLEXGEN_32, CK_FLEXGEN_32, 0, 32),
+	FLEXGEN(_CK_FLEXGEN_33, CK_FLEXGEN_33, 0, 33),
+	FLEXGEN(_CK_FLEXGEN_34, CK_FLEXGEN_34, 0, 34),
+	FLEXGEN(_CK_FLEXGEN_35, CK_FLEXGEN_35, 0, 35),
+	FLEXGEN(_CK_FLEXGEN_36, CK_FLEXGEN_36, 0, 36),
+	FLEXGEN(_CK_FLEXGEN_37, CK_FLEXGEN_37, 0, 37),
+	FLEXGEN(_CK_FLEXGEN_38, CK_FLEXGEN_38, 0, 38),
+	FLEXGEN(_CK_FLEXGEN_39, CK_FLEXGEN_39, 0, 39),
+	FLEXGEN(_CK_FLEXGEN_40, CK_FLEXGEN_40, 0, 40),
+	FLEXGEN(_CK_FLEXGEN_41, CK_FLEXGEN_41, 0, 41),
+	FLEXGEN(_CK_FLEXGEN_42, CK_FLEXGEN_42, 0, 42),
+	FLEXGEN(_CK_FLEXGEN_43, CK_FLEXGEN_43, 0, 43),
+	FLEXGEN(_CK_FLEXGEN_44, CK_FLEXGEN_44, 0, 44),
+	FLEXGEN(_CK_FLEXGEN_45, CK_FLEXGEN_45, 0, 45),
+	FLEXGEN(_CK_FLEXGEN_46, CK_FLEXGEN_46, 0, 46),
+	FLEXGEN(_CK_FLEXGEN_47, CK_FLEXGEN_47, 0, 47),
+	FLEXGEN(_CK_FLEXGEN_48, CK_FLEXGEN_48, 0, 48),
+	FLEXGEN(_CK_FLEXGEN_49, CK_FLEXGEN_49, 0, 49),
+	FLEXGEN(_CK_FLEXGEN_50, CK_FLEXGEN_50, 0, 50),
+	FLEXGEN(_CK_FLEXGEN_51, CK_FLEXGEN_51, 0, 51),
+	FLEXGEN(_CK_FLEXGEN_52, CK_FLEXGEN_52, 0, 52),
+	FLEXGEN(_CK_FLEXGEN_53, CK_FLEXGEN_53, 0, 53),
+	FLEXGEN(_CK_FLEXGEN_54, CK_FLEXGEN_54, 0, 54),
+	FLEXGEN(_CK_FLEXGEN_55, CK_FLEXGEN_55, 0, 55),
+	FLEXGEN(_CK_FLEXGEN_56, CK_FLEXGEN_56, 0, 56),
+	FLEXGEN(_CK_FLEXGEN_57, CK_FLEXGEN_57, 0, 57),
+	FLEXGEN(_CK_FLEXGEN_58, CK_FLEXGEN_58, 0, 58),
+	FLEXGEN(_CK_FLEXGEN_59, CK_FLEXGEN_59, 0, 59),
+	FLEXGEN(_CK_FLEXGEN_60, CK_FLEXGEN_60, 0, 60),
+	FLEXGEN(_CK_FLEXGEN_61, CK_FLEXGEN_61, 0, 61),
+	FLEXGEN(_CK_FLEXGEN_62, CK_FLEXGEN_62, 0, 62),
+	FLEXGEN(_CK_FLEXGEN_63, CK_FLEXGEN_63, 0, 63),
+
+	STM32_DIV(_CK_ICN_APB1, CK_ICN_APB1, _CK_ICN_LS_MCU, 0, DIV_APB1),
+	STM32_DIV(_CK_ICN_APB2, CK_ICN_APB2, _CK_ICN_LS_MCU, 0, DIV_APB2),
+	STM32_DIV(_CK_ICN_APB3, CK_ICN_APB3, _CK_ICN_LS_MCU, 0, DIV_APB3),
+	STM32_DIV(_CK_ICN_APB4, CK_ICN_APB4, _CK_ICN_LS_MCU, 0, DIV_APB4),
+	STM32_DIV(_CK_ICN_APBDBG, CK_ICN_APBDBG, _CK_ICN_LS_MCU, 0, DIV_APBDBG),
+
+	/* KERNEL CLOCK */
+	STM32_GATE(_CK_SYSRAM, CK_BUS_SYSRAM, _CK_ICN_HS_MCU, 0, GATE_SYSRAM),
+	STM32_GATE(_CK_RETRAM, CK_BUS_RETRAM, _CK_ICN_HS_MCU, 0, GATE_RETRAM),
+	STM32_GATE(_CK_SRAM1, CK_BUS_SRAM1, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM1),
+	STM32_GATE(_CK_SRAM2, CK_BUS_SRAM2, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM2),
+
+	STM32_GATE(_CK_DDRPHYC, CK_BUS_DDRPHYC, _CK_ICN_LS_MCU, 0, GATE_DDRPHYC),
+	STM32_GATE(_CK_SYSCPU1, CK_BUS_SYSCPU1, _CK_ICN_LS_MCU, 0, GATE_SYSCPU1),
+	STM32_GATE(_CK_CRC, CK_BUS_CRC, _CK_ICN_LS_MCU, 0, GATE_CRC),
+	STM32_GATE(_CK_OSPIIOM, CK_BUS_OSPIIOM, _CK_ICN_LS_MCU, 0, GATE_OSPIIOM),
+	STM32_GATE(_CK_BKPSRAM, CK_BUS_BKPSRAM, _CK_ICN_LS_MCU, 0, GATE_BKPSRAM),
+	STM32_GATE(_CK_HASH, CK_BUS_HASH, _CK_ICN_LS_MCU, 0, GATE_HASH),
+	STM32_GATE(_CK_RNG, CK_BUS_RNG, _CK_ICN_LS_MCU, 0, GATE_RNG),
+	STM32_GATE(_CK_CRYP1, CK_BUS_CRYP1, _CK_ICN_LS_MCU, 0, GATE_CRYP1),
+	STM32_GATE(_CK_CRYP2, CK_BUS_CRYP2, _CK_ICN_LS_MCU, 0, GATE_CRYP2),
+	STM32_GATE(_CK_SAES, CK_BUS_SAES, _CK_ICN_LS_MCU, 0, GATE_SAES),
+	STM32_GATE(_CK_PKA, CK_BUS_PKA, _CK_ICN_LS_MCU, 0, GATE_PKA),
+
+	STM32_GATE(_CK_GPIOA, CK_BUS_GPIOA, _CK_ICN_LS_MCU, 0, GATE_GPIOA),
+	STM32_GATE(_CK_GPIOB, CK_BUS_GPIOB, _CK_ICN_LS_MCU, 0, GATE_GPIOB),
+	STM32_GATE(_CK_GPIOC, CK_BUS_GPIOC, _CK_ICN_LS_MCU, 0, GATE_GPIOC),
+	STM32_GATE(_CK_GPIOD, CK_BUS_GPIOD, _CK_ICN_LS_MCU, 0, GATE_GPIOD),
+	STM32_GATE(_CK_GPIOE, CK_BUS_GPIOE, _CK_ICN_LS_MCU, 0, GATE_GPIOE),
+	STM32_GATE(_CK_GPIOF, CK_BUS_GPIOF, _CK_ICN_LS_MCU, 0, GATE_GPIOF),
+	STM32_GATE(_CK_GPIOG, CK_BUS_GPIOG, _CK_ICN_LS_MCU, 0, GATE_GPIOG),
+	STM32_GATE(_CK_GPIOH, CK_BUS_GPIOH, _CK_ICN_LS_MCU, 0, GATE_GPIOH),
+	STM32_GATE(_CK_GPIOI, CK_BUS_GPIOI, _CK_ICN_LS_MCU, 0, GATE_GPIOI),
+	STM32_GATE(_CK_GPIOJ, CK_BUS_GPIOJ, _CK_ICN_LS_MCU, 0, GATE_GPIOJ),
+	STM32_GATE(_CK_GPIOK, CK_BUS_GPIOK, _CK_ICN_LS_MCU, 0, GATE_GPIOK),
+	STM32_GATE(_CK_GPIOZ, CK_BUS_GPIOZ, _CK_ICN_LS_MCU, 0, GATE_GPIOZ),
+	STM32_GATE(_CK_RTC, CK_BUS_RTC, _CK_ICN_LS_MCU, 0, GATE_RTC),
+
+	STM32_GATE(_CK_DDRCP, CK_BUS_DDR, _CK_ICN_DDR, 0, GATE_DDRCP),
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	STM32_GATE(_CK_USB2OHCI, CK_BUS_USB2OHCI, _CK_ICN_HSL, 0, GATE_USB2OHCI),
+	STM32_GATE(_CK_USB2EHCI, CK_BUS_USB2EHCI, _CK_ICN_HSL, 0, GATE_USB2EHCI),
+
+	STM32_GATE(_CK_USB3DR, CK_BUS_USB3DR, _CK_ICN_HSL, 0, GATE_USB3DR),
+
+	STM32_GATE(_CK_BSEC, CK_BUS_BSEC, _CK_ICN_APB3, 0, GATE_BSEC),
+	STM32_GATE(_CK_IWDG1, CK_BUS_IWDG1, _CK_ICN_APB3, 0, GATE_IWDG1),
+	STM32_GATE(_CK_IWDG2, CK_BUS_IWDG2, _CK_ICN_APB3, 0, GATE_IWDG2),
+
+	STM32_GATE(_CK_DDRCAPB, CK_BUS_DDRC, _CK_ICN_APB4, 0, GATE_DDRCAPB),
+	STM32_GATE(_CK_DDR, CK_BUS_DDRCFG, _CK_ICN_APB4, 0, GATE_DDR),
+
+	STM32_GATE(_CK_USART2, CK_KER_USART2, _CK_FLEXGEN_08, 0, GATE_USART2),
+	STM32_GATE(_CK_UART4, CK_KER_UART4, _CK_FLEXGEN_08, 0, GATE_UART4),
+	STM32_GATE(_CK_USART3, CK_KER_USART3, _CK_FLEXGEN_09, 0, GATE_USART3),
+	STM32_GATE(_CK_UART5, CK_KER_UART5, _CK_FLEXGEN_09, 0, GATE_UART5),
+	STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_12, 0, GATE_I2C1),
+	STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_12, 0, GATE_I2C2),
+	STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_13, 0, GATE_I2C3),
+	STM32_GATE(_CK_I2C5, CK_KER_I2C5, _CK_FLEXGEN_13, 0, GATE_I2C5),
+	STM32_GATE(_CK_I2C4, CK_KER_I2C4, _CK_FLEXGEN_14, 0, GATE_I2C4),
+	STM32_GATE(_CK_I2C6, CK_KER_I2C6, _CK_FLEXGEN_14, 0, GATE_I2C6),
+	STM32_GATE(_CK_I2C7, CK_KER_I2C7, _CK_FLEXGEN_15, 0, GATE_I2C7),
+	STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_19, 0, GATE_USART1),
+	STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_20, 0, GATE_USART6),
+	STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_21, 0, GATE_UART7),
+	STM32_GATE(_CK_UART8, CK_KER_UART8, _CK_FLEXGEN_21, 0, GATE_UART8),
+	STM32_GATE(_CK_UART9, CK_KER_UART9, _CK_FLEXGEN_22, 0, GATE_UART9),
+	STM32_GATE(_CK_STGEN, CK_KER_STGEN, _CK_FLEXGEN_33, 0, GATE_STGEN),
+	STM32_GATE(_CK_USB3PCIEPHY, CK_KER_USB3PCIEPHY, _CK_FLEXGEN_34, 0, GATE_USB3PCIEPHY),
+	STM32_GATE(_CK_USBTC, CK_KER_USBTC, _CK_FLEXGEN_35, 0, GATE_USBTC),
+	STM32_GATE(_CK_I2C8, CK_KER_I2C8, _CK_FLEXGEN_38, 0, GATE_I2C8),
+	STM32_GATE(_CK_OSPI1, CK_KER_OSPI1, _CK_FLEXGEN_48, 0, GATE_OSPI1),
+	STM32_GATE(_CK_OSPI2, CK_KER_OSPI2, _CK_FLEXGEN_49, 0, GATE_OSPI2),
+	STM32_GATE(_CK_FMC, CK_KER_FMC, _CK_FLEXGEN_50, 0, GATE_FMC),
+	STM32_GATE(_CK_SDMMC1, CK_KER_SDMMC1, _CK_FLEXGEN_51, 0, GATE_SDMMC1),
+	STM32_GATE(_CK_SDMMC2, CK_KER_SDMMC2, _CK_FLEXGEN_52, 0, GATE_SDMMC2),
+	STM32_GATE(_CK_USB2PHY1, CK_KER_USB2PHY1, _CK_FLEXGEN_57, 0, GATE_USB2PHY1),
+	STM32_GATE(_CK_USB2PHY2, CK_KER_USB2PHY2, _CK_FLEXGEN_58, 0, GATE_USB2PHY2),
+};
+
+enum clksrc_id {
+	CLKSRC_CA35SS,
+	CLKSRC_PLL1,
+	CLKSRC_PLL2,
+	CLKSRC_PLL3,
+	CLKSRC_PLL4,
+	CLKSRC_PLL5,
+	CLKSRC_PLL6,
+	CLKSRC_PLL7,
+	CLKSRC_PLL8,
+	CLKSRC_XBAR_CHANNEL0,
+	CLKSRC_XBAR_CHANNEL1,
+	CLKSRC_XBAR_CHANNEL2,
+	CLKSRC_XBAR_CHANNEL3,
+	CLKSRC_XBAR_CHANNEL4,
+	CLKSRC_XBAR_CHANNEL5,
+	CLKSRC_XBAR_CHANNEL6,
+	CLKSRC_XBAR_CHANNEL7,
+	CLKSRC_XBAR_CHANNEL8,
+	CLKSRC_XBAR_CHANNEL9,
+	CLKSRC_XBAR_CHANNEL10,
+	CLKSRC_XBAR_CHANNEL11,
+	CLKSRC_XBAR_CHANNEL12,
+	CLKSRC_XBAR_CHANNEL13,
+	CLKSRC_XBAR_CHANNEL14,
+	CLKSRC_XBAR_CHANNEL15,
+	CLKSRC_XBAR_CHANNEL16,
+	CLKSRC_XBAR_CHANNEL17,
+	CLKSRC_XBAR_CHANNEL18,
+	CLKSRC_XBAR_CHANNEL19,
+	CLKSRC_XBAR_CHANNEL20,
+	CLKSRC_XBAR_CHANNEL21,
+	CLKSRC_XBAR_CHANNEL22,
+	CLKSRC_XBAR_CHANNEL23,
+	CLKSRC_XBAR_CHANNEL24,
+	CLKSRC_XBAR_CHANNEL25,
+	CLKSRC_XBAR_CHANNEL26,
+	CLKSRC_XBAR_CHANNEL27,
+	CLKSRC_XBAR_CHANNEL28,
+	CLKSRC_XBAR_CHANNEL29,
+	CLKSRC_XBAR_CHANNEL30,
+	CLKSRC_XBAR_CHANNEL31,
+	CLKSRC_XBAR_CHANNEL32,
+	CLKSRC_XBAR_CHANNEL33,
+	CLKSRC_XBAR_CHANNEL34,
+	CLKSRC_XBAR_CHANNEL35,
+	CLKSRC_XBAR_CHANNEL36,
+	CLKSRC_XBAR_CHANNEL37,
+	CLKSRC_XBAR_CHANNEL38,
+	CLKSRC_XBAR_CHANNEL39,
+	CLKSRC_XBAR_CHANNEL40,
+	CLKSRC_XBAR_CHANNEL41,
+	CLKSRC_XBAR_CHANNEL42,
+	CLKSRC_XBAR_CHANNEL43,
+	CLKSRC_XBAR_CHANNEL44,
+	CLKSRC_XBAR_CHANNEL45,
+	CLKSRC_XBAR_CHANNEL46,
+	CLKSRC_XBAR_CHANNEL47,
+	CLKSRC_XBAR_CHANNEL48,
+	CLKSRC_XBAR_CHANNEL49,
+	CLKSRC_XBAR_CHANNEL50,
+	CLKSRC_XBAR_CHANNEL51,
+	CLKSRC_XBAR_CHANNEL52,
+	CLKSRC_XBAR_CHANNEL53,
+	CLKSRC_XBAR_CHANNEL54,
+	CLKSRC_XBAR_CHANNEL55,
+	CLKSRC_XBAR_CHANNEL56,
+	CLKSRC_XBAR_CHANNEL57,
+	CLKSRC_XBAR_CHANNEL58,
+	CLKSRC_XBAR_CHANNEL59,
+	CLKSRC_XBAR_CHANNEL60,
+	CLKSRC_XBAR_CHANNEL61,
+	CLKSRC_XBAR_CHANNEL62,
+	CLKSRC_XBAR_CHANNEL63,
+	CLKSRC_RTC,
+	CLKSRC_MCO1,
+	CLKSRC_MCO2,
+	CLKSRC_NB
+};
+
+static void stm32mp2_a35_ss_on_hsi(void)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+	uint64_t timeout;
+
+	if ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) ==
+	    A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
+		/* Nothing to do, clock source is already set on bypass clock */
+		return;
+	}
+
+	mmio_setbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) !=
+	       A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Cannot switch A35 to bypass clock\n");
+			panic();
+		}
+	}
+
+	mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
+}
+
+#ifdef IMAGE_BL2
+static void stm32mp2_clk_muxsel_on_hsi(struct stm32_clk_priv *priv)
+{
+	mmio_clrbits_32(priv->base + RCC_MUXSELCFGR,
+			RCC_MUXSELCFGR_MUXSEL0_MASK |
+			RCC_MUXSELCFGR_MUXSEL1_MASK |
+			RCC_MUXSELCFGR_MUXSEL2_MASK |
+			RCC_MUXSELCFGR_MUXSEL3_MASK |
+			RCC_MUXSELCFGR_MUXSEL4_MASK |
+			RCC_MUXSELCFGR_MUXSEL5_MASK |
+			RCC_MUXSELCFGR_MUXSEL6_MASK |
+			RCC_MUXSELCFGR_MUXSEL7_MASK);
+}
+
+static void stm32mp2_clk_xbar_on_hsi(struct stm32_clk_priv *priv)
+{
+	uintptr_t xbar0cfgr = priv->base + RCC_XBAR0CFGR;
+	uint32_t i;
+
+	for (i = 0; i < XBAR_CHANNEL_NB; i++) {
+		mmio_clrsetbits_32(xbar0cfgr + (0x4 * i),
+				   RCC_XBAR0CFGR_XBAR0SEL_MASK,
+				   XBAR_SRC_HSI);
+	}
+}
+
+static int stm32mp2_a35_pll1_start(void)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+	uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
+
+	/* Wait PLL lock */
+	while ((mmio_read_32(pll_enable_reg) & A35_SS_PLL_ENABLE_LOCKP) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("PLL1 start failed @ 0x%lx: 0x%x\n",
+				    pll_enable_reg, mmio_read_32(pll_enable_reg));
+			return -ETIMEDOUT;
+		}
+	}
+
+	/* De-assert reset on PLL output clock path */
+	mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
+
+	/* Switch CPU clock to PLL clock */
+	mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
+
+	/* Wait for clock change acknowledge */
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("CA35SS switch to PLL1 failed @ 0x%lx: 0x%x\n",
+				    chgclkreq_reg, mmio_read_32(chgclkreq_reg));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32mp2_a35_pll1_config(uint32_t fbdiv, uint32_t refdiv, uint32_t postdiv1,
+				     uint32_t postdiv2)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_freq1_reg = a35_ss_address + A35_SS_PLL_FREQ1;
+	uintptr_t pll_freq2_reg = a35_ss_address + A35_SS_PLL_FREQ2;
+
+	mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_REFDIV_MASK,
+			   (refdiv << A35_SS_PLL_FREQ1_REFDIV_SHIFT) &
+			   A35_SS_PLL_FREQ1_REFDIV_MASK);
+
+	mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_FBDIV_MASK,
+			   (fbdiv << A35_SS_PLL_FREQ1_FBDIV_SHIFT) &
+			   A35_SS_PLL_FREQ1_FBDIV_MASK);
+
+	mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV1_MASK,
+			   (postdiv1 << A35_SS_PLL_FREQ2_POSTDIV1_SHIFT) &
+			   A35_SS_PLL_FREQ2_POSTDIV1_MASK);
+
+	mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV2_MASK,
+			   (postdiv2 << A35_SS_PLL_FREQ2_POSTDIV2_SHIFT) &
+			   A35_SS_PLL_FREQ2_POSTDIV2_MASK);
+}
+
+static int clk_stm32_pll_config_output(struct stm32_clk_priv *priv,
+				       const struct stm32_clk_pll *pll,
+				       uint32_t *pllcfg,
+				       uint32_t fracv)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
+	uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
+	unsigned long refclk;
+
+	refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
+
+	if (fracv == 0U) {
+		/* PLL in integer mode */
+
+		/*
+		 * No need to check max clock, as oscillator reference clocks
+		 * will always be less than 1.2GHz
+		 */
+		if (refclk < PLL_REFCLK_MIN) {
+			panic();
+		}
+
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK);
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+		mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
+	} else {
+		/* PLL in frac mode */
+
+		/*
+		 * No need to check max clock, as oscillator reference clocks
+		 * will always be less than 1.2GHz
+		 */
+		if (refclk < PLL_FRAC_REFCLK_MIN) {
+			panic();
+		}
+
+		mmio_clrsetbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK,
+				   fracv & RCC_PLLxCFGR3_FRACIN_MASK);
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+	}
+
+	assert(pllcfg[REFDIV] != 0U);
+
+	mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FBDIV_MASK,
+			   (pllcfg[FBDIV] << RCC_PLLxCFGR2_FBDIV_SHIFT) &
+			   RCC_PLLxCFGR2_FBDIV_MASK);
+	mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FREFDIV_MASK,
+			   pllcfg[REFDIV] & RCC_PLLxCFGR2_FREFDIV_MASK);
+	mmio_clrsetbits_32(pllxcfgr6, RCC_PLLxCFGR6_POSTDIV1_MASK,
+			   pllcfg[POSTDIV1] & RCC_PLLxCFGR6_POSTDIV1_MASK);
+	mmio_clrsetbits_32(pllxcfgr7, RCC_PLLxCFGR7_POSTDIV2_MASK,
+			   pllcfg[POSTDIV2] & RCC_PLLxCFGR7_POSTDIV2_MASK);
+
+	if ((pllcfg[POSTDIV1] == 0U) || (pllcfg[POSTDIV2] == 0U)) {
+		/* Bypass mode */
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
+	} else {
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
+	}
+
+	return 0;
+}
+
+static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
+				     const struct stm32_clk_pll *pll,
+				     uint32_t *csg)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr5 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR5;
+
+
+	mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_DIVVAL_MASK,
+			   csg[DIVVAL] & RCC_PLLxCFGR5_DIVVAL_MASK);
+	mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_SPREAD_MASK,
+			   (csg[SPREAD] << RCC_PLLxCFGR5_SPREAD_SHIFT) &
+			   RCC_PLLxCFGR5_SPREAD_MASK);
+
+	if (csg[DOWNSPREAD] != 0) {
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
+	} else {
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
+	}
+
+	mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+
+	mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+	udelay(1);
+
+	mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+	mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data);
+
+static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_clk_platdata *pdata = priv->pdata;
+
+	return  &pdata->pll[pll_idx];
+}
+
+static int _clk_stm32_pll1_init(struct stm32_clk_priv *priv, int pll_idx,
+				struct stm32_pll_dt_cfg *pll_conf)
+{
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
+	unsigned long refclk;
+	int ret = 0;
+
+	stm32mp2_a35_ss_on_hsi();
+
+	ret = stm32_clk_configure_mux(priv, pll_conf->src);
+	if (ret != 0) {
+		panic();
+	}
+
+	refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
+
+	/*
+	 * No need to check max clock, as oscillator reference clocks will
+	 * always be less than 1.2 GHz
+	 */
+	if (refclk < PLL_REFCLK_MIN) {
+		EARLY_ERROR("%s: %d\n", __func__, __LINE__);
+		panic();
+	}
+
+	stm32mp2_a35_pll1_config(pll_conf->cfg[FBDIV], pll_conf->cfg[REFDIV],
+				 pll_conf->cfg[POSTDIV1], pll_conf->cfg[POSTDIV2]);
+
+	ret = stm32mp2_a35_pll1_start();
+	if (ret != 0) {
+		panic();
+	}
+
+	return 0;
+}
+
+static int clk_stm32_pll_wait_mux_ready(struct stm32_clk_priv *priv,
+					const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_CKREFST) !=
+	       RCC_PLLxCFGR1_CKREFST) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("PLL%d ref clock not started\n", pll->clk_id - _CK_PLL1 + 1);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
+			       struct stm32_pll_dt_cfg *pll_conf)
+{
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	bool spread_spectrum = false;
+	int ret = 0;
+
+	_clk_stm32_pll_disable(priv, pll);
+
+	ret = stm32_clk_configure_mux(priv, pll_conf->src);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = clk_stm32_pll_wait_mux_ready(priv, pll);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = clk_stm32_pll_config_output(priv, pll, pll_conf->cfg, pll_conf->frac);
+	if (ret != 0) {
+		panic();
+	}
+
+	if (pll_conf->csg_enabled) {
+		clk_stm32_pll_config_csg(priv, pll, pll_conf->csg);
+		spread_spectrum = true;
+	}
+
+	_clk_stm32_pll_enable(priv, pll);
+
+	if (spread_spectrum) {
+		mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
+	}
+
+	return 0;
+}
+
+static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
+{
+	struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
+
+	if (pll_conf->enabled) {
+		if (pll_idx == _PLL1) {
+			return _clk_stm32_pll1_init(priv, pll_idx, pll_conf);
+		} else  {
+			return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp2_clk_pll_configure(struct stm32_clk_priv *priv)
+{
+	enum pll_id i;
+	int err;
+
+	for (i = _PLL1; i < _PLL_NB; i++) {
+		err = clk_stm32_pll_init(priv, i);
+		if (err) {
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_predivsr(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t previvsr;
+	uint32_t channel_bit;
+	uint64_t timeout;
+
+	if (channel < __WORD_BIT) {
+		previvsr = rcc_base + RCC_PREDIVSR1;
+		channel_bit = BIT(channel);
+	} else {
+		previvsr = rcc_base + RCC_PREDIVSR2;
+		channel_bit = BIT(channel - __WORD_BIT);
+	}
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(previvsr) & channel_bit) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Pre divider status: %x\n",
+			      mmio_read_32(previvsr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_findivsr(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t finvivsr;
+	uint32_t channel_bit;
+	uint64_t timeout;
+
+	if (channel < __WORD_BIT) {
+		finvivsr = rcc_base + RCC_FINDIVSR1;
+		channel_bit = BIT(channel);
+	} else {
+		finvivsr = rcc_base + RCC_FINDIVSR2;
+		channel_bit = BIT(channel - __WORD_BIT);
+	}
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(finvivsr) & channel_bit) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Final divider status: %x\n",
+			      mmio_read_32(finvivsr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_xbar_sts(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t xbar_cfgr = rcc_base + RCC_XBAR0CFGR + (0x4U * channel);
+	uint64_t timeout;
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(xbar_cfgr) & RCC_XBAR0CFGR_XBAR0STS) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("XBAR%uCFGR: %x\n", channel,
+			      mmio_read_32(xbar_cfgr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void flexclkgen_config_channel(uint16_t channel, unsigned int clk_src,
+				      unsigned int prediv, unsigned int findiv)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+
+	if (wait_predivsr(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel),
+			   RCC_PREDIV0CFGR_PREDIV0_MASK,
+			   prediv);
+
+	if (wait_predivsr(channel) != 0) {
+		panic();
+	}
+
+	if (wait_findivsr(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			   RCC_FINDIV0CFGR_FINDIV0_MASK,
+			   findiv);
+
+	if (wait_findivsr(channel) != 0) {
+		panic();
+	}
+
+	if (wait_xbar_sts(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
+			   RCC_XBARxCFGR_XBARxSEL_MASK,
+			   clk_src);
+	mmio_setbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
+			RCC_XBARxCFGR_XBARxEN);
+
+	if (wait_xbar_sts(channel) != 0) {
+		panic();
+	}
+}
+
+static int stm32mp2_clk_flexgen_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nflexgen; i++) {
+		uint32_t val = pdata->flexgen[i];
+		uint32_t cmd, cmd_data;
+		unsigned int channel, clk_src, pdiv, fdiv;
+
+		cmd = (val & CMD_MASK) >> CMD_SHIFT;
+		cmd_data = val & ~CMD_MASK;
+
+		if (cmd != CMD_FLEXGEN) {
+			continue;
+		}
+
+		channel = (cmd_data & FLEX_ID_MASK) >> FLEX_ID_SHIFT;
+		clk_src = (cmd_data & FLEX_SEL_MASK) >> FLEX_SEL_SHIFT;
+		pdiv = (cmd_data & FLEX_PDIV_MASK) >> FLEX_PDIV_SHIFT;
+		fdiv = (cmd_data & FLEX_FDIV_MASK) >> FLEX_FDIV_SHIFT;
+
+		switch (channel) {
+		case 33U: /* STGEN */
+			break;
+
+		default:
+			flexclkgen_config_channel(channel, clk_src, pdiv, fdiv);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
+	bool digbyp =  osci->digbyp;
+	bool bypass = osci->bypass;
+	bool css = osci->css;
+
+	if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
+		return;
+	}
+
+	clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
+
+	_clk_stm32_enable(priv, _CK_HSE);
+
+	clk_oscillator_set_css(priv, _CK_HSE, css);
+}
+
+static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
+{
+	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
+	bool digbyp =  osci->digbyp;
+	bool bypass = osci->bypass;
+	uint8_t drive = osci->drive;
+
+	if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
+		return;
+	}
+
+	/* Do not reconfigure LSE if already enabled */
+	if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
+		return;
+	}
+
+	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
+
+	clk_oscillator_set_drive(priv, _CK_LSE, drive);
+
+	_clk_stm32_gate_enable(priv, osc_data->gate_id);
+}
+
+static int stm32mp2_clk_switch_to_hsi(struct stm32_clk_priv *priv)
+{
+	stm32mp2_a35_ss_on_hsi();
+	stm32mp2_clk_muxsel_on_hsi(priv);
+	stm32mp2_clk_xbar_on_hsi(priv);
+
+	return 0;
+}
+
+static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
+{
+	int ret = 0;
+
+	if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
+		ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
+	}
+
+	return ret;
+}
+
+static void stm32_enable_oscillator_msi(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_MSI];
+	int err;
+
+	err = clk_stm32_osc_msi_set_rate(priv, _CK_MSI, osci->freq, 0);
+	if (err != 0) {
+		EARLY_ERROR("Invalid rate %lu MHz for MSI ! (4 or 16 only)\n",
+			    osci->freq / 1000000U);
+		panic();
+	}
+
+	_clk_stm32_enable(priv, _CK_MSI);
+}
+
+static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
+{
+	stm32_enable_oscillator_hse(priv);
+	stm32_enable_oscillator_lse(priv);
+	stm32_enable_oscillator_msi(priv);
+	_clk_stm32_enable(priv, _CK_LSI);
+}
+
+static int stm32_clk_configure_div(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT;
+	int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
+
+	return clk_stm32_set_div(priv, div_id, div_n);
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int mux_id = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+	return clk_mux_set_parent(priv, mux_id, sel);
+}
+
+static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
+{
+	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+
+	return clk_get_index(priv, binding_id);
+}
+
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+	bool enable = ((data & CLK_ON_MASK) >> CLK_ON_SHIFT) != 0U;
+	int clk_id = 0;
+	int ret = 0;
+
+	clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
+	if (clk_id < 0) {
+		return clk_id;
+	}
+
+	if (sel != CLK_NOMUX) {
+		ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	if (enable) {
+		clk_stm32_enable_call_ops(priv, clk_id);
+	} else {
+		clk_stm32_disable_call_ops(priv, clk_id);
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure(struct stm32_clk_priv *priv, uint32_t val)
+{
+	uint32_t cmd = (val & CMD_MASK) >> CMD_SHIFT;
+	uint32_t cmd_data = val & ~CMD_MASK;
+	int ret = -1;
+
+	switch (cmd) {
+	case CMD_DIV:
+		ret = stm32_clk_configure_div(priv, cmd_data);
+		break;
+
+	case CMD_MUX:
+		ret = stm32_clk_configure_mux(priv, cmd_data);
+		break;
+
+	case CMD_CLK:
+		ret = stm32_clk_configure_clk(priv, cmd_data);
+		break;
+
+	default:
+		EARLY_ERROR("%s: cmd unknown ! : 0x%x\n", __func__, val);
+		break;
+	}
+
+	return ret;
+}
+
+static int stm32_clk_bus_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0; i < pdata->nbusclk; i++) {
+		int ret;
+
+		ret = stm32_clk_configure(priv, pdata->busclk[i]);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_kernel_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nkernelclk; i++) {
+		int ret;
+
+		ret = stm32_clk_configure(priv, pdata->kernelclk[i]);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp2_init_clock_tree(void)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	int ret;
+
+	/* Set timer with STGEN without changing its clock source */
+	stm32mp_stgen_restore_rate();
+	generic_delay_timer_init();
+
+	stm32_clk_oscillators_enable(priv);
+
+	/* Come back to HSI */
+	ret = stm32mp2_clk_switch_to_hsi(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32mp2_clk_pll_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	/* Wait LSE ready before to use it */
+	ret = stm32_clk_oscillators_wait_lse_ready(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32mp2_clk_flexgen_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32_clk_bus_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32_clk_kernel_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	return 0;
+}
+
+static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
+					  struct stm32_osci_dt_cfg *osci)
+{
+	int subnode = 0;
+
+	/* Default value oscillator not found, freq=0 */
+	osci->freq = 0;
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar = NULL;
+		const fdt32_t *cuint = NULL;
+		int ret = 0;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return ret;
+		}
+
+		if (strncmp(cchar, name, (size_t)ret) ||
+		    fdt_get_status(subnode) == DT_DISABLED) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
+		if (cuint == NULL) {
+			return ret;
+		}
+
+		osci->freq = fdt32_to_cpu(*cuint);
+
+		if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
+			osci->bypass = true;
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
+			osci->digbyp = true;
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
+			osci->css = true;
+		}
+
+		osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
+
+		return 0;
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
+{
+	int fdt_err = 0;
+	uint32_t i = 0;
+	int node = 0;
+
+	node = fdt_path_offset(fdt, "/clocks");
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	for (i = 0; i < pdata->nosci; i++) {
+		const char *name = NULL;
+
+		name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
+		if (name == NULL) {
+			continue;
+		}
+
+		fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
+		if (fdt_err < 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	const fdt32_t *cuint = NULL;
+	int subnode_pll = 0;
+	uint32_t val = 0;
+	int err = 0;
+
+	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+	if (!cuint) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_pll < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode_pll, "cfg", (int)PLLCFG_NB, pll->cfg);
+	if (err != 0) {
+		return err;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode_pll, "csg", (int)PLLCSG_NB, pll->csg);
+
+	pll->csg_enabled = (err == 0);
+
+	if (err == -FDT_ERR_NOTFOUND) {
+		err = 0;
+	}
+
+	if (err != 0) {
+		return err;
+	}
+
+	pll->enabled = true;
+
+	pll->frac = fdt_read_uint32_default(fdt, subnode_pll, "frac", 0);
+
+	pll->src = UINT32_MAX;
+
+	err = fdt_read_uint32(fdt, subnode_pll, "src", &val);
+	if  (err == 0) {
+		pll->src = val;
+	}
+
+	return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+	unsigned int i = 0;
+
+	for (i = _PLL1; i < pdata->npll; i++) {
+		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		char name[RCC_PLL_NAME_SIZE];
+		int subnode = 0;
+		int err = 0;
+
+		snprintf(name, sizeof(name), "st,pll-%u", i + 1);
+
+		subnode = fdt_subnode_offset(fdt, node, name);
+		if (!fdt_check_node(subnode)) {
+			continue;
+		}
+
+		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+		if (err != 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+	void *fdt = NULL;
+	int node;
+	int err;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		panic();
+	}
+
+	err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,busclk", pdata->busclk, &pdata->nbusclk);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,flexgen", pdata->flexgen,
+					  &pdata->nflexgen);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,kerclk", pdata->kernelclk,
+					  &pdata->nkernelclk);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+#endif /* IMAGE_BL2 */
+
+static struct stm32_osci_dt_cfg mp25_osci[NB_OSCILLATOR];
+
+static struct stm32_pll_dt_cfg mp25_pll[_PLL_NB];
+
+#define DT_FLEXGEN_CLK_MAX	64
+static uint32_t mp25_flexgen[DT_FLEXGEN_CLK_MAX];
+
+#define DT_BUS_CLK_MAX		6
+static uint32_t mp25_busclk[DT_BUS_CLK_MAX];
+
+#define DT_KERNEL_CLK_MAX	20
+static uint32_t mp25_kernelclk[DT_KERNEL_CLK_MAX];
+
+static struct stm32_clk_platdata stm32mp25_pdata = {
+	.osci = mp25_osci,
+	.nosci = NB_OSCILLATOR,
+	.pll = mp25_pll,
+	.npll = _PLL_NB,
+	.flexgen = mp25_flexgen,
+	.nflexgen = DT_FLEXGEN_CLK_MAX,
+	.busclk	= mp25_busclk,
+	.nbusclk = DT_BUS_CLK_MAX,
+	.kernelclk = mp25_kernelclk,
+	.nkernelclk = DT_KERNEL_CLK_MAX,
+};
+
+static uint8_t refcounts_mp25[CK_LAST];
+
+static struct stm32_clk_priv stm32mp25_clock_data = {
+	.base		= RCC_BASE,
+	.num		= ARRAY_SIZE(stm32mp25_clk),
+	.clks		= stm32mp25_clk,
+	.parents	= parent_mp25,
+	.nb_parents	= ARRAY_SIZE(parent_mp25),
+	.gates		= gates_mp25,
+	.nb_gates	= ARRAY_SIZE(gates_mp25),
+	.div		= dividers_mp25,
+	.nb_div		= ARRAY_SIZE(dividers_mp25),
+	.osci_data	= stm32mp25_osc_data,
+	.nb_osci_data	= ARRAY_SIZE(stm32mp25_osc_data),
+	.gate_refcounts	= refcounts_mp25,
+	.pdata		= &stm32mp25_pdata,
+	.ops_array	= ops_array_mp25,
+};
+
+int stm32mp2_clk_init(void)
+{
+	uintptr_t base = RCC_BASE;
+	int ret;
+
+#ifdef IMAGE_BL2
+	ret = stm32_clk_parse_fdt(&stm32mp25_pdata);
+	if (ret != 0) {
+		return ret;
+	}
+#endif
+
+	ret = clk_stm32_init(&stm32mp25_clock_data, base);
+	if (ret != 0) {
+		return ret;
+	}
+
+#ifdef IMAGE_BL2
+	ret = stm32mp2_init_clock_tree();
+	if (ret != 0) {
+		return ret;
+	}
+
+	clk_stm32_enable_critical_clocks();
+#endif
+
+	return 0;
+}
+
+int stm32mp2_pll1_disable(void)
+{
+#ifdef IMAGE_BL2
+	return -EPERM;
+#else
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+
+	stm32mp2_a35_ss_on_hsi();
+
+	mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
+
+	return 0;
+#endif
+}
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 818fd85..3d352af 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -27,6 +27,71 @@
 
 #include <platform_def.h>
 
+enum stm32mp1_pllcfg {
+	PLLCFG_M,
+	PLLCFG_N,
+	PLL_DIV_MN_NB,
+	PLLCFG_P = PLL_DIV_MN_NB,
+	PLLCFG_Q,
+	PLLCFG_R,
+	PLLCFG_O,
+	PLLCFG_NB
+};
+
+#define PLL_DIV_MN_NB	2
+#define PLL_DIV_PQR_NB	3
+
+enum stm32mp1_pllcsg {
+	PLLCSG_MOD_PER,
+	PLLCSG_INC_STEP,
+	PLLCSG_SSCG_MODE,
+	PLLCSG_NB
+};
+
+struct stm32_pll_dt_cfg {
+	bool status;
+	uint32_t src;
+	uint32_t cfg[PLLCFG_NB];
+	uint32_t frac;
+	bool csg_enabled;
+	uint32_t csg[PLLCSG_NB];
+};
+
+struct stm32_clk_platdata {
+	uint32_t npll;
+	struct stm32_pll_dt_cfg *pll;
+	uint32_t nclksrc;
+	uint32_t *clksrc;
+	uint32_t nclkdiv;
+	uint32_t *clkdiv;
+	bool lse_css;
+};
+
+struct stm32_clk_priv {
+	uintptr_t base;
+	const struct mux_cfg *parents;
+	const uint32_t nb_parents;
+	const struct div_cfg *div;
+	const uint32_t nb_div;
+	void *pdata;
+};
+
+static struct stm32_clk_priv *stm32_clock_data;
+
+static struct stm32_clk_priv *clk_stm32_get_priv(void)
+{
+	return stm32_clock_data;
+}
+
+static int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
+{
+	stm32_clock_data = priv;
+
+	priv->base = base;
+
+	return 0;
+}
+
 #define MAX_HSI_HZ		64000000
 #define USB_PHY_48_MHZ		48000000
 
@@ -39,6 +104,199 @@
 #define HSIDIV_TIMEOUT		TIMEOUT_US_200MS
 #define OSCRDY_TIMEOUT		TIMEOUT_US_1S
 
+struct mux_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+struct div_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+#define DIV_NO_BIT_RDY UINT8_MAX
+
+#define DIV_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy	= (_bitrdy),\
+	}
+
+static const struct div_cfg dividers_mp15[] = {
+	DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 31),
+	DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 31),
+	DIV_CFG(DIV_MCU, RCC_MCUDIVR, 0, 4, 31),
+	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 31),
+	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_ETHPTP, RCC_ETHCKSELR, 4, 4, DIV_NO_BIT_RDY),
+};
+
+/*
+ * MUX CONFIG
+ */
+
+#define MUX_NO_BIT_RDY		UINT8_MAX
+
+#define MUXRDY_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy = (_bitrdy),\
+	}
+
+#define MUX_CFG(_id, _offset, _shift, _width)\
+	MUXRDY_CFG(_id, _offset, _shift, _width,  MUX_NO_BIT_RDY)
+
+static const struct mux_cfg parent_mp15[MUX_NB] = {
+	MUX_CFG(MUX_PLL12,	RCC_RCK12SELR, 0, 2),
+	MUX_CFG(MUX_PLL3,	RCC_RCK3SELR, 0, 2),
+	MUX_CFG(MUX_PLL4,	RCC_RCK4SELR, 0, 2),
+	MUX_CFG(MUX_CKPER,	RCC_CPERCKSELR, 0, 2),
+	MUXRDY_CFG(MUX_MPU,	RCC_MPCKSELR, 0, 2, 31),
+	MUXRDY_CFG(MUX_AXI,	RCC_ASSCKSELR, 0, 3, 31),
+	MUXRDY_CFG(MUX_MCU,	RCC_MSSCKSELR, 0, 2, 31),
+	MUX_CFG(MUX_RTC,	RCC_BDCR, 16, 2),
+	MUX_CFG(MUX_SDMMC12,	RCC_SDMMC12CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI2S23,	RCC_SPI2S23CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI45,	RCC_SPI45CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C12,	RCC_I2C12CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C35,	RCC_I2C35CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM23,	RCC_LPTIM23CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM45,	RCC_LPTIM45CKSELR, 0, 3),
+	MUX_CFG(MUX_UART24,	RCC_UART24CKSELR, 0, 3),
+	MUX_CFG(MUX_UART35,	RCC_UART35CKSELR, 0, 3),
+	MUX_CFG(MUX_UART78,	RCC_UART78CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI1,	RCC_SAI1CKSELR, 0, 3),
+	MUX_CFG(MUX_ETH,	RCC_ETHCKSELR, 0, 2),
+	MUX_CFG(MUX_I2C46,	RCC_I2C46CKSELR, 0, 3),
+	MUX_CFG(MUX_RNG2,	RCC_RNG2CKSELR, 0, 2),
+	MUX_CFG(MUX_SDMMC3,	RCC_SDMMC3CKSELR, 0, 3),
+	MUX_CFG(MUX_FMC,	RCC_FMCCKSELR, 0, 2),
+	MUX_CFG(MUX_QSPI,	RCC_QSPICKSELR, 0, 2),
+	MUX_CFG(MUX_USBPHY,	RCC_USBCKSELR, 0, 2),
+	MUX_CFG(MUX_USBO,	RCC_USBCKSELR, 4, 1),
+	MUX_CFG(MUX_SPDIF,	RCC_SPDIFCKSELR, 0, 2),
+	MUX_CFG(MUX_SPI2S1,	RCC_SPI2S1CKSELR, 0, 3),
+	MUX_CFG(MUX_CEC,	RCC_CECCKSELR, 0, 2),
+	MUX_CFG(MUX_LPTIM1,	RCC_LPTIM1CKSELR, 0, 3),
+	MUX_CFG(MUX_UART6,	RCC_UART6CKSELR, 0, 3),
+	MUX_CFG(MUX_FDCAN,	RCC_FDCANCKSELR, 0, 2),
+	MUX_CFG(MUX_SAI2,	RCC_SAI2CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI3,	RCC_SAI3CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI4,	RCC_SAI4CKSELR, 0, 3),
+	MUX_CFG(MUX_ADC,	RCC_ADCCKSELR, 0, 2),
+	MUX_CFG(MUX_DSI,	RCC_DSICKSELR, 0, 1),
+	MUX_CFG(MUX_RNG1,	RCC_RNG1CKSELR, 0, 2),
+	MUX_CFG(MUX_STGEN,	RCC_STGENCKSELR, 0, 2),
+	MUX_CFG(MUX_UART1,	RCC_UART1CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI6,	RCC_SPI6CKSELR, 0, 3),
+	MUX_CFG(MUX_MCO1,	RCC_MCO1CFGR, 0, 3),
+	MUX_CFG(MUX_MCO2,	RCC_MCO2CFGR, 0, 3),
+};
+
+#define MASK_WIDTH_SHIFT(_width, _shift) \
+	GENMASK(((_width) + (_shift) - 1U), (_shift))
+
+int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id)
+{
+	const struct mux_cfg *mux;
+	uint32_t mask;
+
+	if (mux_id >= priv->nb_parents) {
+		panic();
+	}
+
+	mux = &priv->parents[mux_id];
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	return (mmio_read_32(priv->base + mux->offset) & mask) >> mux->shift;
+}
+
+static int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel)
+{
+	const struct mux_cfg *mux = &priv->parents[pid];
+	uintptr_t address = priv->base + mux->offset;
+	uint32_t mask;
+	uint64_t timeout;
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	mmio_clrsetbits_32(address, mask, (sel << mux->shift) & mask);
+
+	if (mux->bitrdy == MUX_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+	mask = BIT(mux->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t val)
+{
+	uint32_t data = val & CMD_DATA_MASK;
+	int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+	return clk_mux_set_parent(priv, mux, sel);
+}
+
+int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value)
+{
+	const struct div_cfg *divider;
+	uintptr_t address;
+	uint64_t timeout;
+	uint32_t mask;
+
+	if (div_id >= priv->nb_div) {
+		panic();
+	}
+
+	divider = &priv->div[div_id];
+	address = priv->base + divider->offset;
+
+	mask = MASK_WIDTH_SHIFT(divider->width, divider->shift);
+	mmio_clrsetbits_32(address, mask, (value << divider->shift) & mask);
+
+	if (divider->bitrdy == DIV_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	mask = BIT(divider->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
 const char *stm32mp_osc_node_label[NB_OSC] = {
 	[_LSI] = "clk-lsi",
 	[_LSE] = "clk-lse",
@@ -206,23 +464,6 @@
 	CLKDIV_NB
 };
 
-enum stm32mp1_pllcfg {
-	PLLCFG_M,
-	PLLCFG_N,
-	PLLCFG_P,
-	PLLCFG_Q,
-	PLLCFG_R,
-	PLLCFG_O,
-	PLLCFG_NB
-};
-
-enum stm32mp1_pllcsg {
-	PLLCSG_MOD_PER,
-	PLLCSG_INC_STEP,
-	PLLCSG_SSCG_MODE,
-	PLLCSG_NB
-};
-
 enum stm32mp1_plltype {
 	PLL_800,
 	PLL_1600,
@@ -537,7 +778,18 @@
 };
 
 /* Define characteristic of PLL according type */
-#define DIVN_MIN	24
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		800000000U
+#define VCO_MAX		1600000000U
+
 static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
 	[PLL_800] = {
 		.refclk_min = 4,
@@ -1327,6 +1579,11 @@
 	uint32_t value;
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
+	/* Do not reconfigure LSE if it is already ON */
+	if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) {
+		return;
+	}
+
 	if (digbyp) {
 		mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_DIGBYP);
 	}
@@ -1360,7 +1617,7 @@
 static void stm32mp1_lse_wait(void)
 {
 	if (stm32mp1_osc_wait(true, RCC_BDCR, RCC_BDCR_LSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1369,7 +1626,7 @@
 	stm32mp1_ls_osc_set(enable, RCC_RDLSICR, RCC_RDLSICR_LSION);
 
 	if (stm32mp1_osc_wait(enable, RCC_RDLSICR, RCC_RDLSICR_LSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1387,7 +1644,7 @@
 
 	stm32mp1_hs_ocs_set(true, RCC_OCENR_HSEON);
 	if (stm32mp1_osc_wait(true, RCC_OCRDYR, RCC_OCRDYR_HSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 
 	if (css) {
@@ -1406,7 +1663,7 @@
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_CSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_CSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1414,7 +1671,7 @@
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_HSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_HSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1454,7 +1711,7 @@
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -1;
 	}
 
@@ -1467,7 +1724,7 @@
 
 static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
 				    unsigned int clksrc,
-				    uint32_t *pllcfg, int plloff)
+				    uint32_t *pllcfg, uint32_t fracv)
 {
 	const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
 	uintptr_t rcc_base = stm32mp_rcc_base();
@@ -1476,8 +1733,7 @@
 	uintptr_t clksrc_address = rcc_base + (clksrc >> 4);
 	unsigned long refclk;
 	uint32_t ifrge = 0U;
-	uint32_t src, value, fracv = 0;
-	void *fdt;
+	uint32_t src, value;
 
 	/* Check PLL output */
 	if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) {
@@ -1516,10 +1772,6 @@
 	}
 
 	/* Fractional configuration */
-	if (fdt_get_address(&fdt) == 1) {
-		fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
-	}
-
 	value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
 	value |= RCC_PLLNFRACR_FRACLE;
 	if (mmio_read_32(rcc_base + pll->pllxfracr) != value) {
@@ -1561,8 +1813,8 @@
 	/* Wait PLL lock */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1590,8 +1842,8 @@
 	/* Wait PLL stopped */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1683,190 +1935,270 @@
 			RCC_PLLNCR_SSCG_CTRL);
 }
 
-static int stm32mp1_set_clksrc(unsigned int clksrc)
+static int clk_compute_pll1_settings(unsigned long input_freq,
+				     uint32_t freq_khz,
+				     uint32_t *pllcfg, uint32_t *fracv)
 {
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
-	uint64_t timeout;
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
 
-	mmio_clrsetbits_32(clksrc_address, RCC_SELR_SRC_MASK,
-			   clksrc & RCC_SELR_SRC_MASK);
+	/* Following parameters have always the same value */
+	pllcfg[PLLCFG_Q] = 0U;
+	pllcfg[PLLCFG_R] = 0U;
+	pllcfg[PLLCFG_O] = PQR(1, 0, 0);
 
-	timeout = timeout_init_us(CLKSRC_TIMEOUT);
-	while ((mmio_read_32(clksrc_address) & RCC_SELR_SRCRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKSRC %x start failed @ 0x%lx: 0x%x\n", clksrc,
-			      clksrc_address, mmio_read_32(clksrc_address));
-			return -ETIMEDOUT;
-		}
-	}
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
 
-	return 0;
-}
-
-static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address)
-{
-	uint64_t timeout;
-
-	mmio_clrsetbits_32(address, RCC_DIVR_DIV_MASK,
-			   clkdiv & RCC_DIVR_DIV_MASK);
-
-	timeout = timeout_init_us(CLKDIV_TIMEOUT);
-	while ((mmio_read_32(address) & RCC_DIVR_DIVRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKDIV %x start failed @ 0x%lx: 0x%x\n",
-			      clkdiv, address, mmio_read_32(address));
-			return -ETIMEDOUT;
-		}
-	}
-
-	return 0;
-}
-
-static void stm32mp1_mco_csg(uint32_t clksrc, uint32_t clkdiv)
-{
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
-
-	/*
-	 * Binding clksrc :
-	 *      bit15-4 offset
-	 *      bit3:   disable
-	 *      bit2-0: MCOSEL[2:0]
-	 */
-	if ((clksrc & 0x8U) != 0U) {
-		mmio_clrbits_32(clksrc_address, RCC_MCOCFG_MCOON);
-	} else {
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCOSRC_MASK,
-				   clksrc & RCC_MCOCFG_MCOSRC_MASK);
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCODIV_MASK,
-				   clkdiv << RCC_MCOCFG_MCODIV_SHIFT);
-		mmio_setbits_32(clksrc_address, RCC_MCOCFG_MCOON);
-	}
-}
-
-static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
-{
-	uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
-
-	if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) ||
-	    (clksrc != (uint32_t)CLK_RTC_DISABLED)) {
-		mmio_clrsetbits_32(address,
-				   RCC_BDCR_RTCSRC_MASK,
-				   (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
-
-		mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
-	}
-
-	if (lse_css) {
-		mmio_setbits_32(address, RCC_BDCR_LSECSSON);
-	}
-}
-
-static void stm32mp1_pkcs_config(uint32_t pkcs)
-{
-	uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU);
-	uint32_t value = pkcs & 0xFU;
-	uint32_t mask = 0xFU;
-
-	if ((pkcs & BIT(31)) != 0U) {
-		mask <<= 4;
-		value <<= 4;
-	}
-
-	mmio_clrsetbits_32(address, mask, value);
-}
-
-static int clk_get_pll_settings_from_dt(int plloff, unsigned int *pllcfg,
-					uint32_t *fracv, uint32_t *csg,
-					bool *csg_set)
-{
-	void *fdt;
-	int ret;
-
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_read_uint32_array(fdt, plloff, "cfg", (uint32_t)PLLCFG_NB,
-				    pllcfg);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	*fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
-
-	ret = fdt_read_uint32_array(fdt, plloff, "csg", (uint32_t)PLLCSG_NB,
-				    csg);
-
-	*csg_set = (ret == 0);
-
-	if (ret == -FDT_ERR_NOTFOUND) {
-		ret = 0;
-	}
-
-	return ret;
-}
-
-int stm32mp1_clk_init(void)
-{
-	uintptr_t rcc_base = stm32mp_rcc_base();
-	uint32_t pllfracv[_PLL_NB];
-	uint32_t pllcsg[_PLL_NB][PLLCSG_NB];
-	unsigned int clksrc[CLKSRC_NB];
-	unsigned int clkdiv[CLKDIV_NB];
-	unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
-	int plloff[_PLL_NB];
-	int ret, len;
-	enum stm32mp1_pll_id i;
-	bool pllcsg_set[_PLL_NB];
-	bool pllcfg_valid[_PLL_NB];
-	bool lse_css = false;
-	bool pll3_preserve = false;
-	bool pll4_preserve = false;
-	bool pll4_bootrom = false;
-	const fdt32_t *pkcs_cell;
-	void *fdt;
-	int stgen_p = stm32mp1_clk_get_parent(STGEN_K);
-	int usbphy_p = stm32mp1_clk_get_parent(USBPHY_K);
-
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB,
-					clksrc);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB,
-					clkdiv);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		char name[12];
-
-		snprintf(name, sizeof(name), "st,pll@%u", i);
-		plloff[i] = fdt_rcc_subnode_offset(name);
-
-		pllcfg_valid[i] = fdt_check_node(plloff[i]);
-		if (!pllcfg_valid[i]) {
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
 			continue;
 		}
 
-		ret = clk_get_pll_settings_from_dt(plloff[i], pllcfg[i],
-						   &pllfracv[i], pllcsg[i],
-						   &pllcsg_set[i]);
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
+
+			freq = output_freq * divm * (divp + 1U);
+
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
+
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pllcfg[PLLCFG_M] = divm - 1U;
+					pllcfg[PLLCFG_N] = (uint32_t)divn;
+					pllcfg[PLLCFG_P] = divp;
+					*fracv = (uint32_t)frac;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
+		}
+	}
+
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int clk_get_pll1_settings(uint32_t clksrc, uint32_t freq_khz,
+				 uint32_t *pllcfg, uint32_t *fracv)
+{
+	unsigned long input_freq = 0UL;
+
+	assert(pllcfg != NULL);
+	assert(fracv != NULL);
+
+	switch (clksrc) {
+	case CLK_PLL12_HSI:
+		input_freq = stm32mp_clk_get_rate(CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = stm32mp_clk_get_rate(CK_HSE);
+		break;
+	default:
+		break;
+	}
+
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	return clk_compute_pll1_settings(input_freq, freq_khz, pllcfg, fracv);
+}
+
+static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nclkdiv; i++) {
+		uint32_t div_id, div_n;
+		uint32_t val;
+		int ret;
+
+		val = pdata->clkdiv[i] & CMD_DATA_MASK;
+		div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
+		div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
+
+		ret = clk_stm32_set_div(priv, div_id, div_n);
 		if (ret != 0) {
 			return ret;
 		}
 	}
 
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
+	return 0;
+}
+
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
+{
+	uint32_t sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+	uint32_t enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
+	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+	struct stm32_clk_platdata *pdata = priv->pdata;
+
+	if (binding_id == RTC) {
+		uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
+
+		if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) || (enable != 0U)) {
+			mmio_clrsetbits_32(address, RCC_BDCR_RTCSRC_MASK,
+					   (sel & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
+
+			mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+			/* Configure LSE CSS */
+			if (pdata->lse_css) {
+				mmio_setbits_32(priv->base + RCC_BDCR, RCC_BDCR_LSECSSON);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure_by_addr_val(struct stm32_clk_priv *priv,
+					   uint32_t data)
+{
+	uint32_t addr = data >> CLK_ADDR_SHIFT;
+	uint32_t val = data & CLK_ADDR_VAL_MASK;
+
+	mmio_setbits_32(priv->base + addr, val);
+
+	return 0;
+}
+
+static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	bool ckper_disabled = false;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nclksrc; i++) {
+		uint32_t val = pdata->clksrc[i];
+		uint32_t cmd, cmd_data;
+		int ret;
+
+		if (val & CMD_ADDR_BIT) {
+			ret = stm32_clk_configure_by_addr_val(priv, val & ~CMD_ADDR_BIT);
+			if (ret != 0) {
+				return ret;
+			}
+
+			continue;
+		}
+
+		if (val == (uint32_t)CLK_CKPER_DISABLED) {
+			ckper_disabled = true;
+			continue;
+		}
+
+		cmd = (val & CMD_MASK) >> CMD_SHIFT;
+		cmd_data = val & ~CMD_MASK;
+
+		switch (cmd) {
+		case CMD_MUX:
+			ret = stm32_clk_configure_mux(priv, cmd_data);
+			break;
+
+		case CMD_CLK:
+			ret = stm32_clk_configure_clk(priv, cmd_data);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/*
+	 * CKPER is source for some peripheral clocks
+	 * (FMC-NAND / QPSI-NOR) and switching source is allowed
+	 * only if previous clock is still ON
+	 * => deactivate CKPER only after switching clock
+	 */
+	if (!ckper_disabled) {
+		return 0;
+	}
+
+	return stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED);
+}
+
+static int stm32mp1_pll_configure_src(struct stm32_clk_priv *priv, int pll_idx)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = &pdata->pll[pll_idx];
+
+	if (!pll_conf->status) {
+		return 0;
+	}
+
+	return stm32_clk_configure_mux(priv, pll_conf->src);
+}
+
+int stm32mp1_clk_init(void)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = pdata->pll;
+	int ret;
+	enum stm32mp1_pll_id i;
+	bool pll3_preserve = false;
+	bool pll4_preserve = false;
+	bool pll4_bootrom = false;
+	int stgen_p = stm32mp1_clk_get_parent(STGEN_K);
+	int usbphy_p = stm32mp1_clk_get_parent(USBPHY_K);
+	uint32_t usbreg_bootrom = 0U;
+
+	if (!pll_conf[_PLL1].status) {
+		ret = clk_get_pll1_settings(pll_conf[_PLL2].src, PLL1_NOMINAL_FREQ_IN_KHZ,
+					    pll_conf[_PLL1].cfg, &pll_conf[_PLL1].frac);
+		if (ret != 0) {
+			return ret;
+		}
+
+		pll_conf[_PLL1].status = true;
+		pll_conf[_PLL1].src = pll_conf[_PLL2].src;
+	}
 
 	/*
 	 * Switch ON oscillator found in device-tree.
@@ -1882,7 +2214,7 @@
 
 		bypass = fdt_clk_read_bool(name, "st,bypass");
 		digbyp = fdt_clk_read_bool(name, "st,digbypass");
-		lse_css = fdt_clk_read_bool(name, "st,css");
+		pdata->lse_css = fdt_clk_read_bool(name, "st,css");
 		lsedrv = fdt_clk_read_uint32_default(name, "st,drive",
 						     LSEDRV_MEDIUM_HIGH);
 		stm32mp1_lse_enable(bypass, digbyp, lsedrv);
@@ -1903,36 +2235,28 @@
 	stm32mp1_csi_set(true);
 
 	/* Come back to HSI */
-	ret = stm32mp1_set_clksrc(CLK_MPU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MPU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_AXI_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_AXI_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_MCU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MCU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-
-	if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
+	if ((mmio_read_32(priv->base + RCC_MP_RSTSCLRR) &
 	     RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
-		if (pllcfg_valid[_PLL3]) {
-			pll3_preserve =
-				stm32mp1_check_pll_conf(_PLL3,
-							clksrc[CLKSRC_PLL3],
-							pllcfg[_PLL3],
-							plloff[_PLL3]);
-		}
-
-		if (pllcfg_valid[_PLL4]) {
-			pll4_preserve =
-				stm32mp1_check_pll_conf(_PLL4,
-							clksrc[CLKSRC_PLL4],
-							pllcfg[_PLL4],
-							plloff[_PLL4]);
-		}
+		pll3_preserve = stm32mp1_check_pll_conf(_PLL3,
+							pll_conf[_PLL3].src,
+							pll_conf[_PLL3].cfg,
+							pll_conf[_PLL3].frac);
+		pll4_preserve = stm32mp1_check_pll_conf(_PLL4,
+							pll_conf[_PLL4].src,
+							pll_conf[_PLL4].cfg,
+							pll_conf[_PLL4].frac);
 	}
 	/* Don't initialize PLL4, when used by BOOTROM */
 	if ((stm32mp_get_boot_itf_selected() ==
@@ -1964,58 +2288,27 @@
 		stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 	}
 
-	/* Select DIV */
-	/* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
-	mmio_write_32(rcc_base + RCC_MPCKDIVR,
-		      clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK);
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc_base + RCC_AXIDIVR);
+	/* Configure dividers */
+	ret = stm32_clk_dividers_configure(priv);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc_base + RCC_APB4DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc_base + RCC_APB5DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_MCU], rcc_base + RCC_MCUDIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc_base + RCC_APB1DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB2], rcc_base + RCC_APB2DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB3], rcc_base + RCC_APB3DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* No ready bit for RTC */
-	mmio_write_32(rcc_base + RCC_RTCDIVR,
-		      clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK);
 
 	/* Configure PLLs source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL12]);
+	ret = stm32mp1_pll_configure_src(priv, _PLL1);
 	if (ret != 0) {
 		return ret;
 	}
 
 	if (!pll3_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL3]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL3);
 		if (ret != 0) {
 			return ret;
 		}
 	}
 
 	if (!pll4_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL4]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL4);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2028,34 +2321,34 @@
 			continue;
 		}
 
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
 		if ((i == _PLL4) && pll4_bootrom) {
 			/* Set output divider if not done by the Bootrom */
-			stm32mp1_pll_config_output(i, pllcfg[i]);
+			stm32mp1_pll_config_output(i, pll_conf[i].cfg);
 			continue;
 		}
 
-		ret = stm32mp1_pll_config(i, pllcfg[i], pllfracv[i]);
+		ret = stm32mp1_pll_config(i, pll_conf[i].cfg, pll_conf[i].frac);
 		if (ret != 0) {
 			return ret;
 		}
 
-		if (pllcsg_set[i]) {
-			stm32mp1_pll_csg(i, pllcsg[i]);
+		if (pll_conf[i].csg_enabled) {
+			stm32mp1_pll_csg(i, pll_conf[i].csg);
 		}
 
 		stm32mp1_pll_start(i);
 	}
 	/* Wait and start PLLs output when ready */
 	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
-		ret = stm32mp1_pll_output(i, pllcfg[i][PLLCFG_O]);
+		ret = stm32mp1_pll_output(i, pll_conf[i].cfg[PLLCFG_O]);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2065,69 +2358,32 @@
 		stm32mp1_lse_wait();
 	}
 
+	if (pll4_bootrom) {
+		usbreg_bootrom = mmio_read_32(priv->base + RCC_USBCKSELR);
+	}
+
 	/* Configure with expected clock source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MPU]);
+	ret = stm32_clk_source_configure(priv);
 	if (ret != 0) {
-		return ret;
+		panic();
 	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_AXI]);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MCU]);
-	if (ret != 0) {
-		return ret;
-	}
-	stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css);
 
-	/* Configure PKCK */
-	pkcs_cell = fdt_rcc_read_prop("st,pkcs", &len);
-	if (pkcs_cell != NULL) {
-		bool ckper_disabled = false;
-		uint32_t j;
-		uint32_t usbreg_bootrom = 0U;
+	if (pll4_bootrom) {
+		uint32_t usbreg_value, usbreg_mask;
+		const struct stm32mp1_clk_sel *sel;
 
-		if (pll4_bootrom) {
-			usbreg_bootrom = mmio_read_32(rcc_base + RCC_USBCKSELR);
-		}
+		sel = clk_sel_ref(_USBPHY_SEL);
+		usbreg_mask = (uint32_t)sel->msk << sel->src;
+		sel = clk_sel_ref(_USBO_SEL);
+		usbreg_mask |= (uint32_t)sel->msk << sel->src;
 
-		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
-			uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
-
-			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
-				ckper_disabled = true;
-				continue;
-			}
-			stm32mp1_pkcs_config(pkcs);
-		}
-
-		/*
-		 * CKPER is source for some peripheral clocks
-		 * (FMC-NAND / QPSI-NOR) and switching source is allowed
-		 * only if previous clock is still ON
-		 * => deactivated CKPER only after switching clock
-		 */
-		if (ckper_disabled) {
-			stm32mp1_pkcs_config(CLK_CKPER_DISABLED);
-		}
-
-		if (pll4_bootrom) {
-			uint32_t usbreg_value, usbreg_mask;
-			const struct stm32mp1_clk_sel *sel;
-
-			sel = clk_sel_ref(_USBPHY_SEL);
-			usbreg_mask = (uint32_t)sel->msk << sel->src;
-			sel = clk_sel_ref(_USBO_SEL);
-			usbreg_mask |= (uint32_t)sel->msk << sel->src;
-
-			usbreg_value = mmio_read_32(rcc_base + RCC_USBCKSELR) &
-				       usbreg_mask;
-			usbreg_bootrom &= usbreg_mask;
-			if (usbreg_bootrom != usbreg_value) {
-				VERBOSE("forbidden new USB clk path\n");
-				VERBOSE("vs bootrom on USB boot\n");
-				return -FDT_ERR_BADVALUE;
-			}
+		usbreg_value = mmio_read_32(priv->base + RCC_USBCKSELR) &
+			       usbreg_mask;
+		usbreg_bootrom &= usbreg_mask;
+		if (usbreg_bootrom != usbreg_value) {
+			EARLY_ERROR("forbidden new USB clk path\n");
+			EARLY_ERROR("vs bootrom on USB boot\n");
+			return -FDT_ERR_BADVALUE;
 		}
 	}
 
@@ -2139,7 +2395,7 @@
 	stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 
 	/* Software Self-Refresh mode (SSR) during DDR initilialization */
-	mmio_clrsetbits_32(rcc_base + RCC_DDRITFCR,
+	mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
 			   RCC_DDRITFCR_DDRCKMOD_MASK,
 			   RCC_DDRITFCR_DDRCKMOD_SSR <<
 			   RCC_DDRITFCR_DDRCKMOD_SHIFT);
@@ -2366,8 +2622,199 @@
 	.get_parent	= stm32mp1_clk_get_parent,
 };
 
+struct stm32_pll_dt_cfg mp15_pll[_PLL_NB];
+uint32_t mp15_clksrc[MUX_NB];
+uint32_t mp15_clkdiv[DIV_NB];
+
+struct stm32_clk_platdata stm32mp15_clock_pdata = {
+	.pll		= mp15_pll,
+	.npll		= _PLL_NB,
+	.clksrc		= mp15_clksrc,
+	.nclksrc	= MUX_NB,
+	.clkdiv		= mp15_clkdiv,
+	.nclkdiv	= DIV_NB,
+};
+
+static struct stm32_clk_priv stm32mp15_clock_data = {
+	.base		= RCC_BASE,
+	.parents	= parent_mp15,
+	.nb_parents	= ARRAY_SIZE(parent_mp15),
+	.div		= dividers_mp15,
+	.nb_div		= ARRAY_SIZE(dividers_mp15),
+	.pdata		= &stm32mp15_clock_pdata,
+};
+
+static int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name,
+				       uint32_t *tab, uint32_t *nb)
+{
+	const fdt32_t *cell;
+	int len = 0;
+	uint32_t i;
+
+	cell = fdt_getprop(fdt, node, name, &len);
+	if (cell == NULL) {
+		*nb = 0U;
+		return 0;
+	}
+
+	for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		tab[i] = fdt32_to_cpu(cell[i]);
+	}
+
+	*nb = (uint32_t)len / sizeof(uint32_t);
+
+	return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, &pll->cfg[PLLCFG_M]);
+	if (err != 0) {
+		return err;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLLCSG_NB, pll->csg);
+	if (err == 0) {
+		pll->csg_enabled = true;
+	} else if (err == -FDT_ERR_NOTFOUND) {
+		pll->csg_enabled = false;
+	} else {
+		return err;
+	}
+
+	pll->status = true;
+
+	pll->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
+
+	pll->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
+
+	return 0;
+}
+
+static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
+				    &pll->cfg[PLLCFG_P]);
+	if (err != 0) {
+		return err;
+	}
+
+	pll->cfg[PLLCFG_O] = PQR(1, 1, 1);
+
+	return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	const fdt32_t *cuint;
+	int subnode_pll;
+	int subnode_vco;
+	int err;
+
+	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+	if (cuint == NULL) {
+		/* Case of no pll is defined */
+		return 0;
+	}
+
+	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_pll < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_vco < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	err = clk_stm32_load_vco_config(fdt, subnode_vco, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	err = clk_stm32_load_output_config(fdt, subnode_pll, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+	size_t i = 0U;
+
+	for (i = _PLL1; i < pdata->npll; i++) {
+		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		char name[RCC_PLL_NAME_SIZE];
+		int subnode;
+		int err;
+
+		snprintf(name, sizeof(name), "st,pll@%u", i);
+
+		subnode = fdt_subnode_offset(fdt, node, name);
+		if (!fdt_check_node(subnode)) {
+			continue;
+		}
+
+		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+		if (err != 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+	void *fdt = NULL;
+	int node;
+	uint32_t err;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		panic();
+	}
+
+	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
 int stm32mp1_clk_probe(void)
 {
+	uintptr_t base = RCC_BASE;
+	int ret;
+
 #if defined(IMAGE_BL32)
 	if (!fdt_get_rcc_secure_state()) {
 		mmio_write_32(stm32mp_rcc_base() + RCC_TZCR, 0U);
@@ -2376,6 +2823,16 @@
 
 	stm32mp1_osc_init();
 
+	ret = stm32_clk_parse_fdt(&stm32mp15_clock_pdata);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_stm32_init(&stm32mp15_clock_data, base);
+	if (ret != 0) {
+		return ret;
+	}
+
 	sync_earlyboot_clocks_state();
 
 	clk_register(&stm32mp_clk_ops);
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 379547f..69922fd 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -335,6 +335,19 @@
 }
 
 /*******************************************************************************
+ * This function returns the STGEN counter value.
+ ******************************************************************************/
+static unsigned long long stm32mp_stgen_get_counter(void)
+{
+#ifdef __aarch64__
+	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
+#else
+	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
+		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
+#endif
+}
+
+/*******************************************************************************
  * This function configures and restores the STGEN counter depending on the
  * connected clock.
  ******************************************************************************/
@@ -350,9 +363,11 @@
 	}
 
 	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	counter = stm32mp_stgen_get_counter() * rate / cntfid0;
 
-	stgen_set_counter(counter);
+	if (cntfid0 != 0U) {
+		counter = stm32mp_stgen_get_counter() * rate / cntfid0;
+		stgen_set_counter(counter);
+	}
 	mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
 	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
 
@@ -363,32 +378,13 @@
 }
 
 /*******************************************************************************
- * This function returns the STGEN counter value.
+ * This function restores CPU generic timer rate from the STGEN clock rate.
  ******************************************************************************/
-unsigned long long stm32mp_stgen_get_counter(void)
+void stm32mp_stgen_restore_rate(void)
 {
-#ifdef __aarch64__
-	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
-#else
-	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
-		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
-#endif
-}
+	unsigned long rate;
 
-/*******************************************************************************
- * This function restores the STGEN counter value.
- * It takes a first input value as a counter backup value to be restored and a
- * offset in ms to be added.
- ******************************************************************************/
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms)
-{
-	unsigned long long cnt;
+	rate = mmio_read_32(STGEN_BASE + CNTFID_OFF);
 
-	cnt = value + ((offset_in_ms *
-			mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U);
-
-	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	stgen_set_counter(cnt);
-	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
+	write_cntfrq_el0((u_register_t)rate);
 }
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index a4a64ca..44d7c09 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,6 +282,7 @@
 
 	clk_disable(clock);
 
+#if STM32MP13 || STM32MP15
 	if (status == DT_SECURE) {
 		stm32mp_register_secure_gpio(bank, pin);
 #if !IMAGE_BL2
@@ -294,6 +295,9 @@
 		set_gpio_secure_cfg(bank, pin, false);
 #endif
 	}
+#else /* !STM32MP13 && !STM32MP15 */
+	set_gpio_secure_cfg(bank, pin, true);
+#endif /* STM32MP13 || STM32MP15 */
 }
 
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
@@ -321,3 +325,74 @@
 		 GPIO_ALTERNATE_(0), DT_DISABLED);
 	set_gpio_secure_cfg(bank, pin, stm32_gpio_is_secure_at_reset(bank));
 }
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (level == GPIO_LEVEL_HIGH) {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin));
+	} else {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin + 16U));
+	}
+
+	VERBOSE("GPIO %u level set to 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+}
+
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+	enum gpio_level level = GPIO_LEVEL_LOW;
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (mmio_read_32(base + GPIO_IDR_OFFSET) & BIT(pin)) {
+		level = GPIO_LEVEL_HIGH;
+	}
+
+	VERBOSE("GPIO %u get level 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+
+	return level;
+}
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status)
+{
+	uint32_t mode = GPIO_MODE_OUTPUT;
+	uint32_t od = 0U;
+	uint32_t pull = GPIO_NO_PULL;
+
+	VERBOSE("GPIO %u:%u set config to 0x%x\n", bank, pin, config);
+
+	if (config & GPIOF_DIR_IN) {
+		mode = GPIO_MODE_INPUT;
+	}
+
+	if (config & GPIOF_OUT_INIT_HIGH) {
+		od = 1U;
+	}
+
+	if (config & GPIOF_PULL_UP) {
+		pull |= GPIO_PULL_UP;
+	}
+
+	if (config & GPIOF_PULL_DOWN) {
+		pull |= GPIO_PULL_DOWN;
+	}
+
+	set_gpio(bank, pin, mode, GPIO_TYPE_PUSH_PULL, GPIO_SPEED_LOW,
+		 pull, od, GPIO_ALTERNATE_(0), status);
+}
diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c
index 98c8dcf..8b828a1 100644
--- a/drivers/st/reset/stm32mp1_reset.c
+++ b/drivers/st/reset/stm32mp1_reset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,6 @@
 #include <errno.h>
 #include <limits.h>
 
-#include <platform_def.h>
-
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -16,6 +14,8 @@
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
 
+#include <platform_def.h>
+
 static uint32_t id2reg_offset(unsigned int reset_id)
 {
 	return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
@@ -67,3 +67,16 @@
 
 	return 0;
 }
+
+void __dead2 stm32mp_system_reset(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_MP_GRSTCSETR,
+			RCC_MP_GRSTCSETR_MPSYSRST);
+
+	/* Loop in case system reset is not immediately caught */
+	while (true) {
+		wfi();
+	}
+}
diff --git a/drivers/st/reset/stm32mp2_reset.c b/drivers/st/reset/stm32mp2_reset.c
new file mode 100644
index 0000000..0918df5
--- /dev/null
+++ b/drivers/st/reset/stm32mp2_reset.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+static uint32_t id2reg_offset(unsigned int reset_id)
+{
+	return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
+}
+
+static uint8_t id2reg_bit_pos(unsigned int reset_id)
+{
+	return (uint8_t)(reset_id & GENMASK(4, 0));
+}
+
+static int reset_toggle(uint32_t id, unsigned int to_us, bool reset_status)
+{
+	uint32_t offset = id2reg_offset(id);
+	uint32_t bitmsk = BIT(id2reg_bit_pos(id));
+	uint32_t bit_check;
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (reset_status) {
+		mmio_setbits_32(rcc_base + offset, bitmsk);
+		bit_check = bitmsk;
+	} else {
+		mmio_clrbits_32(rcc_base + offset, bitmsk);
+		bit_check = 0U;
+	}
+
+	if (to_us != 0U) {
+		uint64_t timeout_ref = timeout_init_us(to_us);
+
+		while ((mmio_read_32(rcc_base + offset) & bitmsk) != bit_check) {
+			if (timeout_elapsed(timeout_ref)) {
+				return -ETIMEDOUT;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int stm32mp_reset_assert(uint32_t id, unsigned int to_us)
+{
+	return reset_toggle(id, to_us, true);
+}
+
+int stm32mp_reset_deassert(uint32_t id, unsigned int to_us)
+{
+	return reset_toggle(id, to_us, false);
+}
+
+void __dead2 stm32mp_system_reset(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_GRSTCSETR, RCC_GRSTCSETR_SYSRST);
+
+	/* Loop in case system reset is not immediately caught */
+	while (true) {
+		wfi();
+	}
+}
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
index d52431b..821f600 100644
--- a/fdts/cca_cot_descriptors.dtsi
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -136,30 +136,12 @@
 	images {
 		compatible = "arm, img-descs";
 
-		fw_config {
-			image-id = <FW_CONFIG_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&fw_config_hash>;
-		};
-
 		hw_config {
 			image-id = <HW_CONFIG_ID>;
 			parent = <&cca_content_cert>;
 			hash = <&hw_config_hash>;
 		};
 
-		tb_fw_hash {
-			image-id = <BL2_IMAGE_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&tb_fw_hash>;
-		};
-
-		tb_fw_config {
-			image-id = <TB_FW_CONFIG_ID>;
-			parent = <&cca_content_cert>;
-			hash = <&tb_fw_config_hash>;
-		};
-
 		bl31_image {
 			image-id = <BL31_IMAGE_ID>;
 			parent = <&cca_content_cert>;
diff --git a/fdts/dualroot_cot_descriptors.dtsi b/fdts/dualroot_cot_descriptors.dtsi
new file mode 100644
index 0000000..459a1dd
--- /dev/null
+++ b/fdts/dualroot_cot_descriptors.dtsi
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/dualroot_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		trusted_boot_fw_cert: trusted_boot_fw_cert {
+			root-certificate;
+			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tb_fw_hash: tb_fw_hash {
+				oid = TRUSTED_BOOT_FW_HASH_OID;
+			};
+			tb_fw_config_hash: tb_fw_config_hash {
+				oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+			};
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_key_cert: trusted_key_cert {
+			root-certificate;
+			image-id = <TRUSTED_KEY_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			trusted_world_pk: trusted_world_pk {
+				oid = TRUSTED_WORLD_PK_OID;
+			};
+		};
+
+		scp_fw_key_cert: scp_fw_key_cert {
+			image-id = <SCP_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			scp_fw_content_pk: scp_fw_content_pk {
+				oid = SCP_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		scp_fw_content_cert: scp_fw_content_cert {
+			image-id = <SCP_FW_CONTENT_CERT_ID>;
+			parent = <&scp_fw_key_cert>;
+			signing-key = <&scp_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			scp_fw_hash: scp_fw_hash {
+				oid = SCP_FW_HASH_OID;
+			};
+		};
+
+		soc_fw_key_cert: soc_fw_key_cert {
+			image-id = <SOC_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+			soc_fw_content_pk: soc_fw_content_pk {
+				oid = SOC_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		soc_fw_content_cert: soc_fw_content_cert {
+			image-id = <SOC_FW_CONTENT_CERT_ID>;
+			parent = <&soc_fw_key_cert>;
+			signing-key = <&soc_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			soc_fw_hash: soc_fw_hash {
+				oid = SOC_AP_FW_HASH_OID;
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = SOC_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_os_fw_key_cert: trusted_os_fw_key_cert {
+			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_content_pk: tos_fw_content_pk {
+				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&trusted_os_fw_key_cert>;
+			signing-key = <&tos_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_extra1_hash: tos_fw_extra1_hash {
+				oid = TRUSTED_OS_FW_EXTRA1_HASH_OID;
+			};
+			tos_fw_extra2_hash: tos_fw_extra2_hash {
+				oid = TRUSTED_OS_FW_EXTRA2_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			root-certificate;
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			root-certificate;
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&trusted_boot_fw_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		scp_bl2_image {
+			image-id = <SCP_BL2_IMAGE_ID>;
+			parent = <&scp_fw_content_cert>;
+			hash = <&scp_fw_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		bl32_extra1_image {
+			image-id = <BL32_EXTRA1_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra1_hash>;
+		};
+
+		bl32_extra2_image {
+			image-id = <BL32_EXTRA2_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra2_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	trusted_nv_counter: trusted_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_counter: non_trusted_nv_counter {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 5a82c46..653c75f 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index e1249d4..2827297 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 7a7d461..08fbbb9 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -190,7 +190,6 @@
 		CLK_AXI_PLL2P
 		CLK_MLAHBS_PLL3
 		CLK_CKPER_HSE
-		CLK_RTC_LSE
 		CLK_SDMMC1_PLL4P
 		CLK_SDMMC2_PLL4P
 		CLK_STGEN_HSE
@@ -212,16 +211,9 @@
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
 		DIV(DIV_APB6, 1)
-		DIV(DIV_RTC, 0)
 	>;
 
 	st,pll_vco {
-		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
-			src = < CLK_PLL12_HSE >;
-			divmn = < 2 80 >;
-			frac = < 0x800 >;
-		};
-
 		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
 			src = <CLK_PLL12_HSE>;
 			divmn = <2 65>;
@@ -240,19 +232,6 @@
 		};
 	};
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1:st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-
-		st,pll = < &pll1_cfg1 >;
-
-		pll1_cfg1: pll1_cfg1 {
-			st,pll_vco = < &pll1_vco_1300Mhz >;
-			st,pll_div_pqr = < 0 1 1 >;
-		};
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
 	pll2:st,pll@1 {
 		compatible = "st,stm32mp1-pll";
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index d583672..6f478d4 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include <common/tbbr/tbbr_img_def.h>
@@ -14,12 +14,9 @@
 
 #define DDR_NS_BASE	STM32MP_DDR_BASE
 #ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top or null size */
-#define DDR_SHARE_SIZE	STM32MP_DDR_SHMEM_SIZE
-#define DDR_SHARE_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
-/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
+/* OP-TEE secure memory: located at DDR top */
 #define DDR_SEC_SIZE	STM32MP_DDR_S_SIZE
-#define DDR_SEC_BASE	(DDR_SHARE_BASE - DDR_SEC_SIZE)
+#define DDR_SEC_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SEC_SIZE))
 #define DDR_NS_SIZE	(DDR_SEC_BASE - DDR_NS_BASE)
 #else /* !AARCH32_SP_OPTEE */
 #define DDR_NS_SIZE	DDR_SIZE
@@ -70,10 +67,6 @@
 		memory-ranges = <
 			DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
 			DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
-#if STM32MP15_OPTEE_RSV_SHM
-			DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
-#endif
 			>;
 #else
 		memory-ranges = <
diff --git a/fdts/stm32mp151a-prtt1a.dts b/fdts/stm32mp151a-prtt1a.dts
index 3634620..9742dcb 100644
--- a/fdts/stm32mp151a-prtt1a.dts
+++ b/fdts/stm32mp151a-prtt1a.dts
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * Copyright (C) 2023, Protonic Holland - All Rights Reserved
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
  * Author: David Jander <david@protonic.nl>
  */
 /dts-v1/;
@@ -123,7 +124,7 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts
index f0da350..7135970 100644
--- a/fdts/stm32mp157a-avenger96.dts
+++ b/fdts/stm32mp157a-avenger96.dts
@@ -175,29 +175,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -228,42 +208,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_480Mhz: pll4-vco-480Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 39>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 39 3 11 4 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_480Mhz>;
+			st,pll_div_pqr = <3 11 4>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index d7bcc84..d85221b 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -194,29 +194,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -247,42 +226,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index a0be718..e5d41fc 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -207,29 +207,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -260,42 +240,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 5138868..12846db 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -193,29 +193,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_PLL4P
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		1 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -246,42 +226,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 1)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_600Mhz: pll4-vco-600hz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 49>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 49 5 11 11 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_600Mhz>;
+			st,pll_div_pqr = <5 11 11>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcor-som.dtsi b/fdts/stm32mp15xx-dhcor-som.dtsi
index 8d829a4..2ebfb2d 100644
--- a/fdts/stm32mp15xx-dhcor-som.dtsi
+++ b/fdts/stm32mp15xx-dhcor-som.dtsi
@@ -4,7 +4,7 @@
  * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  * Copyright (C) 2020 Marek Vasut <marex@denx.de>
  * Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include "stm32mp15-pinctrl.dtsi"
@@ -188,29 +188,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -241,42 +221,84 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
-	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */
+	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */ /* @TOCHECK */
+	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 5 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index d8b7c48..bac9e05 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -198,29 +198,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -251,42 +230,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index ef4c3c0..6e27b41 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -185,29 +185,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -238,41 +218,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
diff --git a/fdts/tbbr_cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
index ac39e4e..d11e2be 100644
--- a/fdts/tbbr_cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -190,12 +190,6 @@
 			hash = <&hw_config_hash>;
 		};
 
-		tb_fw_config {
-			image-id = <TB_FW_CONFIG_ID>;
-			parent = <&trusted_boot_fw_cert>;
-			hash = <&tb_fw_config_hash>;
-		};
-
 		scp_bl2_image {
 			image-id = <SCP_BL2_IMAGE_ID>;
 			parent = <&scp_fw_content_cert>;
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index e32d215..fc6fe78 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -265,9 +265,22 @@
 		method = "smc";
 	};
 
-	cpu-pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	cpu-pmu-little {
+		compatible = LIT_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_little>;
+		status = "okay";
+	};
+
+	cpu-pmu-mid {
+		compatible = MID_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+		status = "okay";
+	};
+
+	cpu-pmu-big {
+		compatible = BIG_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+		status = "okay";
 	};
 
 	sram: sram@6000000 {
@@ -278,37 +291,35 @@
 		#size-cells = <1>;
 		ranges = <0 0x0 PLAT_ARM_NSRAM_BASE PLAT_ARM_NSRAM_SIZE>;
 
-		cpu_scp_scmi_mem: scp-shmem@0 {
+		cpu_scp_scmi_a2p: scp-shmem@0 {
 			compatible = "arm,scmi-shmem";
 			reg = <0x0 0x80>;
 		};
 	};
 
 	mbox_db_rx: mhu@MHU_RX_ADDR {
-		compatible = "arm,mhuv2-rx","arm,primecell";
-		reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 0x1000>;
+		compatible = MHU_RX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 MHU_OFFSET>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupts = <GIC_SPI INT_MBOX_RX IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "mhu_rx";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = MHU_RX_INT_NAME;
 	};
 
 	mbox_db_tx: mhu@MHU_TX_ADDR {
-		compatible = "arm,mhuv2-tx","arm,primecell";
-		reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 0x1000>;
+		compatible = MHU_TX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 MHU_OFFSET>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupt-names = "mhu_tx";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupt-names = MHU_TX_INT_NAME;
 	};
 
 	firmware {
 		scmi {
 			compatible = "arm,scmi";
 			mbox-names = "tx", "rx";
-			mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0 >;
-			shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 
@@ -334,21 +345,33 @@
 	gic: interrupt-controller@GIC_CTRL_ADDR {
 		compatible = "arm,gic-v3";
 		#address-cells = <2>;
-		#interrupt-cells = <3>;
+		#interrupt-cells = <4>;
 		#size-cells = <2>;
 		ranges;
 		interrupt-controller;
 		reg = <0x0 0x30000000 0 0x10000>, /* GICD */
 		      <0x0 0x30080000 0 GIC_GICR_OFFSET>; /* GICR */
-		interrupts = <GIC_PPI 0x9 IRQ_TYPE_LEVEL_LOW>;
+		interrupts = <GIC_PPI 0x9 IRQ_TYPE_LEVEL_LOW 0>;
 	};
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
+	};
+
+	spe-pmu-mid {
+		compatible = "arm,statistical-profiling-extension-v1";
+		interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+		status = "disabled";
+	};
+
+	spe-pmu-big {
+		compatible = "arm,statistical-profiling-extension-v1";
+		interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+		status = "disabled";
 	};
 
 	soc_refclk: refclk {
@@ -376,7 +399,7 @@
 	os_uart: serial@2a400000 {
 		compatible = "arm,pl011", "arm,primecell";
 		reg = <0x0 0x2A400000 0x0 UART_OFFSET>;
-		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&soc_uartclk>, <&soc_refclk>;
 		clock-names = "uartclk", "apb_pclk";
 		status = "okay";
@@ -416,7 +439,7 @@
 
 	ethernet: ethernet@18000000 {
 		reg = <0x0 0x18000000 0x0 0x10000>;
-		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
 
 		reg-io-width = <2>;
 		smsc,irq-push-pull;
@@ -448,8 +471,8 @@
 	mmci: mmci@1c050000 {
 		compatible = "arm,pl180", "arm,primecell";
 		reg = <0x0 0x001c050000 0x0 0x1000>;
-		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
 		wp-gpios = <&sysreg 1 0>;
 		bus-width = <4>;
 		max-frequency = <25000000>;
@@ -473,9 +496,9 @@
 	gpu: gpu@2d000000 {
 		compatible = "arm,mali-midgard";
 		reg = <0x0 0x2d000000 0x0 0x200000>;
-		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "JOB", "MMU", "GPU";
 		clocks = <&gpu_core_clk>;
 		clock-names = "shadercores";
@@ -484,9 +507,14 @@
 		scmi-perf-domain = <3>;
 #endif /* TC_SCMI_PD_CTRL_EN */
 
-#if TC_IOMMU_EN
-		iommus = <&smmu_700 0x200>;
-#endif /* TC_IOMMU_EN */
+		pbha {
+			int-id-override = <0 0x22>, <2 0x23>, <4 0x23>, <7 0x22>,
+					  <8 0x22>, <9 0x22>, <10 0x22>, <11 0x22>,
+					  <12 0x22>, <13 0x22>, <16 0x22>, <17 0x32>,
+					  <18 0x32>, <19 0x22>, <20 0x22>, <21 0x32>,
+					  <22 0x32>, <24 0x22>, <28 0x32>;
+			propagate-bits = <0x0f>;
+		};
 	};
 
 	power_model_simple {
@@ -501,30 +529,50 @@
 		thermal-zone = "";
 	};
 
-#if TC_IOMMU_EN
+	smmu_600: smmu@2ce00000 {
+		compatible = "arm,smmu-v3";
+		reg = <0 0x2ce00000 0 0x20000>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 74 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 76 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 77 IRQ_TYPE_EDGE_RISING 0>;
+		interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+		#iommu-cells = <1>;
+		status = "disabled";
+	};
+
 	smmu_700: iommu@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
 		reg = <0x0 0x3f000000 0x0 0x5000000>;
-		interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>;
+		interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 229 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 230 IRQ_TYPE_EDGE_RISING 0>;
 		interrupt-names = "eventq", "cmdq-sync", "gerror";
 		dma-coherent;
+		status = "disabled";
 	};
-#endif /* TC_IOMMU_EN */
+
+	smmu_700_dpu: iommu@4002a00000 {
+		#iommu-cells = <1>;
+		compatible = "arm,smmu-v3";
+		reg = <HI(0x4002a00000) LO(0x4002a00000) 0x0 0x5000000>;
+		interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 482 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 483 IRQ_TYPE_EDGE_RISING 0>;
+		interrupt-names = "eventq", "cmdq-sync", "gerror";
+		dma-coherent;
+		status = "disabled";
+	};
 
 	dp0: display@DPU_ADDR {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "arm,mali-d71";
 		reg = <HI(ADDRESSIFY(DPU_ADDR)) LO(ADDRESSIFY(DPU_ADDR)) 0 0x20000>;
-		interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "DPU";
 		DPU_CLK_ATTR1;
-#if TC_IOMMU_EN
-		iommus = <&smmu_700 0x100>;
-#endif /* TC_IOMMU_EN */
 
 		pl0: pipeline@0 {
 			reg = <0>;
@@ -607,7 +655,7 @@
 
 	trbe {
 		compatible = "arm,trace-buffer-extension";
-		interrupts = <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW>;
+		interrupts = <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW 0>;
 	};
 
 	trusty {
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index 46b0e81..1e14f0b 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -7,6 +7,23 @@
 #define GIC_CTRL_ADDR		2c010000
 #define GIC_GICR_OFFSET		0x200000
 #define UART_OFFSET		0x1000
+
+#ifdef TC_RESOLUTION_1920X1080P60
+
+#define VENCODER_TIMING_CLK 148500000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <1920>;							\
+	vactive = <1080>;							\
+	hfront-porch = <88>;							\
+	hback-porch = <148>;							\
+	hsync-len = <44>;							\
+	vfront-porch = <4>;							\
+	vback-porch = <36>;							\
+	vsync-len = <5>
+
+#else /* TC_RESOLUTION_640X480P60 */
+
 #define VENCODER_TIMING_CLK 25175000
 #define VENCODER_TIMING								\
 	clock-frequency = <VENCODER_TIMING_CLK>;				\
@@ -19,6 +36,8 @@
 	vback-porch = <33>;							\
 	vsync-len = <2>
 
+#endif
+
 / {
 	chosen {
 		stdout-path = "serial0:115200n8";
@@ -35,7 +54,7 @@
 	rtc@1c170000 {
 		compatible = "arm,pl031", "arm,primecell";
 		reg = <0x0 0x1C170000 0x0 0x1000>;
-		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
 	};
@@ -43,7 +62,7 @@
 	kmi@1c060000 {
 		compatible = "arm,pl050", "arm,primecell";
 		reg = <0x0 0x001c060000 0x0 0x1000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
 		clock-names = "KMIREFCLK", "apb_pclk";
 	};
@@ -51,7 +70,7 @@
 	kmi@1c070000 {
 		compatible = "arm,pl050", "arm,primecell";
 		reg = <0x0 0x001c070000 0x0 0x1000>;
-		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
 		clock-names = "KMIREFCLK", "apb_pclk";
 	};
@@ -60,6 +79,6 @@
 		compatible = "virtio,mmio";
 		reg = <0x0 0x1c130000 0x0 0x200>;
 		/* spec lists this wrong */
-		interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
 	};
 };
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index 288b40f..ae37ce3 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -20,9 +20,21 @@
 #endif /* TARGET_FLAVOUR_FPGA */
 #define BIG_CAPACITY			1024
 
-#define INT_MBOX_RX			317
 #define MHU_TX_ADDR			45000000 /* hex */
+#define MHU_TX_COMPAT			"arm,mhuv2-tx","arm,primecell"
+#define MHU_TX_INT_NAME			"mhu_tx"
+
 #define MHU_RX_ADDR			45010000 /* hex */
+#define MHU_RX_COMPAT			"arm,mhuv2-rx","arm,primecell"
+#define MHU_OFFSET			0x1000
+#define MHU_MBOX_CELLS			2
+#define MHU_RX_INT_NUM			317
+#define MHU_RX_INT_NAME			"mhu_rx"
+
+#define LIT_CPU_PMU_COMPATIBLE		"arm,cortex-a520-pmu"
+#define MID_CPU_PMU_COMPATIBLE		"arm,cortex-a720-pmu"
+#define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x4-pmu"
+
 #define MPAM_ADDR			0x1 0x00010000 /* 0x1_0001_0000 */
 #define UARTCLK_FREQ			5000000
 
@@ -185,22 +197,10 @@
 	};
 #endif /* TARGET_FLAVOUR_FPGA */
 
-	cpu-pmu {
-#if TARGET_FLAVOUR_FPGA
-		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
-				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>,
-				     <&CPU8>,  <&CPU9>,  <&CPU10>, <&CPU11>,
-				     <&CPU12>, <&CPU13>;
-#else
-		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
-				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>;
-#endif
-	};
-
 	cmn-pmu {
 		compatible = "arm,ci-700";
 		reg = <0x0 0x50000000 0x0 0x10000000>;
-		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH 0>;
 	};
 
 	mbox_db_rx: mhu@MHU_RX_ADDR {
@@ -211,9 +211,66 @@
 		arm,mhuv2-protocols = <0 1>;
 	};
 
+	firmware {
+		/*
+		 * TC2 does not have a P2A channel, but wiring one was needed to make Linux work
+		 * (by chance). At the time the SCMI driver did not support bidirectional
+		 * mailboxes so as a workaround, the A2P channel was wired for TX communication
+		 * and the synchronous replies would be read asyncrhonously as if coming from
+		 * the P2A channel, while being the actual A2P channel.
+		 *
+		 * This will not work with kernels > 5.15, but keep it around to keep TC2
+		 * working with its target kernel. Newer kernels will still work, but SCMI
+		 * won't as they check that the two regions are distinct.
+		 */
+		scmi {
+			mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0>;
+			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_a2p>;
+		};
+	};
+
+	gic: interrupt-controller@GIC_CTRL_ADDR {
+		ppi-partitions {
+			ppi_partition_little: interrupt-partition-0 {
+				affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>;
+			};
+
+#if TARGET_FLAVOUR_FVP
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU4>, <&CPU5>, <&CPU6>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU7>;
+			};
+#elif TARGET_FLAVOUR_FPGA
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, <&CPU8>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU9>, <&CPU10>, <&CPU11>, <&CPU12>, <&CPU13>;
+			};
+#endif
+		};
+	};
+
+	spe-pmu-big {
+		status = "okay";
+	};
+
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
 	dp0: display@DPU_ADDR {
 #if TC_SCMI_PD_CTRL_EN
 		power-domains = <&scmi_devpd (PLAT_MAX_CPUS_PER_CLUSTER + 2)>;
 #endif
+		iommus = <&smmu_700 0x100>;
+	};
+
+	gpu: gpu@2d000000 {
+		iommus = <&smmu_700 0x200>;
 	};
 };
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index 52b0856..58c8edc 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -14,9 +14,21 @@
 #define MID_CAPACITY			686
 #define BIG_CAPACITY			1024
 
-#define INT_MBOX_RX			300
 #define MHU_TX_ADDR			46040000 /* hex */
+#define MHU_TX_COMPAT			"arm,mhuv3"
+#define MHU_TX_INT_NAME			""
+
 #define MHU_RX_ADDR			46140000 /* hex */
+#define MHU_RX_COMPAT			"arm,mhuv3"
+#define MHU_OFFSET			0x10000
+#define MHU_MBOX_CELLS			3
+#define MHU_RX_INT_NUM			300
+#define MHU_RX_INT_NAME			"combined-mbx"
+
+#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"
+
 #define MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
 #define UARTCLK_FREQ			3750000
 
@@ -59,8 +71,102 @@
 		};
 	};
 
-	cpu-pmu {
-		interrupt-affinity = <&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>;
+	};
+
+	spe-pmu-mid {
+		status = "okay";
+	};
+
+	spe-pmu-big {
+		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>;
+	};
+
+	sram: sram@6000000 {
+		cpu_scp_scmi_p2a: scp-shmem@80 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x80 0x80>;
+		};
+	};
+
+	firmware {
+		scmi {
+			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>;
+		};
+	};
+
+	gic: interrupt-controller@GIC_CTRL_ADDR {
+		ppi-partitions {
+			ppi_partition_little: interrupt-partition-0 {
+				affinity = <&CPU0>, <&CPU1>;
+			};
+
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU6>, <&CPU7>;
+			};
+		};
+	};
+
+#if TARGET_FLAVOUR_FVP
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		status = "okay";
+	};
+#else
+	smmu_600: smmu@2ce00000 {
+		status = "okay";
+	};
+#endif
+
+	dp0: display@DPU_ADDR {
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700_dpu 0x000>, <&smmu_700_dpu 0x100>,
+			 <&smmu_700_dpu 0x200>, <&smmu_700_dpu 0x600>;
+#else /* TARGET_FLAVOUR_FPGA */
+		iommus = <&smmu_600 0>, <&smmu_600 1>, <&smmu_600 2>, <&smmu_600 3>,
+			 <&smmu_600 4>, <&smmu_600 5>, <&smmu_600 6>, <&smmu_600 7>,
+			 <&smmu_600 8>, <&smmu_600 9>;
+#endif
+	};
+
+	gpu: gpu@2d000000 {
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700 0x200>;
+#endif
 	};
 };
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 8e39529..abe34a4 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -16,6 +16,7 @@
 	((unsigned int)(((reg) >> (feat)) & mask))
 
 #define CREATE_FEATURE_SUPPORTED(name, read_func, guard)			\
+__attribute__((always_inline))							\
 static inline bool is_ ## name ## _supported(void)				\
 {										\
 	if ((guard) == FEAT_STATE_DISABLED) {					\
@@ -28,6 +29,7 @@
 }
 
 #define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+__attribute__((always_inline))							\
 static inline bool is_ ## name ## _present(void)				\
 {										\
 	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
@@ -68,6 +70,7 @@
  */
 
 /* GENTIMER */
+__attribute__((always_inline))
 static inline bool is_armv7_gentimer_present(void)
 {
 	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT,
@@ -111,6 +114,7 @@
 		      ID_DFR0_PERFMON_MASK, 3U)
 
 /* FEAT_MTPMU */
+__attribute__((always_inline))
 static inline bool is_feat_mtpmu_present(void)
 {
 	unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT,
@@ -124,39 +128,71 @@
  * code. In fact, EL2 context switching is only needed for AArch64 (since
  * there is no secure AArch32 EL2), so just disable these features here.
  */
+__attribute__((always_inline))
 static inline bool is_feat_twed_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ecv_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ecv_v2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_csv2_2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_csv2_3_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ras_supported(void) { return false; }
 
 /* The following features are supported in AArch64 only. */
+__attribute__((always_inline))
 static inline bool is_feat_vhe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sel2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_fgt_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_tcr2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_spe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_rng_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_gcs_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_mte2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_mpam_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_hcx_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sve_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_brbe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_trbe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_nv2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sme_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sme2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s2poe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s1poe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sxpoe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s2pie_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s1pie_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_uao_present(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_nmi_present(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ebep_present(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sebep_present(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 4eb54ed..52ed2b9 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -114,9 +114,14 @@
  * Definitions for EL2 system registers for save/restore routine
  ******************************************************************************/
 #define CNTPOFF_EL2		S3_4_C14_C0_6
-#define HAFGRTR_EL2		S3_4_C3_C1_6
+#define HDFGRTR2_EL2		S3_4_C3_C1_0
+#define HDFGWTR2_EL2		S3_4_C3_C1_1
+#define HFGRTR2_EL2		S3_4_C3_C1_2
+#define HFGWTR2_EL2		S3_4_C3_C1_3
 #define HDFGRTR_EL2		S3_4_C3_C1_4
 #define HDFGWTR_EL2		S3_4_C3_C1_5
+#define HAFGRTR_EL2		S3_4_C3_C1_6
+#define HFGITR2_EL2		S3_4_C3_C1_7
 #define HFGITR_EL2		S3_4_C1_C1_6
 #define HFGRTR_EL2		S3_4_C1_C1_4
 #define HFGWTR_EL2		S3_4_C1_C1_5
@@ -224,6 +229,11 @@
 #define EL_IMPL_A64ONLY		ULL(1)
 #define EL_IMPL_A64_A32		ULL(2)
 
+/* ID_AA64DFR0_EL1.DebugVer definitions */
+#define ID_AA64DFR0_DEBUGVER_SHIFT		U(0)
+#define ID_AA64DFR0_DEBUGVER_MASK		ULL(0xf)
+#define DEBUGVER_V8P9_IMPLEMENTED		ULL(0xb)
+
 /* ID_AA64DFR0_EL1.TraceVer definitions */
 #define ID_AA64DFR0_TRACEVER_SHIFT	U(4)
 #define ID_AA64DFR0_TRACEVER_MASK	ULL(0xf)
@@ -238,7 +248,7 @@
 #define ID_AA64DFR0_PMUVER_SHIFT	U(8)
 #define ID_AA64DFR0_PMUVER_MASK		U(0xf)
 #define ID_AA64DFR0_PMUVER_PMUV3	U(1)
-#define ID_AA64DFR0_PMUVER_PMUV3P7	U(7)
+#define ID_AA64DFR0_PMUVER_PMUV3P8	U(8)
 #define ID_AA64DFR0_PMUVER_IMP_DEF	U(0xf)
 
 /* ID_AA64DFR0_EL1.SEBEP definitions */
@@ -326,6 +336,7 @@
 
 #define ID_AA64MMFR0_EL1_FGT_SHIFT		U(56)
 #define ID_AA64MMFR0_EL1_FGT_MASK		ULL(0xf)
+#define FGT2_IMPLEMENTED			ULL(0x2)
 #define FGT_IMPLEMENTED				ULL(0x1)
 #define FGT_NOT_IMPLEMENTED			ULL(0x0)
 
@@ -569,6 +580,7 @@
 /* SCR definitions */
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
 #define SCR_NSE_SHIFT		U(62)
+#define SCR_FGTEN2_BIT		(UL(1) << 59)
 #define SCR_NSE_BIT		(ULL(1) << SCR_NSE_SHIFT)
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
@@ -607,6 +619,7 @@
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
+#define MDCR_EBWE_BIT		(ULL(1) << 43)
 #define MDCR_EnPMSN_BIT		(ULL(1) << 36)
 #define MDCR_MPMX_BIT		(ULL(1) << 35)
 #define MDCR_MCCD_BIT		(ULL(1) << 34)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index ddc1c80..f03c9d5 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -16,6 +16,7 @@
 	((unsigned int)(((reg) >> (feat)) & mask))
 
 #define CREATE_FEATURE_SUPPORTED(name, read_func, guard)			\
+__attribute__((always_inline))							\
 static inline bool is_ ## name ## _supported(void)				\
 {										\
 	if ((guard) == FEAT_STATE_DISABLED) {					\
@@ -28,6 +29,7 @@
 }
 
 #define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+__attribute__((always_inline))							\
 static inline bool is_ ## name ## _present(void)				\
 {										\
 	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
@@ -130,8 +132,11 @@
  * +----------------------------+
  * |	FEAT_MTPMU		|
  * +----------------------------+
+ * |	FEAT_FGT2		|
+ * +----------------------------+
  */
 
+__attribute__((always_inline))
 static inline bool is_armv7_gentimer_present(void)
 {
 	/* The Generic Timer is always present in an ARMv8-A implementation */
@@ -160,6 +165,7 @@
 			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT)), 1U)
 
 /* PAUTH */
+__attribute__((always_inline))
 static inline bool is_armv8_3_pauth_present(void)
 {
 	uint64_t mask_id_aa64isar1 =
@@ -216,6 +222,10 @@
 CREATE_FEATURE_FUNCS(feat_fgt, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
 		     ID_AA64MMFR0_EL1_FGT_MASK, 1U, ENABLE_FEAT_FGT)
 
+/* FEAT_FGT2: Fine-grained traps extended */
+CREATE_FEATURE_FUNCS(feat_fgt2, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
+		     ID_AA64MMFR0_EL1_FGT_MASK, FGT2_IMPLEMENTED, ENABLE_FEAT_FGT2)
+
 /* FEAT_ECV: Enhanced Counter Virtualization */
 CREATE_FEATURE_FUNCS(feat_ecv, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
 		     ID_AA64MMFR0_EL1_ECV_MASK, 1U, ENABLE_FEAT_ECV)
@@ -238,6 +248,7 @@
 CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
 		     ID_AA64MMFR3_EL1_S1POE_MASK, 1U, ENABLE_FEAT_S1POE)
 
+__attribute__((always_inline))
 static inline bool is_feat_sxpoe_supported(void)
 {
 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
@@ -251,6 +262,7 @@
 CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
 		     ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
 
+__attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void)
 {
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
@@ -277,6 +289,7 @@
  * 0x11: v1.1 Armv8.4 or later
  *
  */
+__attribute__((always_inline))
 static inline bool is_feat_mpam_present(void)
 {
 	unsigned int ret = (unsigned int)((((read_id_aa64pfr0_el1() >>
@@ -288,6 +301,23 @@
 
 CREATE_FEATURE_SUPPORTED(feat_mpam, is_feat_mpam_present, ENABLE_FEAT_MPAM)
 
+/*
+ * FEAT_DebugV8P9: Debug extension. This function checks the field 3:0 of
+ * ID_AA64DFR0 Aarch64 Debug Feature Register 0 for the version of
+ * Feat_Debug supported. The value of the field determines feature presence
+ *
+ * 0b0110 - Arm v8.0 debug
+ * 0b0111 - Arm v8.0 debug architecture with Virtualization host extensions
+ * 0x1000 - FEAT_Debugv8p2 is supported
+ * 0x1001 - FEAT_Debugv8p4 is supported
+ * 0x1010 - FEAT_Debugv8p8 is supported
+ * 0x1011 - FEAT_Debugv8p9 is supported
+ *
+ */
+CREATE_FEATURE_FUNCS(feat_debugv8p9, id_aa64dfr0_el1, ID_AA64DFR0_DEBUGVER_SHIFT,
+		ID_AA64DFR0_DEBUGVER_MASK, DEBUGVER_V8P9_IMPLEMENTED,
+		ENABLE_FEAT_DEBUGV8P9)
+
 /* FEAT_HCX: Extended Hypervisor Configuration Register */
 CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
 		     ID_AA64MMFR1_EL1_HCX_MASK, 1U, ENABLE_FEAT_HCX)
@@ -375,6 +405,7 @@
  * Function to get hardware granularity support
  ******************************************************************************/
 
+__attribute__((always_inline))
 static inline bool is_feat_tgran4K_present(void)
 {
 	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
@@ -385,6 +416,7 @@
 CREATE_FEATURE_PRESENT(feat_tgran16K, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
 		       ID_AA64MMFR0_EL1_TGRAN16_MASK, TGRAN16_IMPLEMENTED)
 
+__attribute__((always_inline))
 static inline bool is_feat_tgran64K_present(void)
 {
 	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
@@ -397,6 +429,7 @@
 		      ID_AA64DFR0_PMUVER_MASK, 1U)
 
 /* FEAT_MTPMU */
+__attribute__((always_inline))
 static inline bool is_feat_mtpmu_present(void)
 {
 	unsigned int mtpmu = ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT,
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 59adc7c..a892654 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -639,6 +639,13 @@
 /* Armv8.9 system registers */
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
 
+/* Armv8.9 FEAT_FGT2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgrtr2_el2, HDFGRTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgwtr2_el2, HDFGWTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgitr2_el2, HFGITR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr2_el2, HFGRTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr2_el2, HFGWTR2_EL2)
+
 /* FEAT_TCR2 Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el1, TCR2_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
@@ -807,15 +814,6 @@
 	TLBIRPALOS(addr, TLBI_SZ_512M);
 }
 
-/*
- * Invalidate TLBs of GPT entries by Physical address, last level.
- *
- * @pa: the starting address for the range
- *      of invalidation
- * @size: size of the range of invalidation
- */
-void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
-
 /* Previously defined accessor functions with incomplete register names  */
 
 #define read_current_el()	read_CurrentEl()
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
index 9f82399..b9b0e3d 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -408,7 +408,7 @@
 	 * -----------------------------------------------------------
 	 */
 	isb
-	ldp	x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+	ldp	x28, x29, [sp, #CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1]
 	msr	sctlr_el1, x28
 	isb
 	msr	tcr_el1, x29
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 1a3e9b6..60c5a0c 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -88,21 +88,8 @@
 	 * 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.
-	 *
-	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
-	 *  privileged debug from S-EL1.
-	 *
-	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
-	 *  access to the powerdown debug registers do not trap to EL3.
-	 *
-	 * MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
-	 *  debug registers, other than those registers that are controlled by
-	 *  MDCR_EL3.TDOSA.
 	 */
-	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
-		      MDCR_SPD32(MDCR_SPD32_DISABLE)) & \
-		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT))
-
+	mov_imm	x0, (MDCR_EL3_RESET_VAL | MDCR_SDD_BIT)
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
@@ -450,7 +437,7 @@
 	 * -----------------------------------------------------------
 	 */
 	isb
-	ldp	x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+	ldp	x28, x29, [sp, #CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1]
 	msr	sctlr_el1, x28
 	isb
 	msr	tcr_el1, x29
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index 88302fd..d6c1a2a 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,10 @@
 #define SENDER_REG_STAT(_channel)	(0x20 * (_channel))
 #define SENDER_REG_SET(_channel)	((0x20 * (_channel)) + 0xC)
 
+#define MHU_V3_PBX_PDBCW_PAGE_OFFSET		UL(0x1000)
+#define MHU_V3_SENDER_REG_SET(_channel)		(MHU_V3_PBX_PDBCW_PAGE_OFFSET + \
+						 SENDER_REG_SET(_channel))
+
 /* Helper macro to ring doorbell */
 #define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
 		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
diff --git a/include/drivers/arm/fvp/fvp_cpu_pwr.h b/include/drivers/arm/fvp/fvp_cpu_pwr.h
new file mode 100644
index 0000000..488be18
--- /dev/null
+++ b/include/drivers/arm/fvp/fvp_cpu_pwr.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_CPU_PWR_H
+#define FVP_CPU_PWR_H
+
+#ifndef __ASSEMBLER__
+#include <stdbool.h>
+#include <stdint.h>
+
+#if __aarch64__
+bool check_cpupwrctrl_el1_is_available(void);
+#endif /* __aarch64__ */
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CPUPWRCTLR_EL1                  S3_0_C15_C2_7
+#define CPUPWRCTLR_EL1_CORE_PWRDN_BIT   U(1)
+
+#endif /* FVP_CPU_PWR_H */
diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h
index b4f2d22..019ae17 100644
--- a/include/drivers/auth/tbbr_cot_common.h
+++ b/include/drivers/auth/tbbr_cot_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020,2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,10 +21,10 @@
 extern auth_param_type_desc_t raw_data;
 
 extern auth_param_type_desc_t tb_fw_hash;
+extern auth_param_type_desc_t hw_config_hash;
 extern auth_param_type_desc_t tb_fw_config_hash;
 extern auth_param_type_desc_t fw_config_hash;
 
 extern const auth_img_desc_t trusted_boot_fw_cert;
-extern const auth_img_desc_t hw_config;
 
 #endif /* TBBR_COT_COMMON_H */
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index 6452725..8bf3b78 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -280,9 +280,6 @@
 #define SDMMC_CDN(_reg)				(SDMMC_CDN_REG_BASE + \
 								(SDMMC_CDN_##_reg))
 
-/* Refer to atf/tools/cert_create/include/debug.h */
-#define BIT_32(nr)					(U(1) << (nr))
-
 /* MMC Peripheral Definition */
 #define SOCFPGA_MMC_BLOCK_SIZE		U(8192)
 #define SOCFPGA_MMC_BLOCK_MASK		(SOCFPGA_MMC_BLOCK_SIZE - U(1))
diff --git a/include/drivers/clk.h b/include/drivers/clk.h
index a18f41f..4db20f8 100644
--- a/include/drivers/clk.h
+++ b/include/drivers/clk.h
@@ -13,15 +13,20 @@
 	int (*enable)(unsigned long id);
 	void (*disable)(unsigned long id);
 	unsigned long (*get_rate)(unsigned long id);
+	int (*set_rate)(unsigned long id, unsigned long rate,
+			unsigned long *orate);
 	int (*get_parent)(unsigned long id);
+	int (*set_parent)(unsigned long id, unsigned long parent_id);
 	bool (*is_enabled)(unsigned long id);
 };
 
 int clk_enable(unsigned long id);
 void clk_disable(unsigned long id);
 unsigned long clk_get_rate(unsigned long id);
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate);
 bool clk_is_enabled(unsigned long id);
 int clk_get_parent(unsigned long id);
+int clk_set_parent(unsigned long id, unsigned long parent_id);
 
 void clk_register(const struct clk_ops *ops);
 
diff --git a/include/drivers/measured_boot/rse/dice_prot_env.h b/include/drivers/measured_boot/rse/dice_prot_env.h
index 6f754f5..e5aef51 100644
--- a/include/drivers/measured_boot/rse/dice_prot_env.h
+++ b/include/drivers/measured_boot/rse/dice_prot_env.h
@@ -27,6 +27,7 @@
 	bool allow_new_context_to_derive;
 	bool retain_parent_context;
 	bool create_certificate;
+	int target_locality;
 	void *pk_oid;
 };
 
@@ -43,7 +44,7 @@
 /* Child components inherit their first valid context handle from their parents.
  * How to share context handle is platform specific.
  */
-void plat_dpe_share_context_handle(int *ctx_handle);
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle);
 void plat_dpe_get_context_handle(int *ctx_handle);
 
 #endif /* DICE_PROT_ENV_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
new file mode 100644
index 0000000..d879f5b
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef S32CC_CLK_DRV_H
+#define S32CC_CLK_DRV_H
+
+int s32cc_init_early_clks(void);
+
+#endif
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
new file mode 100644
index 0000000..633f173
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_IDS_H
+#define S32CC_CLK_IDS_H
+
+#include <stdint.h>
+#include <lib/utils_def.h>
+
+/**
+ * Clock ID encoding:
+ *     31:30 bits = Type of the clock
+ *     29:0  bits = Clock ID within the clock category
+ */
+#define S32CC_CLK_ID_MASK	GENMASK_64(29U, 0U)
+#define S32CC_CLK_TYPE_MASK	GENMASK_64(31U, 30U)
+#define S32CC_CLK_ID(ID)	(((unsigned long)(ID)) & S32CC_CLK_ID_MASK)
+#define S32CC_CLK_TYPE(ID)	(((unsigned long)(ID)) & S32CC_CLK_TYPE_MASK)
+#define S32CC_CLK(TAG, ID)	(S32CC_CLK_ID(ID) | (S32CC_CLK_TYPE((TAG) << 30U)))
+#define S32CC_HW_CLK(ID)	S32CC_CLK(0UL, U(ID))
+#define S32CC_SW_CLK(SUB, ID)	S32CC_CLK(2UL | ((SUB) & 1UL), U(ID))
+
+/* SW clocks subcategories */
+#define S32CC_ARCH_CLK(ID)	S32CC_SW_CLK(0UL, ID)
+#define S32CC_PLAT_CLK(ID)	S32CC_SW_CLK(1UL, ID)
+
+/* IDs for clock selectors listed in S32CC Reference Manuals  */
+#define S32CC_CLK_FIRC				S32CC_HW_CLK(0)
+#define S32CC_CLK_SIRC				S32CC_HW_CLK(1)
+#define S32CC_CLK_FXOSC				S32CC_HW_CLK(2)
+#define S32CC_CLK_ARM_PLL_PHI0			S32CC_HW_CLK(4)
+#define S32CC_CLK_ARM_PLL_PHI1			S32CC_HW_CLK(5)
+#define S32CC_CLK_ARM_PLL_PHI2			S32CC_HW_CLK(6)
+#define S32CC_CLK_ARM_PLL_PHI3			S32CC_HW_CLK(7)
+#define S32CC_CLK_ARM_PLL_PHI4			S32CC_HW_CLK(8)
+#define S32CC_CLK_ARM_PLL_PHI5			S32CC_HW_CLK(9)
+#define S32CC_CLK_ARM_PLL_PHI6			S32CC_HW_CLK(10)
+#define S32CC_CLK_ARM_PLL_PHI7			S32CC_HW_CLK(11)
+#define S32CC_CLK_ARM_PLL_DFS1			S32CC_HW_CLK(12)
+#define S32CC_CLK_ARM_PLL_DFS2			S32CC_HW_CLK(13)
+#define S32CC_CLK_ARM_PLL_DFS3			S32CC_HW_CLK(14)
+#define S32CC_CLK_ARM_PLL_DFS4			S32CC_HW_CLK(15)
+#define S32CC_CLK_ARM_PLL_DFS5			S32CC_HW_CLK(16)
+#define S32CC_CLK_ARM_PLL_DFS6			S32CC_HW_CLK(17)
+#define S32CC_CLK_PERIPH_PLL_PHI0		S32CC_HW_CLK(18)
+#define S32CC_CLK_PERIPH_PLL_PHI1		S32CC_HW_CLK(19)
+#define S32CC_CLK_PERIPH_PLL_PHI2		S32CC_HW_CLK(20)
+#define S32CC_CLK_PERIPH_PLL_PHI3		S32CC_HW_CLK(21)
+#define S32CC_CLK_PERIPH_PLL_PHI4		S32CC_HW_CLK(22)
+#define S32CC_CLK_PERIPH_PLL_PHI5		S32CC_HW_CLK(23)
+#define S32CC_CLK_PERIPH_PLL_PHI6		S32CC_HW_CLK(24)
+#define S32CC_CLK_PERIPH_PLL_PHI7		S32CC_HW_CLK(25)
+#define S32CC_CLK_PERIPH_PLL_DFS1		S32CC_HW_CLK(26)
+#define S32CC_CLK_PERIPH_PLL_DFS2		S32CC_HW_CLK(27)
+#define S32CC_CLK_PERIPH_PLL_DFS3		S32CC_HW_CLK(28)
+#define S32CC_CLK_PERIPH_PLL_DFS4		S32CC_HW_CLK(29)
+#define S32CC_CLK_PERIPH_PLL_DFS5		S32CC_HW_CLK(30)
+#define S32CC_CLK_PERIPH_PLL_DFS6		S32CC_HW_CLK(31)
+#define S32CC_CLK_FTM0_EXT_REF			S32CC_HW_CLK(34)
+#define S32CC_CLK_FTM1_EXT_REF			S32CC_HW_CLK(35)
+#define S32CC_CLK_DDR_PLL_PHI0			S32CC_HW_CLK(36)
+#define S32CC_CLK_GMAC0_EXT_TX			S32CC_HW_CLK(37)
+#define S32CC_CLK_GMAC0_EXT_RX			S32CC_HW_CLK(38)
+#define S32CC_CLK_GMAC0_EXT_REF			S32CC_HW_CLK(39)
+#define S32CC_CLK_SERDES0_LANE0_TX		S32CC_HW_CLK(40)
+#define S32CC_CLK_SERDES0_LANE0_CDR		S32CC_HW_CLK(41)
+#define S32CC_CLK_GMAC0_EXT_TS			S32CC_HW_CLK(44)
+#define S32CC_CLK_GMAC0_REF_DIV			S32CC_HW_CLK(45)
+
+/* Software defined clock IDs */
+#define S32CC_CLK_ARM_PLL_MUX			S32CC_ARCH_CLK(0)
+#define S32CC_CLK_ARM_PLL_VCO			S32CC_ARCH_CLK(1)
+
+/* ARM CGM1 clocks */
+#define S32CC_CLK_MC_CGM1_MUX0			S32CC_ARCH_CLK(2)
+#define S32CC_CLK_A53_CORE			S32CC_ARCH_CLK(3)
+#define S32CC_CLK_A53_CORE_DIV2			S32CC_ARCH_CLK(4)
+#define S32CC_CLK_A53_CORE_DIV10		S32CC_ARCH_CLK(5)
+
+#endif /* S32CC_CLK_IDS_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
new file mode 100644
index 0000000..41fc6f4
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2020-2024 NXP
+ */
+#ifndef S32CC_CLK_MODULES_H
+#define S32CC_CLK_MODULES_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define MHZ	UL(1000000)
+#define GHZ	(UL(1000) * MHZ)
+
+enum s32cc_clkm_type {
+	s32cc_osc_t,
+	s32cc_clk_t,
+	s32cc_pll_t,
+	s32cc_pll_out_div_t,
+	s32cc_clkmux_t,
+	s32cc_shared_clkmux_t,
+	s32cc_fixed_div_t,
+};
+
+enum s32cc_clk_source {
+	S32CC_FIRC,
+	S32CC_FXOSC,
+	S32CC_SIRC,
+	S32CC_ARM_PLL,
+	S32CC_CGM1,
+};
+
+struct s32cc_clk_obj {
+	enum s32cc_clkm_type type;
+	uint32_t refcount;
+};
+
+struct s32cc_osc {
+	struct s32cc_clk_obj desc;
+	enum s32cc_clk_source source;
+	unsigned long freq;
+	void *base;
+};
+
+#define S32CC_OSC_INIT(SOURCE)       \
+{                                    \
+	.desc = {                    \
+		.type = s32cc_osc_t, \
+	},                           \
+	.source = (SOURCE),          \
+}
+
+struct s32cc_clkmux {
+	struct s32cc_clk_obj desc;
+	enum s32cc_clk_source module;
+	uint8_t index; /* Mux index in parent module */
+	unsigned long source_id; /* Selected source */
+	uint8_t nclks; /* Number of input clocks */
+	unsigned long clkids[5]; /* IDs of the input clocks */
+};
+
+#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
+{                                                               \
+	.desc = {                                               \
+		.type = (TYPE),                                 \
+	},                                                      \
+	.module = (MODULE),                                     \
+	.index = (INDEX),                                       \
+	.nclks = (NCLKS),                                       \
+	.clkids = {__VA_ARGS__},                                \
+}
+
+#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
+	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
+			       INDEX, NCLKS, __VA_ARGS__)
+
+#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
+	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
+			       INDEX, NCLKS, __VA_ARGS__)
+
+struct s32cc_pll {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *source;
+	enum s32cc_clk_source instance;
+	unsigned long vco_freq;
+	uint32_t ndividers;
+	uintptr_t base;
+};
+
+#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
+{                                                        \
+	.desc = {                                        \
+		.type = s32cc_pll_t,                     \
+	},                                               \
+	.source = &(PLL_MUX_CLK).desc,                   \
+	.instance = (INSTANCE),                          \
+	.ndividers = (NDIVIDERS),                        \
+}
+
+struct s32cc_pll_out_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t index;
+	unsigned long freq;
+};
+
+#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_pll_out_div_t,   \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.index = (INDEX),                      \
+}
+
+#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_pll_out_div_t,   \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.index = (INDEX),                      \
+}
+
+struct s32cc_fixed_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t rate_div;
+};
+
+#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_fixed_div_t,     \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.rate_div = (RATE_DIV),                \
+}
+
+struct s32cc_clk {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *module;
+	struct s32cc_clk *pclock;
+	unsigned long min_freq;
+	unsigned long max_freq;
+};
+
+struct s32cc_clk_array {
+	unsigned long type_mask;
+	struct s32cc_clk **clks;
+	size_t n_clks;
+};
+
+#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
+{                                                      \
+	.desc = {                                      \
+		.type = s32cc_clk_t,                   \
+	},                                             \
+	.module = &(PARENT_MODULE).desc,               \
+	.min_freq = (MIN_F),                           \
+	.max_freq = (MAX_F),                           \
+}
+
+#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
+	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
+
+#define S32CC_MODULE_CLK(PARENT_MODULE) \
+	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
+
+static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t osc_addr;
+
+	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
+	return (struct s32cc_osc *)osc_addr;
+}
+
+static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t clk_addr;
+
+	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
+	return (struct s32cc_clk *)clk_addr;
+}
+
+static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
+{
+	const struct s32cc_clk_obj *module;
+
+	module = clk->module;
+	if (module == NULL) {
+		return false;
+	}
+
+	return (module->type == s32cc_clkmux_t) ||
+	    (module->type == s32cc_shared_clkmux_t);
+}
+
+static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t cmux_addr;
+
+	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
+	return (struct s32cc_clkmux *)cmux_addr;
+}
+
+static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
+{
+	if (!is_s32cc_clk_mux(clk)) {
+		return NULL;
+	}
+
+	return s32cc_obj2clkmux(clk->module);
+}
+
+static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t pll_addr;
+
+	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
+	return (struct s32cc_pll *)pll_addr;
+}
+
+static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t plldiv_addr;
+
+	plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
+	return (struct s32cc_pll_out_div *)plldiv_addr;
+}
+
+static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t fdiv_addr;
+
+	fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
+	return (struct s32cc_fixed_div *)fdiv_addr;
+}
+
+#endif /* S32CC_CLK_MODULES_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
new file mode 100644
index 0000000..6a90406
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_UTILS_H
+#define S32CC_CLK_UTILS_H
+
+#include <s32cc-clk-modules.h>
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id);
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
+
+void s32cc_clk_register_drv(void);
+
+#endif /* S32CC_CLK_UTILS_H */
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index eeef9da..ef4eb04 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #define GPIO_TYPE_OFFSET	U(0x04)
 #define GPIO_SPEED_OFFSET	U(0x08)
 #define GPIO_PUPD_OFFSET	U(0x0C)
+#define GPIO_IDR_OFFSET		U(0x10)
 #define GPIO_OD_OFFSET		U(0x14)
 #define GPIO_BSRR_OFFSET	U(0x18)
 #define GPIO_AFRL_OFFSET	U(0x20)
@@ -58,6 +59,16 @@
 int dt_set_pinctrl_config(int node);
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
 void set_gpio_reset_cfg(uint32_t bank, uint32_t pin);
+
+enum gpio_level {
+	GPIO_LEVEL_LOW,
+	GPIO_LEVEL_HIGH
+};
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level);
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin);
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status);
 #endif /*__ASSEMBLER__*/
 
 #endif /* STM32_GPIO_H */
diff --git a/include/drivers/st/stm32mp25_rcc.h b/include/drivers/st/stm32mp25_rcc.h
index 9dd25f3..d5d228c 100644
--- a/include/drivers/st/stm32mp25_rcc.h
+++ b/include/drivers/st/stm32mp25_rcc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -426,7 +426,7 @@
 #define RCC_USB2CFGR				U(0x7FC)
 #define RCC_USB2PHY1CFGR			U(0x800)
 #define RCC_USB2PHY2CFGR			U(0x804)
-#define RCC_USB3DRDCFGR				U(0x808)
+#define RCC_USB3DRCFGR				U(0x808)
 #define RCC_USB3PCIEPHYCFGR			U(0x80C)
 #define RCC_PCIECFGR				U(0x810)
 #define RCC_USBTCCFGR				U(0x814)
@@ -459,7 +459,6 @@
 #define RCC_IWDG5CFGR				U(0x898)
 #define RCC_WWDG1CFGR				U(0x89C)
 #define RCC_WWDG2CFGR				U(0x8A0)
-#define RCC_BUSPERFMCFGR			U(0x8A4)
 #define RCC_VREFCFGR				U(0x8A8)
 #define RCC_TMPSENSCFGR				U(0x8AC)
 #define RCC_CRCCFGR				U(0x8B4)
@@ -2352,11 +2351,13 @@
 /* RCC_C1SREQSETR register fields */
 #define RCC_C1SREQSETR_STPREQ_P0		BIT(0)
 #define RCC_C1SREQSETR_STPREQ_P1		BIT(1)
+#define RCC_C1SREQSETR_STPREQ_MASK		GENMASK_32(1, 0)
 #define RCC_C1SREQSETR_ESLPREQ			BIT(16)
 
 /* RCC_C1SREQCLRR register fields */
 #define RCC_C1SREQCLRR_STPREQ_P0		BIT(0)
 #define RCC_C1SREQCLRR_STPREQ_P1		BIT(1)
+#define RCC_C1SREQCLRR_STPREQ_MASK		GENMASK_32(1, 0)
 #define RCC_C1SREQCLRR_ESLPREQ			BIT(16)
 
 /* RCC_CPUBOOTCR register fields */
@@ -2401,12 +2402,12 @@
 #define RCC_BDCR_LSEDRV_WIDTH			2
 
 /* RCC_D3DCR register fields */
-#define RCC_D3DCR_CSION				BIT(0)
-#define RCC_D3DCR_CSIKERON			BIT(1)
-#define RCC_D3DCR_CSIRDY			BIT(2)
+#define RCC_D3DCR_MSION				BIT(0)
+#define RCC_D3DCR_MSIKERON			BIT(1)
+#define RCC_D3DCR_MSIRDY			BIT(2)
 #define RCC_D3DCR_D3PERCKSEL_MASK		GENMASK_32(17, 16)
 #define RCC_D3DCR_D3PERCKSEL_SHIFT		16
-#define RCC_D3DCR_CSIRDY_BIT			2
+#define RCC_D3DCR_MSIRDY_BIT			2
 
 /* RCC_D3DSR register fields */
 #define RCC_D3DSR_D3STATE_MASK			GENMASK_32(1, 0)
@@ -3458,11 +3459,11 @@
 #define RCC_USB2PHYxCFGR_USB2PHY1STPEN		BIT(4)
 #define RCC_USB2PHYxCFGR_USB2PHY1CKREFSEL	BIT(15)
 
-/* RCC_USB3DRDCFGR register fields */
-#define RCC_USB3DRDCFGR_USB3DRDRST		BIT(0)
-#define RCC_USB3DRDCFGR_USB3DRDEN		BIT(1)
-#define RCC_USB3DRDCFGR_USB3DRDLPEN		BIT(2)
-#define RCC_USB3DRDCFGR_USB3DRDSTPEN		BIT(4)
+/* RCC_USB3DRCFGR register fields */
+#define RCC_USB3DRCFGR_USB3DRRST		BIT(0)
+#define RCC_USB3DRCFGR_USB3DREN			BIT(1)
+#define RCC_USB3DRCFGR_USB3DRLPEN		BIT(2)
+#define RCC_USB3DRCFGR_USB3DRSTPEN		BIT(4)
 
 /* RCC_USB3PCIEPHYCFGR register fields */
 #define RCC_USB3PCIEPHYCFGR_USB3PCIEPHYRST	BIT(0)
@@ -3647,11 +3648,6 @@
 #define RCC_WWDG2CFGR_WWDG2LPEN			BIT(2)
 #define RCC_WWDG2CFGR_WWDG2AMEN			BIT(3)
 
-/* RCC_BUSPERFMCFGR register fields */
-#define RCC_BUSPERFMCFGR_BUSPERFMRST		BIT(0)
-#define RCC_BUSPERFMCFGR_BUSPERFMEN		BIT(1)
-#define RCC_BUSPERFMCFGR_BUSPERFMLPEN		BIT(2)
-
 /* RCC_VREFCFGR register fields */
 #define RCC_VREFCFGR_VREFRST			BIT(0)
 #define RCC_VREFCFGR_VREFEN			BIT(1)
diff --git a/include/drivers/st/stm32mp2_clk.h b/include/drivers/st/stm32mp2_clk.h
new file mode 100644
index 0000000..b9226cd
--- /dev/null
+++ b/include/drivers/st/stm32mp2_clk.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_CLK_H
+#define STM32MP2_CLK_H
+
+#include <platform_def.h>
+
+enum stm32mp_osc_id {
+	_HSI,
+	_HSE,
+	_CSI,
+	_LSI,
+	_LSE,
+	_I2S_CKIN,
+	_SPDIF_SYMB,
+	NB_OSC,
+	_UNKNOWN_OSC_ID = 0xFF
+};
+
+extern const char *stm32mp_osc_node_label[NB_OSC];
+
+enum pll_cfg {
+	FBDIV,
+	REFDIV,
+	POSTDIV1,
+	POSTDIV2,
+	PLLCFG_NB
+};
+
+enum pll_csg {
+	DIVVAL,
+	SPREAD,
+	DOWNSPREAD,
+	PLLCSG_NB
+};
+
+int stm32mp2_clk_init(void);
+int stm32mp2_pll1_disable(void);
+
+#endif /* STM32MP2_CLK_H */
diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h
index 61286b2..8fd5ed1 100644
--- a/include/drivers/st/stm32mp_clkfunc.h
+++ b/include/drivers/st/stm32mp_clkfunc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,8 +29,6 @@
 unsigned long fdt_get_uart_clock_freq(uintptr_t instance);
 
 void stm32mp_stgen_config(unsigned long rate);
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms);
-unsigned long long stm32mp_stgen_get_counter(void);
+void stm32mp_stgen_restore_rate(void);
 
 #endif /* STM32MP_CLKFUNC_H */
diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h
index 8444805..a8648b4 100644
--- a/include/drivers/st/stm32mp_reset.h
+++ b/include/drivers/st/stm32mp_reset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,4 +47,9 @@
 	(void)stm32mp_reset_deassert(reset_id, 0U);
 }
 
+/*
+ * Manage system reset control
+ */
+void __dead2 stm32mp_system_reset(void);
+
 #endif /* STM32MP_RESET_H */
diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h
index 1d5bb78..031e432 100644
--- a/include/dt-bindings/clock/stm32mp13-clks.h
+++ b/include/dt-bindings/clock/stm32mp13-clks.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2022-2024 - All Rights Reserved
  * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
  */
 
@@ -193,7 +193,13 @@
 #define SAI1		160
 #define SAI2		161
 
-#define STM32MP1_LAST_CLK 162
+#define SPI1		162
+#define SPI2		163
+#define SPI3		164
+#define SPI4		165
+#define SPI5		166
+
+#define STM32MP1_LAST_CLK 167
 
 /* SCMI clock identifiers */
 #define CK_SCMI0_HSE		0
diff --git a/include/dt-bindings/clock/stm32mp15-clksrc.h b/include/dt-bindings/clock/stm32mp15-clksrc.h
index 3a3792d..e601b48 100644
--- a/include/dt-bindings/clock/stm32mp15-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp15-clksrc.h
@@ -1,273 +1,413 @@
 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
 /*
- * Copyright (C) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2017-2024, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 #define _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 
+#include <lib/utils_def.h>
+
+#define CMD_DIV		0
+#define CMD_MUX		1
+#define CMD_CLK		2
+
+#define CMD_ADDR_BIT	BIT(31)
+
+#define CMD_SHIFT	26
+#define CMD_MASK	GENMASK_32(31, 26)
+#define CMD_DATA_MASK	GENMASK_32(25, 0)
+
+#define DIV_ID_SHIFT	8
+#define DIV_ID_MASK	GENMASK_32(15, 8)
+
+#define DIV_DIVN_SHIFT	0
+#define DIV_DIVN_MASK	GENMASK_32(7, 0)
+
+#define MUX_ID_SHIFT	4
+#define MUX_ID_MASK	GENMASK_32(11, 4)
+
+#define MUX_SEL_SHIFT	0
+#define MUX_SEL_MASK	GENMASK_32(3, 0)
+
+#define CLK_ID_MASK	GENMASK_32(19, 11)
+#define CLK_ID_SHIFT	11
+#define CLK_ON_MASK	0x00000400
+#define CLK_ON_SHIFT	10
+#define CLK_DIV_MASK	GENMASK_32(9, 4)
+#define CLK_DIV_SHIFT	4
+#define CLK_SEL_MASK	GENMASK_32(3, 0)
+#define CLK_SEL_SHIFT	0
+
+#define DIV(div_id, div)	((CMD_DIV << CMD_SHIFT) |\
+				 ((div_id) << DIV_ID_SHIFT) |\
+				 (div))
+
+#define CLKSRC(mux_id, sel)	((CMD_MUX << CMD_SHIFT) |\
+				 ((mux_id) << MUX_ID_SHIFT) |\
+				 (sel))
+
+/* CLK output is enable */
+#define CLK_SRC(clk_id, sel)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT) |\
+				 (sel) | CLK_ON_MASK)
+
+#define CLK_DISABLED(clk_id)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT))
+
+#define CLK_ADDR_SHIFT		16
+#define CLK_ADDR_MASK		GENMASK_32(30, 16)
+#define CLK_ADDR_VAL_MASK	GENMASK_32(15, 0)
+
+#define DIV_PLL1DIVP	0
+#define DIV_PLL2DIVP	1
+#define DIV_PLL2DIVQ	2
+#define DIV_PLL2DIVR	3
+#define DIV_PLL3DIVP	4
+#define DIV_PLL3DIVQ	5
+#define DIV_PLL3DIVR	6
+#define DIV_PLL4DIVP	7
+#define DIV_PLL4DIVQ	8
+#define DIV_PLL4DIVR	9
+#define DIV_MPU		10
+#define DIV_AXI		11
+#define DIV_MCU		12
+#define DIV_APB1	13
+#define DIV_APB2	14
+#define DIV_APB3	15
+#define DIV_APB4	16
+#define DIV_APB5	17
+#define DIV_RTC		19
+#define DIV_MCO1	20
+#define DIV_MCO2	21
+#define DIV_HSI		22
+#define DIV_TRACE	23
+#define DIV_ETHPTP	24
+#define DIV_NB		25
+
+#define MUX_MPU		0
+#define MUX_AXI		1
+#define MUX_MCU		2
+#define MUX_PLL12	3
+#define MUX_PLL3	4
+#define MUX_PLL4	5
+#define MUX_CKPER	6
+#define MUX_RTC		7
+#define MUX_SDMMC12	8
+#define MUX_SDMMC3	9
+#define MUX_FMC		10
+#define MUX_QSPI	11
+#define MUX_RNG1	12
+#define MUX_RNG2	13
+#define MUX_USBPHY	14
+#define MUX_USBO	15
+#define MUX_STGEN	16
+#define MUX_SPDIF	17
+#define MUX_SPI2S1	18
+#define MUX_SPI2S23	19
+#define MUX_SPI45	20
+#define MUX_SPI6	21
+#define MUX_CEC		22
+#define MUX_I2C12	23
+#define MUX_I2C35	24
+#define MUX_I2C46	25
+#define MUX_LPTIM1	26
+#define MUX_LPTIM23	27
+#define MUX_LPTIM45	28
+#define MUX_UART1	29
+#define MUX_UART24	30
+#define MUX_UART35	31
+#define MUX_UART6	32
+#define MUX_UART78	33
+#define MUX_SAI1	34
+#define MUX_SAI2	35
+#define MUX_SAI3	36
+#define MUX_SAI4	37
+#define MUX_DSI		38
+#define MUX_FDCAN	39
+#define MUX_ADC		40
+#define MUX_ETH		41
+#define MUX_MCO1	42
+#define MUX_MCO2	43
+#define MUX_NB		44
+
 /* PLL output is enable when x=1, with x=p,q or r */
 #define PQR(p, q, r)	(((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
 
-/* st,clksrc: mandatory clock source */
-#define CLK_MPU_HSI		0x00000200
-#define CLK_MPU_HSE		0x00000201
-#define CLK_MPU_PLL1P		0x00000202
-#define CLK_MPU_PLL1P_DIV	0x00000203
+/* st,clksrc: clock sources */
+#define CLK_MPU_HSI		CLKSRC(MUX_MPU, 0)
+#define CLK_MPU_HSE		CLKSRC(MUX_MPU, 1)
+#define CLK_MPU_PLL1P		CLKSRC(MUX_MPU, 2)
+#define CLK_MPU_PLL1P_DIV	CLKSRC(MUX_MPU, 3)
 
-#define CLK_AXI_HSI		0x00000240
-#define CLK_AXI_HSE		0x00000241
-#define CLK_AXI_PLL2P		0x00000242
+#define CLK_AXI_HSI		CLKSRC(MUX_AXI, 0)
+#define CLK_AXI_HSE		CLKSRC(MUX_AXI, 1)
+#define CLK_AXI_PLL2P		CLKSRC(MUX_AXI, 2)
 
-#define CLK_MCU_HSI		0x00000480
-#define CLK_MCU_HSE		0x00000481
-#define CLK_MCU_CSI		0x00000482
-#define CLK_MCU_PLL3P		0x00000483
+#define CLK_MCU_HSI		CLKSRC(MUX_MCU, 0)
+#define CLK_MCU_HSE		CLKSRC(MUX_MCU, 1)
+#define CLK_MCU_CSI		CLKSRC(MUX_MCU, 2)
+#define CLK_MCU_PLL3P		CLKSRC(MUX_MCU, 3)
 
-#define CLK_PLL12_HSI		0x00000280
-#define CLK_PLL12_HSE		0x00000281
+#define CLK_PLL12_HSI		CLKSRC(MUX_PLL12, 0)
+#define CLK_PLL12_HSE		CLKSRC(MUX_PLL12, 1)
 
-#define CLK_PLL3_HSI		0x00008200
-#define CLK_PLL3_HSE		0x00008201
-#define CLK_PLL3_CSI		0x00008202
+#define CLK_PLL3_HSI		CLKSRC(MUX_PLL3, 0)
+#define CLK_PLL3_HSE		CLKSRC(MUX_PLL3, 1)
+#define CLK_PLL3_CSI		CLKSRC(MUX_PLL3, 2)
 
-#define CLK_PLL4_HSI		0x00008240
-#define CLK_PLL4_HSE		0x00008241
-#define CLK_PLL4_CSI		0x00008242
-#define CLK_PLL4_I2SCKIN	0x00008243
+#define CLK_PLL4_HSI		CLKSRC(MUX_PLL4, 0)
+#define CLK_PLL4_HSE		CLKSRC(MUX_PLL4, 1)
+#define CLK_PLL4_CSI		CLKSRC(MUX_PLL4, 2)
+#define CLK_PLL4_I2SCKIN	CLKSRC(MUX_PLL4, 3)
 
-#define CLK_RTC_DISABLED	0x00001400
-#define CLK_RTC_LSE		0x00001401
-#define CLK_RTC_LSI		0x00001402
-#define CLK_RTC_HSE		0x00001403
+#define CLK_RTC_DISABLED	CLK_DISABLED(RTC)
+#define CLK_RTC_LSE		CLK_SRC(RTC, 1)
+#define CLK_RTC_LSI		CLK_SRC(RTC, 2)
+#define CLK_RTC_HSE		CLK_SRC(RTC, 3)
 
-#define CLK_MCO1_HSI		0x00008000
-#define CLK_MCO1_HSE		0x00008001
-#define CLK_MCO1_CSI		0x00008002
-#define CLK_MCO1_LSI		0x00008003
-#define CLK_MCO1_LSE		0x00008004
-#define CLK_MCO1_DISABLED	0x0000800F
+/* Register addresses of MCO1 & MCO2 */
+#define MCO1			0x800
+#define MCO2			0x804
 
-#define CLK_MCO2_MPU		0x00008040
-#define CLK_MCO2_AXI		0x00008041
-#define CLK_MCO2_MCU		0x00008042
-#define CLK_MCO2_PLL4P		0x00008043
-#define CLK_MCO2_HSE		0x00008044
-#define CLK_MCO2_HSI		0x00008045
-#define CLK_MCO2_DISABLED	0x0000804F
+#define MCO_OFF			0
+#define MCO_ON			1
+#define MCO_STATUS_SHIFT	12
 
-/* st,pkcs: peripheral kernel clock source */
+#define MCO_ON_CFG(addr, sel)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_ON << MCO_STATUS_SHIFT) |\
+				(sel))
 
-#define CLK_I2C12_PCLK1		0x00008C00
-#define CLK_I2C12_PLL4R		0x00008C01
-#define CLK_I2C12_HSI		0x00008C02
-#define CLK_I2C12_CSI		0x00008C03
-#define CLK_I2C12_DISABLED	0x00008C07
+#define MCO_OFF_CFG(addr)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_OFF << MCO_STATUS_SHIFT))
 
-#define CLK_I2C35_PCLK1		0x00008C40
-#define CLK_I2C35_PLL4R		0x00008C41
-#define CLK_I2C35_HSI		0x00008C42
-#define CLK_I2C35_CSI		0x00008C43
-#define CLK_I2C35_DISABLED	0x00008C47
+#define CLK_MCO1_HSI		MCO_ON_CFG(MCO1, 0)
+#define CLK_MCO1_HSE		MCO_ON_CFG(MCO1, 1)
+#define CLK_MCO1_CSI		MCO_ON_CFG(MCO1, 2)
+#define CLK_MCO1_LSI		MCO_ON_CFG(MCO1, 3)
+#define CLK_MCO1_LSE		MCO_ON_CFG(MCO1, 4)
+#define CLK_MCO1_DISABLED	MCO_OFF_CFG(MCO1)
 
-#define CLK_I2C46_PCLK5		0x00000C00
-#define CLK_I2C46_PLL3Q		0x00000C01
-#define CLK_I2C46_HSI		0x00000C02
-#define CLK_I2C46_CSI		0x00000C03
-#define CLK_I2C46_DISABLED	0x00000C07
+#define CLK_MCO2_MPU		MCO_ON_CFG(MCO2, 0)
+#define CLK_MCO2_AXI		MCO_ON_CFG(MCO2, 1)
+#define CLK_MCO2_MCU		MCO_ON_CFG(MCO2, 2)
+#define CLK_MCO2_PLL4		MCO_ON_CFG(MCO2, 3)
+#define CLK_MCO2_HSE		MCO_ON_CFG(MCO2, 4)
+#define CLK_MCO2_HSI		MCO_ON_CFG(MCO2, 5)
+#define CLK_MCO2_DISABLED	MCO_OFF_CFG(MCO2)
 
-#define CLK_SAI1_PLL4Q		0x00008C80
-#define CLK_SAI1_PLL3Q		0x00008C81
-#define CLK_SAI1_I2SCKIN	0x00008C82
-#define CLK_SAI1_CKPER		0x00008C83
-#define CLK_SAI1_PLL3R		0x00008C84
-#define CLK_SAI1_DISABLED	0x00008C87
+#define CLK_I2C12_PCLK1		CLKSRC(MUX_I2C12, 0)
+#define CLK_I2C12_PLL4R		CLKSRC(MUX_I2C12, 1)
+#define CLK_I2C12_HSI		CLKSRC(MUX_I2C12, 2)
+#define CLK_I2C12_CSI		CLKSRC(MUX_I2C12, 3)
+#define CLK_I2C12_DISABLED	CLKSRC(MUX_I2C12, 7)
 
-#define CLK_SAI2_PLL4Q		0x00008CC0
-#define CLK_SAI2_PLL3Q		0x00008CC1
-#define CLK_SAI2_I2SCKIN	0x00008CC2
-#define CLK_SAI2_CKPER		0x00008CC3
-#define CLK_SAI2_SPDIF		0x00008CC4
-#define CLK_SAI2_PLL3R		0x00008CC5
-#define CLK_SAI2_DISABLED	0x00008CC7
+#define CLK_I2C35_PCLK1		CLKSRC(MUX_I2C35, 0)
+#define CLK_I2C35_PLL4R		CLKSRC(MUX_I2C35, 1)
+#define CLK_I2C35_HSI		CLKSRC(MUX_I2C35, 2)
+#define CLK_I2C35_CSI		CLKSRC(MUX_I2C35, 3)
+#define CLK_I2C35_DISABLED	CLKSRC(MUX_I2C35, 7)
 
-#define CLK_SAI3_PLL4Q		0x00008D00
-#define CLK_SAI3_PLL3Q		0x00008D01
-#define CLK_SAI3_I2SCKIN	0x00008D02
-#define CLK_SAI3_CKPER		0x00008D03
-#define CLK_SAI3_PLL3R		0x00008D04
-#define CLK_SAI3_DISABLED	0x00008D07
+#define CLK_I2C46_PCLK5		CLKSRC(MUX_I2C46, 0)
+#define CLK_I2C46_PLL3Q		CLKSRC(MUX_I2C46, 1)
+#define CLK_I2C46_HSI		CLKSRC(MUX_I2C46, 2)
+#define CLK_I2C46_CSI		CLKSRC(MUX_I2C46, 3)
+#define CLK_I2C46_DISABLED	CLKSRC(MUX_I2C46, 7)
 
-#define CLK_SAI4_PLL4Q		0x00008D40
-#define CLK_SAI4_PLL3Q		0x00008D41
-#define CLK_SAI4_I2SCKIN	0x00008D42
-#define CLK_SAI4_CKPER		0x00008D43
-#define CLK_SAI4_PLL3R		0x00008D44
-#define CLK_SAI4_DISABLED	0x00008D47
+#define CLK_SAI1_PLL4Q		CLKSRC(MUX_SAI1, 0)
+#define CLK_SAI1_PLL3Q		CLKSRC(MUX_SAI1, 1)
+#define CLK_SAI1_I2SCKIN	CLKSRC(MUX_SAI1, 2)
+#define CLK_SAI1_CKPER		CLKSRC(MUX_SAI1, 3)
+#define CLK_SAI1_PLL3R		CLKSRC(MUX_SAI1, 4)
+#define CLK_SAI1_DISABLED	CLKSRC(MUX_SAI1, 7)
 
-#define CLK_SPI2S1_PLL4P	0x00008D80
-#define CLK_SPI2S1_PLL3Q	0x00008D81
-#define CLK_SPI2S1_I2SCKIN	0x00008D82
-#define CLK_SPI2S1_CKPER	0x00008D83
-#define CLK_SPI2S1_PLL3R	0x00008D84
-#define CLK_SPI2S1_DISABLED	0x00008D87
+#define CLK_SAI2_PLL4Q		CLKSRC(MUX_SAI2, 0)
+#define CLK_SAI2_PLL3Q		CLKSRC(MUX_SAI2, 1)
+#define CLK_SAI2_I2SCKIN	CLKSRC(MUX_SAI2, 2)
+#define CLK_SAI2_CKPER		CLKSRC(MUX_SAI2, 3)
+#define CLK_SAI2_SPDIF		CLKSRC(MUX_SAI2, 4)
+#define CLK_SAI2_PLL3R		CLKSRC(MUX_SAI2, 5)
+#define CLK_SAI2_DISABLED	CLKSRC(MUX_SAI2, 7)
 
-#define CLK_SPI2S23_PLL4P	0x00008DC0
-#define CLK_SPI2S23_PLL3Q	0x00008DC1
-#define CLK_SPI2S23_I2SCKIN	0x00008DC2
-#define CLK_SPI2S23_CKPER	0x00008DC3
-#define CLK_SPI2S23_PLL3R	0x00008DC4
-#define CLK_SPI2S23_DISABLED	0x00008DC7
+#define CLK_SAI3_PLL4Q		CLKSRC(MUX_SAI3, 0)
+#define CLK_SAI3_PLL3Q		CLKSRC(MUX_SAI3, 1)
+#define CLK_SAI3_I2SCKIN	CLKSRC(MUX_SAI3, 2)
+#define CLK_SAI3_CKPER		CLKSRC(MUX_SAI3, 3)
+#define CLK_SAI3_PLL3R		CLKSRC(MUX_SAI3, 4)
+#define CLK_SAI3_DISABLED	CLKSRC(MUX_SAI3, 7)
 
-#define CLK_SPI45_PCLK2		0x00008E00
-#define CLK_SPI45_PLL4Q		0x00008E01
-#define CLK_SPI45_HSI		0x00008E02
-#define CLK_SPI45_CSI		0x00008E03
-#define CLK_SPI45_HSE		0x00008E04
-#define CLK_SPI45_DISABLED	0x00008E07
+#define CLK_SAI4_PLL4Q		CLKSRC(MUX_SAI4, 0)
+#define CLK_SAI4_PLL3Q		CLKSRC(MUX_SAI4, 1)
+#define CLK_SAI4_I2SCKIN	CLKSRC(MUX_SAI4, 2)
+#define CLK_SAI4_CKPER		CLKSRC(MUX_SAI4, 3)
+#define CLK_SAI4_PLL3R		CLKSRC(MUX_SAI4, 4)
+#define CLK_SAI4_DISABLED	CLKSRC(MUX_SAI4, 7)
 
-#define CLK_SPI6_PCLK5		0x00000C40
-#define CLK_SPI6_PLL4Q		0x00000C41
-#define CLK_SPI6_HSI		0x00000C42
-#define CLK_SPI6_CSI		0x00000C43
-#define CLK_SPI6_HSE		0x00000C44
-#define CLK_SPI6_PLL3Q		0x00000C45
-#define CLK_SPI6_DISABLED	0x00000C47
+#define CLK_SPI2S1_PLL4P	CLKSRC(MUX_SPI2S1, 0)
+#define CLK_SPI2S1_PLL3Q	CLKSRC(MUX_SPI2S1, 1)
+#define CLK_SPI2S1_I2SCKIN	CLKSRC(MUX_SPI2S1, 2)
+#define CLK_SPI2S1_CKPER	CLKSRC(MUX_SPI2S1, 3)
+#define CLK_SPI2S1_PLL3R	CLKSRC(MUX_SPI2S1, 4)
+#define CLK_SPI2S1_DISABLED	CLKSRC(MUX_SPI2S1, 7)
 
-#define CLK_UART6_PCLK2		0x00008E40
-#define CLK_UART6_PLL4Q		0x00008E41
-#define CLK_UART6_HSI		0x00008E42
-#define CLK_UART6_CSI		0x00008E43
-#define CLK_UART6_HSE		0x00008E44
-#define CLK_UART6_DISABLED	0x00008E47
+#define CLK_SPI2S23_PLL4P	CLKSRC(MUX_SPI2S23, 0)
+#define CLK_SPI2S23_PLL3Q	CLKSRC(MUX_SPI2S23, 1)
+#define CLK_SPI2S23_I2SCKIN	CLKSRC(MUX_SPI2S23, 2)
+#define CLK_SPI2S23_CKPER	CLKSRC(MUX_SPI2S23, 3)
+#define CLK_SPI2S23_PLL3R	CLKSRC(MUX_SPI2S23, 4)
+#define CLK_SPI2S23_DISABLED	CLKSRC(MUX_SPI2S23, 7)
 
-#define CLK_UART24_PCLK1	0x00008E80
-#define CLK_UART24_PLL4Q	0x00008E81
-#define CLK_UART24_HSI		0x00008E82
-#define CLK_UART24_CSI		0x00008E83
-#define CLK_UART24_HSE		0x00008E84
-#define CLK_UART24_DISABLED	0x00008E87
+#define CLK_SPI45_PCLK2		CLKSRC(MUX_SPI45, 0)
+#define CLK_SPI45_PLL4Q		CLKSRC(MUX_SPI45, 1)
+#define CLK_SPI45_HSI		CLKSRC(MUX_SPI45, 2)
+#define CLK_SPI45_CSI		CLKSRC(MUX_SPI45, 3)
+#define CLK_SPI45_HSE		CLKSRC(MUX_SPI45, 4)
+#define CLK_SPI45_DISABLED	CLKSRC(MUX_SPI45, 7)
 
-#define CLK_UART35_PCLK1	0x00008EC0
-#define CLK_UART35_PLL4Q	0x00008EC1
-#define CLK_UART35_HSI		0x00008EC2
-#define CLK_UART35_CSI		0x00008EC3
-#define CLK_UART35_HSE		0x00008EC4
-#define CLK_UART35_DISABLED	0x00008EC7
+#define CLK_SPI6_PCLK5		CLKSRC(MUX_SPI6, 0)
+#define CLK_SPI6_PLL4Q		CLKSRC(MUX_SPI6, 1)
+#define CLK_SPI6_HSI		CLKSRC(MUX_SPI6, 2)
+#define CLK_SPI6_CSI		CLKSRC(MUX_SPI6, 3)
+#define CLK_SPI6_HSE		CLKSRC(MUX_SPI6, 4)
+#define CLK_SPI6_PLL3Q		CLKSRC(MUX_SPI6, 5)
+#define CLK_SPI6_DISABLED	CLKSRC(MUX_SPI6, 7)
 
-#define CLK_UART78_PCLK1	0x00008F00
-#define CLK_UART78_PLL4Q	0x00008F01
-#define CLK_UART78_HSI		0x00008F02
-#define CLK_UART78_CSI		0x00008F03
-#define CLK_UART78_HSE		0x00008F04
-#define CLK_UART78_DISABLED	0x00008F07
+#define CLK_UART6_PCLK2		CLKSRC(MUX_UART6, 0)
+#define CLK_UART6_PLL4Q		CLKSRC(MUX_UART6, 1)
+#define CLK_UART6_HSI		CLKSRC(MUX_UART6, 2)
+#define CLK_UART6_CSI		CLKSRC(MUX_UART6, 3)
+#define CLK_UART6_HSE		CLKSRC(MUX_UART6, 4)
+#define CLK_UART6_DISABLED	CLKSRC(MUX_UART6, 7)
 
-#define CLK_UART1_PCLK5		0x00000C80
-#define CLK_UART1_PLL3Q		0x00000C81
-#define CLK_UART1_HSI		0x00000C82
-#define CLK_UART1_CSI		0x00000C83
-#define CLK_UART1_PLL4Q		0x00000C84
-#define CLK_UART1_HSE		0x00000C85
-#define CLK_UART1_DISABLED	0x00000C87
+#define CLK_UART24_PCLK1	CLKSRC(MUX_UART24, 0)
+#define CLK_UART24_PLL4Q	CLKSRC(MUX_UART24, 1)
+#define CLK_UART24_HSI		CLKSRC(MUX_UART24, 2)
+#define CLK_UART24_CSI		CLKSRC(MUX_UART24, 3)
+#define CLK_UART24_HSE		CLKSRC(MUX_UART24, 4)
+#define CLK_UART24_DISABLED	CLKSRC(MUX_UART24, 7)
 
-#define CLK_SDMMC12_HCLK6	0x00008F40
-#define CLK_SDMMC12_PLL3R	0x00008F41
-#define CLK_SDMMC12_PLL4P	0x00008F42
-#define CLK_SDMMC12_HSI		0x00008F43
-#define CLK_SDMMC12_DISABLED	0x00008F47
+#define CLK_UART35_PCLK1	CLKSRC(MUX_UART35, 0)
+#define CLK_UART35_PLL4Q	CLKSRC(MUX_UART35, 1)
+#define CLK_UART35_HSI		CLKSRC(MUX_UART35, 2)
+#define CLK_UART35_CSI		CLKSRC(MUX_UART35, 3)
+#define CLK_UART35_HSE		CLKSRC(MUX_UART35, 4)
+#define CLK_UART35_DISABLED	CLKSRC(MUX_UART35, 7)
 
-#define CLK_SDMMC3_HCLK2	0x00008F80
-#define CLK_SDMMC3_PLL3R	0x00008F81
-#define CLK_SDMMC3_PLL4P	0x00008F82
-#define CLK_SDMMC3_HSI		0x00008F83
-#define CLK_SDMMC3_DISABLED	0x00008F87
+#define CLK_UART78_PCLK1	CLKSRC(MUX_UART78, 0)
+#define CLK_UART78_PLL4Q	CLKSRC(MUX_UART78, 1)
+#define CLK_UART78_HSI		CLKSRC(MUX_UART78, 2)
+#define CLK_UART78_CSI		CLKSRC(MUX_UART78, 3)
+#define CLK_UART78_HSE		CLKSRC(MUX_UART78, 4)
+#define CLK_UART78_DISABLED	CLKSRC(MUX_UART78, 7)
 
-#define CLK_ETH_PLL4P		0x00008FC0
-#define CLK_ETH_PLL3Q		0x00008FC1
-#define CLK_ETH_DISABLED	0x00008FC3
+#define CLK_UART1_PCLK5		CLKSRC(MUX_UART1, 0)
+#define CLK_UART1_PLL3Q		CLKSRC(MUX_UART1, 1)
+#define CLK_UART1_HSI		CLKSRC(MUX_UART1, 2)
+#define CLK_UART1_CSI		CLKSRC(MUX_UART1, 3)
+#define CLK_UART1_PLL4Q		CLKSRC(MUX_UART1, 4)
+#define CLK_UART1_HSE		CLKSRC(MUX_UART1, 5)
+#define CLK_UART1_DISABLED	CLKSRC(MUX_UART1, 7)
 
-#define CLK_QSPI_ACLK		0x00009000
-#define CLK_QSPI_PLL3R		0x00009001
-#define CLK_QSPI_PLL4P		0x00009002
-#define CLK_QSPI_CKPER		0x00009003
+#define CLK_SDMMC12_HCLK6	CLKSRC(MUX_SDMMC12, 0)
+#define CLK_SDMMC12_PLL3R	CLKSRC(MUX_SDMMC12, 1)
+#define CLK_SDMMC12_PLL4P	CLKSRC(MUX_SDMMC12, 2)
+#define CLK_SDMMC12_HSI		CLKSRC(MUX_SDMMC12, 3)
+#define CLK_SDMMC12_DISABLED	CLKSRC(MUX_SDMMC12, 7)
 
-#define CLK_FMC_ACLK		0x00009040
-#define CLK_FMC_PLL3R		0x00009041
-#define CLK_FMC_PLL4P		0x00009042
-#define CLK_FMC_CKPER		0x00009043
+#define CLK_SDMMC3_HCLK2	CLKSRC(MUX_SDMMC3, 0)
+#define CLK_SDMMC3_PLL3R	CLKSRC(MUX_SDMMC3, 1)
+#define CLK_SDMMC3_PLL4P	CLKSRC(MUX_SDMMC3, 2)
+#define CLK_SDMMC3_HSI		CLKSRC(MUX_SDMMC3, 3)
+#define CLK_SDMMC3_DISABLED	CLKSRC(MUX_SDMMC3, 7)
 
-#define CLK_FDCAN_HSE		0x000090C0
-#define CLK_FDCAN_PLL3Q		0x000090C1
-#define CLK_FDCAN_PLL4Q		0x000090C2
-#define CLK_FDCAN_PLL4R		0x000090C3
+#define CLK_ETH_PLL4P		CLKSRC(MUX_ETH, 0)
+#define CLK_ETH_PLL3Q		CLKSRC(MUX_ETH, 1)
+#define CLK_ETH_DISABLED	CLKSRC(MUX_ETH, 3)
 
-#define CLK_SPDIF_PLL4P		0x00009140
-#define CLK_SPDIF_PLL3Q		0x00009141
-#define CLK_SPDIF_HSI		0x00009142
-#define CLK_SPDIF_DISABLED	0x00009143
+#define CLK_QSPI_ACLK		CLKSRC(MUX_QSPI, 0)
+#define CLK_QSPI_PLL3R		CLKSRC(MUX_QSPI, 1)
+#define CLK_QSPI_PLL4P		CLKSRC(MUX_QSPI, 2)
+#define CLK_QSPI_CKPER		CLKSRC(MUX_QSPI, 3)
 
-#define CLK_CEC_LSE		0x00009180
-#define CLK_CEC_LSI		0x00009181
-#define CLK_CEC_CSI_DIV122	0x00009182
-#define CLK_CEC_DISABLED	0x00009183
+#define CLK_FMC_ACLK		CLKSRC(MUX_FMC, 0)
+#define CLK_FMC_PLL3R		CLKSRC(MUX_FMC, 1)
+#define CLK_FMC_PLL4P		CLKSRC(MUX_FMC, 2)
+#define CLK_FMC_CKPER		CLKSRC(MUX_FMC, 3)
 
-#define CLK_USBPHY_HSE		0x000091C0
-#define CLK_USBPHY_PLL4R	0x000091C1
-#define CLK_USBPHY_HSE_DIV2	0x000091C2
-#define CLK_USBPHY_DISABLED	0x000091C3
+#define CLK_FDCAN_HSE		CLKSRC(MUX_FDCAN, 0)
+#define CLK_FDCAN_PLL3Q		CLKSRC(MUX_FDCAN, 1)
+#define CLK_FDCAN_PLL4Q		CLKSRC(MUX_FDCAN, 2)
+#define CLK_FDCAN_PLL4R		CLKSRC(MUX_FDCAN, 3)
 
-#define CLK_USBO_PLL4R		0x800091C0
-#define CLK_USBO_USBPHY		0x800091C1
+#define CLK_SPDIF_PLL4P		CLKSRC(MUX_SPDIF, 0)
+#define CLK_SPDIF_PLL3Q		CLKSRC(MUX_SPDIF, 1)
+#define CLK_SPDIF_HSI		CLKSRC(MUX_SPDIF, 2)
+#define CLK_SPDIF_DISABLED	CLKSRC(MUX_SPDIF, 3)
 
-#define CLK_RNG1_CSI		0x00000CC0
-#define CLK_RNG1_PLL4R		0x00000CC1
-#define CLK_RNG1_LSE		0x00000CC2
-#define CLK_RNG1_LSI		0x00000CC3
+#define CLK_CEC_LSE		CLKSRC(MUX_CEC, 0)
+#define CLK_CEC_LSI		CLKSRC(MUX_CEC, 1)
+#define CLK_CEC_CSI_DIV122	CLKSRC(MUX_CEC, 2)
+#define CLK_CEC_DISABLED	CLKSRC(MUX_CEC, 3)
 
-#define CLK_RNG2_CSI		0x00009200
-#define CLK_RNG2_PLL4R		0x00009201
-#define CLK_RNG2_LSE		0x00009202
-#define CLK_RNG2_LSI		0x00009203
+#define CLK_USBPHY_HSE		CLKSRC(MUX_USBPHY, 0)
+#define CLK_USBPHY_PLL4R	CLKSRC(MUX_USBPHY, 1)
+#define CLK_USBPHY_HSE_DIV2	CLKSRC(MUX_USBPHY, 2)
+#define CLK_USBPHY_DISABLED	CLKSRC(MUX_USBPHY, 3)
 
-#define CLK_CKPER_HSI		0x00000D00
-#define CLK_CKPER_CSI		0x00000D01
-#define CLK_CKPER_HSE		0x00000D02
-#define CLK_CKPER_DISABLED	0x00000D03
+#define CLK_USBO_PLL4R		CLKSRC(MUX_USBO, 0)
+#define CLK_USBO_USBPHY		CLKSRC(MUX_USBO, 1)
 
-#define CLK_STGEN_HSI		0x00000D40
-#define CLK_STGEN_HSE		0x00000D41
-#define CLK_STGEN_DISABLED	0x00000D43
+#define CLK_RNG1_CSI		CLKSRC(MUX_RNG1, 0)
+#define CLK_RNG1_PLL4R		CLKSRC(MUX_RNG1, 1)
+#define CLK_RNG1_LSE		CLKSRC(MUX_RNG1, 2)
+#define CLK_RNG1_LSI		CLKSRC(MUX_RNG1, 3)
 
-#define CLK_DSI_DSIPLL		0x00009240
-#define CLK_DSI_PLL4P		0x00009241
+#define CLK_RNG2_CSI		CLKSRC(MUX_RNG2, 0)
+#define CLK_RNG2_PLL4R		CLKSRC(MUX_RNG2, 1)
+#define CLK_RNG2_LSE		CLKSRC(MUX_RNG2, 2)
+#define CLK_RNG2_LSI		CLKSRC(MUX_RNG2, 3)
 
-#define CLK_ADC_PLL4R		0x00009280
-#define CLK_ADC_CKPER		0x00009281
-#define CLK_ADC_PLL3Q		0x00009282
-#define CLK_ADC_DISABLED	0x00009283
+#define CLK_CKPER_HSI		CLKSRC(MUX_CKPER, 0)
+#define CLK_CKPER_CSI		CLKSRC(MUX_CKPER, 1)
+#define CLK_CKPER_HSE		CLKSRC(MUX_CKPER, 2)
+#define CLK_CKPER_DISABLED	CLKSRC(MUX_CKPER, 3)
 
-#define CLK_LPTIM45_PCLK3	0x000092C0
-#define CLK_LPTIM45_PLL4P	0x000092C1
-#define CLK_LPTIM45_PLL3Q	0x000092C2
-#define CLK_LPTIM45_LSE		0x000092C3
-#define CLK_LPTIM45_LSI		0x000092C4
-#define CLK_LPTIM45_CKPER	0x000092C5
-#define CLK_LPTIM45_DISABLED	0x000092C7
+#define CLK_STGEN_HSI		CLKSRC(MUX_STGEN, 0)
+#define CLK_STGEN_HSE		CLKSRC(MUX_STGEN, 1)
+#define CLK_STGEN_DISABLED	CLKSRC(MUX_STGEN, 3)
 
-#define CLK_LPTIM23_PCLK3	0x00009300
-#define CLK_LPTIM23_PLL4Q	0x00009301
-#define CLK_LPTIM23_CKPER	0x00009302
-#define CLK_LPTIM23_LSE		0x00009303
-#define CLK_LPTIM23_LSI		0x00009304
-#define CLK_LPTIM23_DISABLED	0x00009307
+#define CLK_DSI_DSIPLL		CLKSRC(MUX_DSI, 0)
+#define CLK_DSI_PLL4P		CLKSRC(MUX_DSI, 1)
 
-#define CLK_LPTIM1_PCLK1	0x00009340
-#define CLK_LPTIM1_PLL4P	0x00009341
-#define CLK_LPTIM1_PLL3Q	0x00009342
-#define CLK_LPTIM1_LSE		0x00009343
-#define CLK_LPTIM1_LSI		0x00009344
-#define CLK_LPTIM1_CKPER	0x00009345
-#define CLK_LPTIM1_DISABLED	0x00009347
+#define CLK_ADC_PLL4R		CLKSRC(MUX_ADC, 0)
+#define CLK_ADC_CKPER		CLKSRC(MUX_ADC, 1)
+#define CLK_ADC_PLL3Q		CLKSRC(MUX_ADC, 2)
+#define CLK_ADC_DISABLED	CLKSRC(MUX_ADC, 3)
+
+#define CLK_LPTIM45_PCLK3	CLKSRC(MUX_LPTIM45, 0)
+#define CLK_LPTIM45_PLL4P	CLKSRC(MUX_LPTIM45, 1)
+#define CLK_LPTIM45_PLL3Q	CLKSRC(MUX_LPTIM45, 2)
+#define CLK_LPTIM45_LSE		CLKSRC(MUX_LPTIM45, 3)
+#define CLK_LPTIM45_LSI		CLKSRC(MUX_LPTIM45, 4)
+#define CLK_LPTIM45_CKPER	CLKSRC(MUX_LPTIM45, 5)
+#define CLK_LPTIM45_DISABLED	CLKSRC(MUX_LPTIM45, 7)
+
+#define CLK_LPTIM23_PCLK3	CLKSRC(MUX_LPTIM23, 0)
+#define CLK_LPTIM23_PLL4Q	CLKSRC(MUX_LPTIM23, 1)
+#define CLK_LPTIM23_CKPER	CLKSRC(MUX_LPTIM23, 2)
+#define CLK_LPTIM23_LSE		CLKSRC(MUX_LPTIM23, 3)
+#define CLK_LPTIM23_LSI		CLKSRC(MUX_LPTIM23, 4)
+#define CLK_LPTIM23_DISABLED	CLKSRC(MUX_LPTIM23, 7)
+
+#define CLK_LPTIM1_PCLK1	CLKSRC(MUX_LPTIM1, 0)
+#define CLK_LPTIM1_PLL4P	CLKSRC(MUX_LPTIM1, 1)
+#define CLK_LPTIM1_PLL3Q	CLKSRC(MUX_LPTIM1, 2)
+#define CLK_LPTIM1_LSE		CLKSRC(MUX_LPTIM1, 3)
+#define CLK_LPTIM1_LSI		CLKSRC(MUX_LPTIM1, 4)
+#define CLK_LPTIM1_CKPER	CLKSRC(MUX_LPTIM1, 5)
+#define CLK_LPTIM1_DISABLED	CLKSRC(MUX_LPTIM1, 7)
 
 /* define for st,pll /csg */
 #define SSCG_MODE_CENTER_SPREAD	0
diff --git a/include/dt-bindings/clock/stm32mp25-clks.h b/include/dt-bindings/clock/stm32mp25-clks.h
index c4ff9cf..e7ab5b0 100644
--- a/include/dt-bindings/clock/stm32mp25-clks.h
+++ b/include/dt-bindings/clock/stm32mp25-clks.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
- * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
  */
 
 #ifndef _DT_BINDINGS_STM32MP25_CLKS_H_
@@ -109,7 +109,7 @@
 /* LOW SPEED MCU CLOCK */
 #define CK_ICN_LS_MCU		88
 
-#define CK_BUS_STM500		89
+#define CK_BUS_STM		89
 #define CK_BUS_FMC		90
 #define CK_BUS_GPU		91
 #define CK_BUS_ETH1		92
@@ -233,7 +233,6 @@
 #define CK_BUS_DDRCFG		210
 #define CK_BUS_GICV2M		211
 #define CK_BUS_USBTC		212
-#define CK_BUS_BUSPERFM		213
 #define CK_BUS_USB3PCIEPHY	214
 #define CK_BUS_STGEN		215
 #define CK_BUS_VDEC		216
@@ -272,7 +271,7 @@
 #define CK_BUS_RISAF4		249
 #define CK_BUS_USB2OHCI		250
 #define CK_BUS_USB2EHCI		251
-#define CK_BUS_USB3DRD		252
+#define CK_BUS_USB3DR		252
 #define CK_KER_LPTIM1		253
 #define CK_KER_LPTIM2		254
 #define CK_KER_USART2		255
@@ -364,8 +363,10 @@
 #define CK_BUS_ETHSWACMCFG	341
 #define CK_BUS_ETHSWACMMSG	342
 #define HSE_DIV2_CK		343
+#define CK_KER_ETR		344
+#define CK_KER_STM		345
 
-#define STM32MP25_LAST_CLK	344
+#define STM32MP25_LAST_CLK	346
 
 #define CK_SCMI_ICN_HS_MCU	0
 #define CK_SCMI_ICN_SDMMC	1
@@ -453,8 +454,7 @@
 #define CK_SCMI_TIMG2		83
 #define CK_SCMI_BKPSRAM		84
 #define CK_SCMI_BSEC		85
-#define CK_SCMI_BUSPERFM	86
-#define CK_SCMI_ETR		87
+#define CK_SCMI_BUS_ETR		87
 #define CK_SCMI_FMC		88
 #define CK_SCMI_GPIOA		89
 #define CK_SCMI_GPIOB		90
@@ -489,6 +489,8 @@
 #define CK_SCMI_SYSDBG		119
 #define CK_SCMI_SYSATB		120
 #define CK_SCMI_TSDBG		121
-#define CK_SCMI_STM500		122
+#define CK_SCMI_BUS_STM		122
+#define CK_SCMI_KER_STM		123
+#define CK_SCMI_KER_ETR		124
 
 #endif /* _DT_BINDINGS_STM32MP25_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp25-clksrc.h b/include/dt-bindings/clock/stm32mp25-clksrc.h
index e6f7154..319fd82 100644
--- a/include/dt-bindings/clock/stm32mp25-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp25-clksrc.h
@@ -1,6 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef _DT_BINDINGS_CLOCK_STM32MP25_CLKSRC_H_
@@ -108,9 +108,8 @@
 #define MUX_DSIPHY	18
 #define MUX_LVDSPHY	19
 #define MUX_DTS		20
-#define MUX_CPU1	21
-#define MUX_D3PER	22
-#define MUX_NB		23
+#define MUX_D3PER	21
+#define MUX_NB		22
 
 #define MUXSEL_HSI		0
 #define MUXSEL_HSE		1
@@ -144,7 +143,7 @@
 #define MUX_USB3PCIEPHY_FLEX34	0x0
 #define MUX_USB3PCIEPHY_HSE	0x1
 
-#define MUX_DSIBLANE_FLEX28	0x0
+#define MUX_DSIBLANE_DSIPHY	0x0
 #define MUX_DSIBLANE_FLEX27	0x1
 
 #define MUX_DSIPHY_FLEX28	0x0
@@ -219,8 +218,8 @@
 
 /* define for st,drive */
 #define LSEDRV_LOWEST		0
-#define LSEDRV_MEDIUM_LOW	1
-#define LSEDRV_MEDIUM_HIGH	2
+#define LSEDRV_MEDIUM_LOW	2
+#define LSEDRV_MEDIUM_HIGH	1
 #define LSEDRV_HIGHEST		3
 
 #endif /* _DT_BINDINGS_CLOCK_STM32MP25_CLKSRC_H_ */
diff --git a/include/dt-bindings/gpio/stm32-gpio.h b/include/dt-bindings/gpio/stm32-gpio.h
new file mode 100644
index 0000000..2c7a0f1
--- /dev/null
+++ b/include/dt-bindings/gpio/stm32-gpio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2024 STMicroelectronics - All Rights Reserved
+ * Author: Paillet Pascal <p.paillet@foss.st.com> for STMicroelectronics.
+ */
+
+#ifndef DT_BINDINGS_STM32_GPIO_H
+#define DT_BINDINGS_STM32_GPIO_H
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A			0U
+#define GPIO_BANK_B			1U
+#define GPIO_BANK_C			2U
+#define GPIO_BANK_D			3U
+#define GPIO_BANK_E			4U
+#define GPIO_BANK_F			5U
+#define GPIO_BANK_G			6U
+#define GPIO_BANK_H			7U
+#define GPIO_BANK_I			8U
+#define GPIO_BANK_J			9U
+#define GPIO_BANK_K			10U
+#define GPIO_BANK_Z			25U
+
+/* Bit 0 is used to set GPIO in input mode */
+#define GPIOF_DIR_OUT			0x0
+#define GPIOF_DIR_IN			0x1
+
+/* Bit 1 is used to set GPIO high level during init */
+#define GPIOF_INIT_LOW			0x0
+#define GPIOF_INIT_HIGH			0x2
+
+#define GPIOF_IN			(GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_LOW		(GPIOF_DIR_OUT | GPIOF_INIT_LOW)
+#define GPIOF_OUT_INIT_HIGH		(GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+/* Bit 2 is used to set GPIO pull up */
+#define GPIOF_PULL_UP			0x4
+/* Bit 3 is used to set GPIO pull down */
+#define GPIOF_PULL_DOWN			0x8
+
+#endif /* DT_BINDINGS_STM32_GPIO_H */
diff --git a/include/dt-bindings/reset/stm32mp25-resets.h b/include/dt-bindings/reset/stm32mp25-resets.h
index c34fe2a..99b8058 100644
--- a/include/dt-bindings/reset/stm32mp25-resets.h
+++ b/include/dt-bindings/reset/stm32mp25-resets.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later or BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author(s): Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
  */
 
@@ -14,16 +14,16 @@
 #define C2_R		8288
 #define C2_HOLDBOOT_R	8608
 #define C1_HOLDBOOT_R	8609
-#define VSW_R		8703
-#define C1MS_R		8808
-#define IWDG2_KER_R	9074
-#define IWDG4_KER_R	9202
-#define C3_R		9312
-#define DDRCP_R		9856
-#define DDRCAPB_R	9888
-#define DDRPHYCAPB_R	9920
-#define DDRCFG_R	9984
-#define DDR_R		10016
+#define VSW_R		8735
+#define C1MS_R		8840
+#define IWDG2_KER_R	9106
+#define IWDG4_KER_R	9234
+#define C3_R		9344
+#define DDRCP_R		9888
+#define DDRCAPB_R	9920
+#define DDRPHYCAPB_R	9952
+#define DDRCFG_R	10016
+#define DDR_R		10048
 #define OSPI1_R		10400
 #define OSPI1DLL_R	10416
 #define OSPI2_R		10432
@@ -115,7 +115,7 @@
 #define USB2_R		16352
 #define USB2PHY1_R	16384
 #define USB2PHY2_R	16416
-#define USB3DRD_R	16448
+#define USB3DR_R	16448
 #define USB3PCIEPHY_R	16480
 #define PCIE_R		16512
 #define USBTC_R		16544
@@ -143,7 +143,6 @@
 #define CRYP2_R		17440
 #define WWDG1_R		17632
 #define WWDG2_R		17664
-#define BUSPERFM_R	17696
 #define VREF_R		17728
 #define DTS_R		17760
 #define CRC_R		17824
@@ -159,6 +158,9 @@
 #define RST_SCMI_C1_HOLDBOOT_R	2
 #define RST_SCMI_C2_HOLDBOOT_R	3
 #define RST_SCMI_FMC		4
-#define RST_SCMI_PCIE		5
+#define RST_SCMI_OSPI1		5
+#define RST_SCMI_OSPI1DLL	6
+#define RST_SCMI_OSPI2		7
+#define RST_SCMI_OSPI2DLL	8
 
 #endif /* _DT_BINDINGS_STM32MP25_RESET_H_ */
diff --git a/include/lib/cpus/aarch64/cortex_a520.h b/include/lib/cpus/aarch64/cortex_a520.h
index 619a15d..ed3401d 100644
--- a/include/lib/cpus/aarch64/cortex_a520.h
+++ b/include/lib/cpus/aarch64/cortex_a520.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,7 @@
 #define CORTEX_A520_CPUACTLR_EL1				S3_0_C15_C1_0
 
 #define CORTEX_A520_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT			U(0)
 
 /*******************************************************************************
  * CPU Auxiliary Control register 1 specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a725.h b/include/lib/cpus/aarch64/cortex_a725.h
new file mode 100644
index 0000000..cb1c099
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a725.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A725_H
+#define CORTEX_A725_H
+
+#define CORTEX_A725_MIDR					U(0x410FD870)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A725_CPUECTLR_EL1_EXTLLC_BIT			U(0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A725_H */
diff --git a/include/lib/cpus/aarch64/cortex_blackhawk.h b/include/lib/cpus/aarch64/cortex_blackhawk.h
deleted file mode 100644
index bfb3039..0000000
--- a/include/lib/cpus/aarch64/cortex_blackhawk.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_BLACKHAWK_H
-#define CORTEX_BLACKHAWK_H
-
-#define CORTEX_BLACKHAWK_MIDR					U(0x410FD850)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_BLACKHAWK_H */
diff --git a/include/lib/cpus/aarch64/cortex_chaberton.h b/include/lib/cpus/aarch64/cortex_chaberton.h
deleted file mode 100644
index 8f10b68..0000000
--- a/include/lib/cpus/aarch64/cortex_chaberton.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_CHABERTON_H
-#define CORTEX_CHABERTON_H
-
-#define CORTEX_CHABERTON_MIDR					U(0x410FD870)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_CHABERTON_H */
diff --git a/include/lib/cpus/aarch64/cortex_x925.h b/include/lib/cpus/aarch64/cortex_x925.h
new file mode 100644
index 0000000..b0d0ca4
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X925_H
+#define CORTEX_X925_H
+
+#define CORTEX_X925_MIDR					U(0x410FD850)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_X925_CPUECTLR_EL1_EXTLLC_BIT			U(0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_X925_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 6faef5d..d49d82e 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -456,6 +456,14 @@
 	msr	\_reg, x0
 .endm
 
+.macro sysreg_bitfield_insert_from_gpr _reg:req, _gpr:req, _lsb:req, _width:req
+	/* Source value in register for BFI */
+	mov	x1, \_gpr
+	mrs	x0, \_reg
+	bfi	x0, x1, #\_lsb, #\_width
+	msr	\_reg, x0
+.endm
+
 /*
  * Apply erratum
  *
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 577de61..51fbfd1 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -30,6 +30,7 @@
  * DSU Cluster Auxiliary Control registers definitions
  ********************************************************************/
 #define CLUSTERACTLR_EL1	S3_0_C15_C3_3
+#define CLUSTERPWRCTLR_EL1	S3_0_C15_C3_5
 
 #define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING	(ULL(1) << 15)
 #define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING	(ULL(3) << 15)
@@ -39,4 +40,7 @@
  ********************************************************************/
 #define DSU_ERRATA_936184_MASK	(U(0x3) << 15)
 
+#ifndef __ASSEMBLER__
+void dsu_pwr_dwn(void);
+#endif
 #endif /* DSU_DEF_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 4f11ad2..7c10506 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -7,6 +7,7 @@
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#include <lib/el3_runtime/context_el1.h>
 #include <lib/el3_runtime/context_el2.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/utils_def.h>
@@ -63,169 +64,29 @@
 #define CTX_ELR_EL3		U(0x20)
 #define CTX_PMCR_EL0		U(0x28)
 #define CTX_IS_IN_EL3		U(0x30)
+#define CTX_MDCR_EL3		U(0x38)
 /* Constants required in supporting nested exception in EL3 */
-#define CTX_SAVED_ELR_EL3	U(0x38)
+#define CTX_SAVED_ELR_EL3	U(0x40)
 /*
  * General purpose flag, to save various EL3 states
  * FFH mode : Used to identify if handling nested exception
  * KFH mode : Used as counter value
  */
-#define CTX_NESTED_EA_FLAG	U(0x40)
+#define CTX_NESTED_EA_FLAG	U(0x48)
 #if FFH_SUPPORT
- #define CTX_SAVED_ESR_EL3	U(0x48)
- #define CTX_SAVED_SPSR_EL3	U(0x50)
- #define CTX_SAVED_GPREG_LR	U(0x58)
- #define CTX_EL3STATE_END	U(0x60) /* Align to the next 16 byte boundary */
+ #define CTX_SAVED_ESR_EL3	U(0x50)
+ #define CTX_SAVED_SPSR_EL3	U(0x58)
+ #define CTX_SAVED_GPREG_LR	U(0x60)
+ #define CTX_EL3STATE_END	U(0x70) /* Align to the next 16 byte boundary */
 #else
  #define CTX_EL3STATE_END	U(0x50) /* Align to the next 16 byte boundary */
 #endif /* FFH_SUPPORT */
 
 /*******************************************************************************
- * Constants that allow assembler code to access members of and the
- * 'el1_sys_regs' structure at their correct offsets. Note that some of the
- * registers are only 32-bits wide but are stored as 64-bit values for
- * convenience
- ******************************************************************************/
-#define CTX_EL1_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
-#define CTX_SPSR_EL1		U(0x0)
-#define CTX_ELR_EL1		U(0x8)
-#define CTX_SCTLR_EL1		U(0x10)
-#define CTX_TCR_EL1		U(0x18)
-#define CTX_CPACR_EL1		U(0x20)
-#define CTX_CSSELR_EL1		U(0x28)
-#define CTX_SP_EL1		U(0x30)
-#define CTX_ESR_EL1		U(0x38)
-#define CTX_TTBR0_EL1		U(0x40)
-#define CTX_TTBR1_EL1		U(0x48)
-#define CTX_MAIR_EL1		U(0x50)
-#define CTX_AMAIR_EL1		U(0x58)
-#define CTX_ACTLR_EL1		U(0x60)
-#define CTX_TPIDR_EL1		U(0x68)
-#define CTX_TPIDR_EL0		U(0x70)
-#define CTX_TPIDRRO_EL0		U(0x78)
-#define CTX_PAR_EL1		U(0x80)
-#define CTX_FAR_EL1		U(0x88)
-#define CTX_AFSR0_EL1		U(0x90)
-#define CTX_AFSR1_EL1		U(0x98)
-#define CTX_CONTEXTIDR_EL1	U(0xa0)
-#define CTX_VBAR_EL1		U(0xa8)
-#define CTX_MDCCINT_EL1		U(0xb0)
-#define CTX_MDSCR_EL1		U(0xb8)
-
-#define CTX_AARCH64_END		U(0xc0) /* Align to the next 16 byte boundary */
-
-/*
- * If the platform is AArch64-only, there is no need to save and restore these
- * AArch32 registers.
- */
-#if CTX_INCLUDE_AARCH32_REGS
-#define CTX_SPSR_ABT		(CTX_AARCH64_END + U(0x0))
-#define CTX_SPSR_UND		(CTX_AARCH64_END + U(0x8))
-#define CTX_SPSR_IRQ		(CTX_AARCH64_END + U(0x10))
-#define CTX_SPSR_FIQ		(CTX_AARCH64_END + U(0x18))
-#define CTX_DACR32_EL2		(CTX_AARCH64_END + U(0x20))
-#define CTX_IFSR32_EL2		(CTX_AARCH64_END + U(0x28))
-#define CTX_AARCH32_END		(CTX_AARCH64_END + U(0x30)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_AARCH32_END		CTX_AARCH64_END
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-/*
- * If the timer registers aren't saved and restored, we don't have to reserve
- * space for them in the context
- */
-#if NS_TIMER_SWITCH
-#define CTX_CNTP_CTL_EL0	(CTX_AARCH32_END + U(0x0))
-#define CTX_CNTP_CVAL_EL0	(CTX_AARCH32_END + U(0x8))
-#define CTX_CNTV_CTL_EL0	(CTX_AARCH32_END + U(0x10))
-#define CTX_CNTV_CVAL_EL0	(CTX_AARCH32_END + U(0x18))
-#define CTX_CNTKCTL_EL1		(CTX_AARCH32_END + U(0x20))
-#define CTX_TIMER_SYSREGS_END	(CTX_AARCH32_END + U(0x30)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_TIMER_SYSREGS_END	CTX_AARCH32_END
-#endif /* NS_TIMER_SWITCH */
-
-#if ENABLE_FEAT_MTE2
-#define CTX_TFSRE0_EL1		(CTX_TIMER_SYSREGS_END + U(0x0))
-#define CTX_TFSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x8))
-#define CTX_RGSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x10))
-#define CTX_GCR_EL1		(CTX_TIMER_SYSREGS_END + U(0x18))
-#define CTX_MTE_REGS_END	(CTX_TIMER_SYSREGS_END + U(0x20)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_MTE_REGS_END	CTX_TIMER_SYSREGS_END
-#endif /* ENABLE_FEAT_MTE2 */
-
-#if ENABLE_FEAT_RAS
-#define CTX_DISR_EL1		(CTX_MTE_REGS_END + U(0x0))
-#define CTX_RAS_REGS_END	(CTX_MTE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_RAS_REGS_END        CTX_MTE_REGS_END
-#endif /* ENABLE_FEAT_RAS */
-
-#if ENABLE_FEAT_S1PIE
-#define CTX_PIRE0_EL1		(CTX_RAS_REGS_END + U(0x0))
-#define CTX_PIR_EL1		(CTX_RAS_REGS_END + U(0x8))
-#define CTX_S1PIE_REGS_END	(CTX_RAS_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_S1PIE_REGS_END	CTX_RAS_REGS_END
-#endif /* ENABLE_FEAT_S1PIE */
-
-#if ENABLE_FEAT_S1POE
-#define CTX_POR_EL1		(CTX_S1PIE_REGS_END + U(0x0))
-#define CTX_S1POE_REGS_END	(CTX_S1PIE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_S1POE_REGS_END	CTX_S1PIE_REGS_END
-#endif /* ENABLE_FEAT_S1POE */
-
-#if ENABLE_FEAT_S2POE
-#define CTX_S2POR_EL1		(CTX_S1POE_REGS_END + U(0x0))
-#define CTX_S2POE_REGS_END	(CTX_S1POE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_S2POE_REGS_END	CTX_S1POE_REGS_END
-#endif /* ENABLE_FEAT_S2POE */
-
-#if ENABLE_FEAT_TCR2
-#define CTX_TCR2_EL1		(CTX_S2POE_REGS_END + U(0x0))
-#define CTX_TCR2_REGS_END	(CTX_S2POE_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_TCR2_REGS_END       CTX_S2POE_REGS_END
-#endif /* ENABLE_FEAT_TCR2 */
-
-#if ENABLE_TRF_FOR_NS
-#define CTX_TRFCR_EL1		(CTX_TCR2_REGS_END + U(0x0))
-#define CTX_TRF_REGS_END	(CTX_TCR2_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_TRF_REGS_END	CTX_TCR2_REGS_END
-#endif /* ENABLE_TRF_FOR_NS */
-
-#if ENABLE_FEAT_CSV2_2
-#define CTX_SCXTNUM_EL0		(CTX_TRF_REGS_END + U(0x0))
-#define CTX_SCXTNUM_EL1		(CTX_TRF_REGS_END + U(0x8))
-#define CTX_CSV2_2_REGS_END	(CTX_TRF_REGS_END + U(0x10)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_CSV2_2_REGS_END	CTX_TRF_REGS_END
-#endif /* ENABLE_FEAT_CSV2_2 */
-
-#if ENABLE_FEAT_GCS
-#define CTX_GCSCR_EL1		(CTX_CSV2_2_REGS_END + U(0x0))
-#define CTX_GCSCRE0_EL1		(CTX_CSV2_2_REGS_END + U(0x8))
-#define CTX_GCSPR_EL1		(CTX_CSV2_2_REGS_END + U(0x10))
-#define CTX_GCSPR_EL0		(CTX_CSV2_2_REGS_END + U(0x18))
-#define CTX_GCS_REGS_END	(CTX_CSV2_2_REGS_END + U(0x20)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_GCS_REGS_END	CTX_CSV2_2_REGS_END
-#endif /* ENABLE_FEAT_GCS */
-
-/*
- * End of EL1 system registers.
- */
-#define CTX_EL1_SYSREGS_END	CTX_GCS_REGS_END
-
-/*******************************************************************************
  * Constants that allow assembler code to access members of and the 'fp_regs'
  * structure at their correct offsets.
  ******************************************************************************/
-# define CTX_FPREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
+# define CTX_FPREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
 #if CTX_INCLUDE_FPREGS
 #define CTX_FP_Q0		U(0x0)
 #define CTX_FP_Q1		U(0x10)
@@ -279,9 +140,53 @@
 #define CTX_CVE_2018_3639_END		U(0x10) /* Align to the next 16 byte boundary */
 
 /*******************************************************************************
+ * Registers related to ERRATA_SPECULATIVE_AT
+ *
+ * This is essential as with EL1 and EL2 context registers being decoupled,
+ * both will not be present for a given build configuration.
+ * As ERRATA_SPECULATIVE_AT errata requires SCTLR_EL1 and TCR_EL1 registers
+ * independent of the above logic, we need explicit context entries to be
+ * reserved for these registers.
+ *
+ * NOTE: Based on this we end up with following different configurations depending
+ * on the presence of errata and inclusion of EL1 or EL2 context.
+ *
+ * ============================================================================
+ * | ERRATA_SPECULATIVE_AT | EL1 context| Memory allocation(Sctlr_el1,Tcr_el1)|
+ * ============================================================================
+ * |        0              |      0     |            None                     |
+ * |        0              |      1     |    EL1 C-Context structure          |
+ * |        1              |      0     |    Errata Context Offset Entries    |
+ * |        1              |      1     |    Errata Context Offset Entries    |
+ * ============================================================================
+ *
+ * In the above table, when ERRATA_SPECULATIVE_AT=1, EL1_Context=0, it implies
+ * there is only EL2 context and memory for SCTLR_EL1 and TCR_EL1 registers is
+ * reserved explicitly under ERRATA_SPECULATIVE_AT build flag here.
+ *
+ * In situations when EL1_Context=1 and  ERRATA_SPECULATIVE_AT=1, since SCTLR_EL1
+ * and TCR_EL1 registers will be modified under errata and it happens at the
+ * early in the codeflow prior to el1 context (save and restore operations),
+ * context memory still will be reserved under the errata logic here explicitly.
+ * These registers will not be part of EL1 context save & restore routines.
+ *
+ * Only when ERRATA_SPECULATIVE_AT=0, EL1_Context=1, for this combination,
+ * SCTLR_EL1 and TCR_EL1 will be part of EL1 context structure (context_el1.h)
+ * -----------------------------------------------------------------------------
+ ******************************************************************************/
+#define CTX_ERRATA_SPEC_AT_OFFSET	(CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END)
+#if ERRATA_SPECULATIVE_AT
+#define CTX_ERRATA_SPEC_AT_SCTLR_EL1	U(0x0)
+#define CTX_ERRATA_SPEC_AT_TCR_EL1	U(0x8)
+#define CTX_ERRATA_SPEC_AT_END		U(0x10) /* Align to the next 16 byte boundary */
+#else
+#define CTX_ERRATA_SPEC_AT_END		U(0x0)
+#endif /* ERRATA_SPECULATIVE_AT */
+
+/*******************************************************************************
  * Registers related to ARMv8.3-PAuth.
  ******************************************************************************/
-#define CTX_PAUTH_REGS_OFFSET	(CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END)
+#define CTX_PAUTH_REGS_OFFSET	(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_END)
 #if CTX_INCLUDE_PAUTH_REGS
 #define CTX_PACIAKEY_LO		U(0x0)
 #define CTX_PACIAKEY_HI		U(0x8)
@@ -299,27 +204,6 @@
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 /*******************************************************************************
- * Registers related to ARMv8.2-MPAM.
- ******************************************************************************/
-#define CTX_MPAM_REGS_OFFSET	(CTX_PAUTH_REGS_OFFSET + CTX_PAUTH_REGS_END)
-#if CTX_INCLUDE_MPAM_REGS
-#define CTX_MPAM2_EL2		U(0x0)
-#define CTX_MPAMHCR_EL2		U(0x8)
-#define CTX_MPAMVPM0_EL2	U(0x10)
-#define CTX_MPAMVPM1_EL2	U(0x18)
-#define CTX_MPAMVPM2_EL2	U(0x20)
-#define CTX_MPAMVPM3_EL2	U(0x28)
-#define CTX_MPAMVPM4_EL2	U(0x30)
-#define CTX_MPAMVPM5_EL2	U(0x38)
-#define CTX_MPAMVPM6_EL2	U(0x40)
-#define CTX_MPAMVPM7_EL2	U(0x48)
-#define CTX_MPAMVPMV_EL2	U(0x50)
-#define CTX_MPAM_REGS_END	U(0x60)
-#else
-#define CTX_MPAM_REGS_END	U(0x0)
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-/*******************************************************************************
  * Registers initialised in a per-world context.
  ******************************************************************************/
 #define CTX_CPTR_EL3			U(0x0)
@@ -345,19 +229,19 @@
 
 /* Constants to determine the size of individual context structures */
 #define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
-#define CTX_EL1_SYSREGS_ALL	(CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
 
 #if CTX_INCLUDE_FPREGS
 # define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
 #endif
 #define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)
 #define CTX_CVE_2018_3639_ALL	(CTX_CVE_2018_3639_END >> DWORD_SHIFT)
+
+#if ERRATA_SPECULATIVE_AT
+#define CTX_ERRATA_SPEC_AT_ALL	(CTX_ERRATA_SPEC_AT_END >> DWORD_SHIFT)
+#endif
 #if CTX_INCLUDE_PAUTH_REGS
 # define CTX_PAUTH_REGS_ALL	(CTX_PAUTH_REGS_END >> DWORD_SHIFT)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define CTX_MPAM_REGS_ALL	(CTX_MPAM_REGS_END >> DWORD_SHIFT)
-#endif
 
 /*
  * AArch64 general purpose register context structure. Usually x0-x18,
@@ -369,12 +253,6 @@
 DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
 
 /*
- * AArch64 EL1 system register context structure for preserving the
- * architectural state during world switches.
- */
-DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);
-
-/*
  * AArch64 floating point register context structure for preserving
  * the floating point state during switches from one security state to
  * another.
@@ -392,16 +270,16 @@
 /* Function pointer used by CVE-2018-3639 dynamic mitigation */
 DEFINE_REG_STRUCT(cve_2018_3639, CTX_CVE_2018_3639_ALL);
 
+/* Registers associated to Errata_Speculative */
+#if ERRATA_SPECULATIVE_AT
+DEFINE_REG_STRUCT(errata_speculative_at, CTX_ERRATA_SPEC_AT_ALL);
+#endif
+
 /* Registers associated to ARMv8.3-PAuth */
 #if CTX_INCLUDE_PAUTH_REGS
 DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
 #endif
 
-/* Registers associated to ARMv8.2 MPAM */
-#if CTX_INCLUDE_MPAM_REGS
-DEFINE_REG_STRUCT(mpam, CTX_MPAM_REGS_ALL);
-#endif
-
 /*
  * Macros to access members of any of the above structures using their
  * offsets
@@ -421,20 +299,21 @@
 typedef struct cpu_context {
 	gp_regs_t gpregs_ctx;
 	el3_state_t el3state_ctx;
-	el1_sysregs_t el1_sysregs_ctx;
 
 #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;
-#endif
+	el1_sysregs_t el1_sysregs_ctx;
 
 #if CTX_INCLUDE_EL2_REGS
 	el2_sysregs_t el2_sysregs_ctx;
@@ -465,12 +344,14 @@
 #endif
 #define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
 #define get_cve_2018_3639_ctx(h)	(&((cpu_context_t *) h)->cve_2018_3639_ctx)
+
+#if ERRATA_SPECULATIVE_AT
+#define get_errata_speculative_at_ctx(h)	(&((cpu_context_t *) h)->errata_speculative_at_ctx)
+#endif
+
 #if CTX_INCLUDE_PAUTH_REGS
 # define get_pauth_ctx(h)	(&((cpu_context_t *) h)->pauth_ctx)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define get_mpam_ctx(h)	(&((cpu_context_t *) h)->mpam_ctx)
-#endif
 
 /*
  * Compile time assertions related to the 'cpu_context' structure to
@@ -483,9 +364,6 @@
 CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
 	assert_core_context_el3state_offset_mismatch);
 
-CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx),
-	assert_core_context_el1_sys_offset_mismatch);
-
 #if CTX_INCLUDE_FPREGS
 CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx),
 	assert_core_context_fp_offset_mismatch);
@@ -494,16 +372,16 @@
 CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx),
 	assert_core_context_cve_2018_3639_offset_mismatch);
 
+#if ERRATA_SPECULATIVE_AT
+CASSERT(CTX_ERRATA_SPEC_AT_OFFSET == __builtin_offsetof(cpu_context_t, errata_speculative_at_ctx),
+	assert_core_context_errata_speculative_at_offset_mismatch);
+#endif
+
 #if CTX_INCLUDE_PAUTH_REGS
 CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 	assert_core_context_pauth_offset_mismatch);
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
-#if CTX_INCLUDE_MPAM_REGS
-CASSERT(CTX_MPAM_REGS_OFFSET == __builtin_offsetof(cpu_context_t, mpam_ctx),
-	assert_core_context_mpam_offset_mismatch);
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
 /*
  * Helper macro to set the general purpose registers that correspond to
  * parameters in an aapcs_64 call i.e. x0-x7
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
new file mode 100644
index 0000000..038de25
--- /dev/null
+++ b/include/lib/el3_runtime/context_el1.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONTEXT_EL1_H
+#define CONTEXT_EL1_H
+
+#ifndef __ASSEMBLER__
+
+/*******************************************************************************
+ * EL1 Registers:
+ * AArch64 EL1 system register context structure for preserving the
+ * architectural state during world switches.
+ ******************************************************************************/
+
+typedef struct el1_common_regs {
+	uint64_t spsr_el1;
+	uint64_t elr_el1;
+
+#if (!ERRATA_SPECULATIVE_AT)
+	uint64_t sctlr_el1;
+	uint64_t tcr_el1;
+#endif /* ERRATA_SPECULATIVE_AT=0 */
+
+	uint64_t cpacr_el1;
+	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;
+	uint64_t contextidr_el1;
+	uint64_t vbar_el1;
+	uint64_t mdccint_el1;
+	uint64_t mdscr_el1;
+} el1_common_regs_t;
+
+typedef struct el1_aarch32_regs {
+	uint64_t spsr_abt;
+	uint64_t spsr_und;
+	uint64_t spsr_irq;
+	uint64_t spsr_fiq;
+	uint64_t dacr32_el2;
+	uint64_t ifsr32_el2;
+} el1_aarch32_regs_t;
+
+typedef struct el1_arch_timer_regs {
+	uint64_t cntp_ctl_el0;
+	uint64_t cntp_cval_el0;
+	uint64_t cntv_ctl_el0;
+	uint64_t cntv_cval_el0;
+	uint64_t cntkctl_el1;
+} el1_arch_timer_regs_t;
+
+typedef struct el1_mte2_regs {
+	uint64_t tfsre0_el1;
+	uint64_t tfsr_el1;
+	uint64_t rgsr_el1;
+	uint64_t gcr_el1;
+} el1_mte2_regs_t;
+
+typedef struct el1_ras_regs {
+	uint64_t disr_el1;
+} el1_ras_regs_t;
+
+typedef struct el1_s1pie_regs {
+	uint64_t pire0_el1;
+	uint64_t pir_el1;
+} el1_s1pie_regs_t;
+
+typedef struct el1_s1poe_regs {
+	uint64_t por_el1;
+} el1_s1poe_regs_t;
+
+typedef struct el1_s2poe_regs {
+	uint64_t s2por_el1;
+} el1_s2poe_regs_t;
+
+typedef struct el1_tcr2_regs {
+	uint64_t tcr2_el1;
+} el1_tcr2_regs_t;
+
+typedef struct el1_trf_regs {
+	uint64_t trfcr_el1;
+} el1_trf_regs_t;
+
+typedef struct el1_csv2_2_regs {
+	uint64_t scxtnum_el0;
+	uint64_t scxtnum_el1;
+} el1_csv2_2_regs_t;
+
+typedef struct el1_gcs_regs {
+	uint64_t gcscr_el1;
+	uint64_t gcscre0_el1;
+	uint64_t gcspr_el1;
+	uint64_t gcspr_el0;
+} el1_gcs_regs_t;
+
+typedef struct el1_sysregs {
+
+	el1_common_regs_t common;
+
+#if CTX_INCLUDE_AARCH32_REGS
+	el1_aarch32_regs_t el1_aarch32;
+#endif
+
+#if NS_TIMER_SWITCH
+	el1_arch_timer_regs_t arch_timer;
+#endif
+
+#if ENABLE_FEAT_MTE2
+	el1_mte2_regs_t mte2;
+#endif
+
+#if ENABLE_FEAT_RAS
+	el1_ras_regs_t ras;
+#endif
+
+#if ENABLE_FEAT_S1PIE
+	el1_s1pie_regs_t s1pie;
+#endif
+
+#if ENABLE_FEAT_S1POE
+	el1_s1poe_regs_t s1poe;
+#endif
+
+#if ENABLE_FEAT_S2POE
+	el1_s2poe_regs_t s2poe;
+#endif
+
+#if ENABLE_FEAT_TCR2
+	el1_tcr2_regs_t tcr2;
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	el1_trf_regs_t trf;
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	el1_csv2_2_regs_t csv2_2;
+#endif
+
+#if ENABLE_FEAT_GCS
+	el1_gcs_regs_t gcs;
+#endif
+
+} el1_sysregs_t;
+
+
+/*
+ * Macros to access members related to individual features of the el1_sysregs_t
+ * structures.
+ */
+
+#define read_el1_ctx_common(ctx, reg)		(((ctx)->common).reg)
+
+#define write_el1_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (uint64_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)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_arch_timer(ctx, reg)		ULL(0)
+#define write_el1_ctx_arch_timer(ctx, reg, val)
+#endif /* NS_TIMER_SWITCH */
+
+#if CTX_INCLUDE_AARCH32_REGS
+#define read_el1_ctx_aarch32(ctx, reg)		(((ctx)->el1_aarch32).reg)
+#define write_el1_ctx_aarch32(ctx, reg, val)	((((ctx)->el1_aarch32).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_aarch32(ctx, reg)		ULL(0)
+#define write_el1_ctx_aarch32(ctx, reg, val)
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
+#if ENABLE_FEAT_MTE2
+#define read_el1_ctx_mte2(ctx, reg)		(((ctx)->mte2).reg)
+#define write_el1_ctx_mte2(ctx, reg, val)	((((ctx)->mte2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_mte2(ctx, reg)		ULL(0)
+#define write_el1_ctx_mte2(ctx, reg, val)
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_RAS
+#define read_el1_ctx_ras(ctx, reg)		(((ctx)->ras).reg)
+#define write_el1_ctx_ras(ctx, reg, val)	((((ctx)->ras).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_ras(ctx, reg)		ULL(0)
+#define write_el1_ctx_ras(ctx, reg, val)
+#endif /* ENABLE_FEAT_RAS */
+
+#if ENABLE_FEAT_S1PIE
+#define read_el1_ctx_s1pie(ctx, reg)		(((ctx)->s1pie).reg)
+#define write_el1_ctx_s1pie(ctx, reg, val)	((((ctx)->s1pie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s1pie(ctx, reg)		ULL(0)
+#define write_el1_ctx_s1pie(ctx, reg, val)
+#endif /* ENABLE_FEAT_S1PIE */
+
+#if ENABLE_FEAT_S1POE
+#define read_el1_ctx_s1poe(ctx, reg)		(((ctx)->s1poe).reg)
+#define write_el1_ctx_s1poe(ctx, reg, val)	((((ctx)->s1poe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s1poe(ctx, reg)		ULL(0)
+#define write_el1_ctx_s1poe(ctx, reg, val)
+#endif /* ENABLE_FEAT_S1POE */
+
+#if ENABLE_FEAT_S2POE
+#define read_el1_ctx_s2poe(ctx, reg)		(((ctx)->s2poe).reg)
+#define write_el1_ctx_s2poe(ctx, reg, val)	((((ctx)->s2poe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s2poe(ctx, reg)		ULL(0)
+#define write_el1_ctx_s2poe(ctx, reg, val)
+#endif /* ENABLE_FEAT_S2POE */
+
+#if ENABLE_FEAT_TCR2
+#define read_el1_ctx_tcr2(ctx, reg)		(((ctx)->tcr2).reg)
+#define write_el1_ctx_tcr2(ctx, reg, val)	((((ctx)->tcr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_tcr2(ctx, reg)		ULL(0)
+#define write_el1_ctx_tcr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_TCR2 */
+
+#if ENABLE_TRF_FOR_NS
+#define read_el1_ctx_trf(ctx, reg)		(((ctx)->trf).reg)
+#define write_el1_ctx_trf(ctx, reg, val)	((((ctx)->trf).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_trf(ctx, reg)		ULL(0)
+#define write_el1_ctx_trf(ctx, reg, val)
+#endif /* ENABLE_TRF_FOR_NS */
+
+#if ENABLE_FEAT_CSV2_2
+#define read_el1_ctx_csv2_2(ctx, reg)		(((ctx)->csv2_2).reg)
+#define write_el1_ctx_csv2_2(ctx, reg, val)	((((ctx)->csv2_2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_csv2_2(ctx, reg)		ULL(0)
+#define write_el1_ctx_csv2_2(ctx, reg, val)
+#endif /* ENABLE_FEAT_CSV2_2 */
+
+#if ENABLE_FEAT_GCS
+#define read_el1_ctx_gcs(ctx, reg)		(((ctx)->gcs).reg)
+#define write_el1_ctx_gcs(ctx, reg, val)	((((ctx)->gcs).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_gcs(ctx, reg)		ULL(0)
+#define write_el1_ctx_gcs(ctx, reg, val)
+#endif /* ENABLE_FEAT_GCS */
+/******************************************************************************/
+#endif /* __ASSEMBLER__ */
+
+#endif /* CONTEXT_EL1_H */
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 04f6587..ca1ea4e 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -62,6 +62,14 @@
 	uint64_t hfgwtr_el2;
 } el2_fgt_regs_t;
 
+typedef struct el2_fgt2_regs {
+	uint64_t hdfgrtr2_el2;
+	uint64_t hdfgwtr2_el2;
+	uint64_t hfgitr2_el2;
+	uint64_t hfgrtr2_el2;
+	uint64_t hfgwtr2_el2;
+} el2_fgt2_regs_t;
+
 typedef struct el2_ecv_regs {
 	uint64_t cntpoff_el2;
 } el2_ecv_regs_t;
@@ -114,6 +122,20 @@
 	uint64_t gcspr_el2;
 } el2_gcs_regs_t;
 
+typedef struct el2_mpam_regs {
+	uint64_t mpam2_el2;
+	uint64_t mpamhcr_el2;
+	uint64_t mpamvpm0_el2;
+	uint64_t mpamvpm1_el2;
+	uint64_t mpamvpm2_el2;
+	uint64_t mpamvpm3_el2;
+	uint64_t mpamvpm4_el2;
+	uint64_t mpamvpm5_el2;
+	uint64_t mpamvpm6_el2;
+	uint64_t mpamvpm7_el2;
+	uint64_t mpamvpmv_el2;
+} el2_mpam_regs_t;
+
 typedef struct el2_sysregs {
 
 	el2_common_regs_t common;
@@ -126,6 +148,10 @@
 	el2_fgt_regs_t fgt;
 #endif
 
+#if ENABLE_FEAT_FGT2
+	el2_fgt2_regs_t fgt2;
+#endif
+
 #if ENABLE_FEAT_ECV
 	el2_ecv_regs_t ecv;
 #endif
@@ -174,6 +200,10 @@
 	el2_gcs_regs_t gcs;
 #endif
 
+#if CTX_INCLUDE_MPAM_REGS
+	el2_mpam_regs_t mpam;
+#endif
+
 } el2_sysregs_t;
 
 /*
@@ -203,6 +233,15 @@
 #define write_el2_ctx_fgt(ctx, reg, val)
 #endif /* ENABLE_FEAT_FGT */
 
+#if ENABLE_FEAT_FGT2
+#define read_el2_ctx_fgt2(ctx, reg)		(((ctx)->fgt2).reg)
+#define write_el2_ctx_fgt2(ctx, reg, val)	((((ctx)->fgt2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_fgt2(ctx, reg)		ULL(0)
+#define write_el2_ctx_fgt2(ctx, reg, val)
+#endif /* ENABLE_FEAT_FGT */
+
 #if ENABLE_FEAT_ECV
 #define read_el2_ctx_ecv(ctx, reg)		(((ctx)->ecv).reg)
 #define write_el2_ctx_ecv(ctx, reg, val)	((((ctx)->ecv).reg)	\
@@ -311,6 +350,15 @@
 #define write_el2_ctx_gcs(ctx, reg, val)
 #endif /* ENABLE_FEAT_GCS */
 
+#if CTX_INCLUDE_MPAM_REGS
+#define read_el2_ctx_mpam(ctx, reg)		(((ctx)->mpam).reg)
+#define write_el2_ctx_mpam(ctx, reg, val)	((((ctx)->mpam).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mpam(ctx, reg)		ULL(0)
+#define write_el2_ctx_mpam(ctx, reg, val)
+#endif /* CTX_INCLUDE_MPAM_REGS */
+
 #endif /* CTX_INCLUDE_EL2_REGS */
 /******************************************************************************/
 
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
index 194efba..425a037 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.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
  */
@@ -7,10 +7,12 @@
 #ifndef BRBE_H
 #define BRBE_H
 
+#include <context.h>
+
 #if ENABLE_BRBE_FOR_NS
-void brbe_init_el3(void);
+void brbe_enable(cpu_context_t *ctx);
 #else
-static inline void brbe_init_el3(void)
+static inline void brbe_enable(cpu_context_t *ctx)
 {
 }
 #endif /* ENABLE_BRBE_FOR_NS */
diff --git a/include/lib/extensions/debug_v8p9.h b/include/lib/extensions/debug_v8p9.h
new file mode 100644
index 0000000..d72c9ea
--- /dev/null
+++ b/include/lib/extensions/debug_v8p9.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEBUG_V8P9_H
+#define DEBUG_V8P9_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_DEBUGV8P9
+void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx);
+#else
+static inline void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_DEBUGV8P9 */
+
+#endif /* DEBUG_V8P9_H */
diff --git a/include/lib/extensions/fgt2.h b/include/lib/extensions/fgt2.h
new file mode 100644
index 0000000..0388d18
--- /dev/null
+++ b/include/lib/extensions/fgt2.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FGT2_H
+#define FGT2_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_FGT2
+void fgt2_enable(cpu_context_t *ctx);
+#else
+static inline void fgt2_enable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_FGT2 */
+
+#endif /* FGT2_H */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 7b39037..4801a22 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.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
  */
@@ -8,19 +8,24 @@
 #define SPE_H
 
 #include <stdbool.h>
+#include <context.h>
 
 #if ENABLE_SPE_FOR_NS
-void spe_init_el3(void);
+void spe_enable(cpu_context_t *ctx);
+void spe_disable(cpu_context_t *ctx);
 void spe_init_el2_unused(void);
-void spe_disable(void);
+void spe_stop(void);
 #else
-static inline void spe_init_el3(void)
+static inline void spe_enable(cpu_context_t *ctx)
+{
+}
+static inline void spe_disable(cpu_context_t *ctx)
 {
 }
 static inline void spe_init_el2_unused(void)
 {
 }
-static inline void spe_disable(void)
+static inline void spe_stop(void)
 {
 }
 #endif /* ENABLE_SPE_FOR_NS */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 0bed433..2c488e0 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,11 +7,17 @@
 #ifndef TRBE_H
 #define TRBE_H
 
+#include <context.h>
+
 #if ENABLE_TRBE_FOR_NS
-void trbe_init_el3(void);
+void trbe_disable(cpu_context_t *ctx);
+void trbe_enable(cpu_context_t *ctx);
 void trbe_init_el2_unused(void);
 #else
-static inline void trbe_init_el3(void)
+static inline void trbe_disable(cpu_context_t *ctx)
+{
+}
+static inline void trbe_enable(cpu_context_t *ctx)
 {
 }
 static inline void trbe_init_el2_unused(void)
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index 1ac7cda..f0a946b 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,16 +7,32 @@
 #ifndef TRF_H
 #define TRF_H
 
+#include <context.h>
+
 #if ENABLE_TRF_FOR_NS
-void trf_init_el3(void);
+
+#if __aarch64__
+void trf_enable(cpu_context_t *ctx);
 void trf_init_el2_unused(void);
-#else
-static inline void trf_init_el3(void)
+#else /* !__aarch64 */
+void trf_init_el3(void);
+#endif /* __aarch64__ */
+
+#else /* ENABLE_TRF_FOR_NS=0 */
+
+#if __aarch64__
+static inline void trf_enable(cpu_context_t *ctx)
 {
 }
 static inline void trf_init_el2_unused(void)
 {
 }
+#else /* !__aarch64 */
+static inline void trf_init_el3(void)
+{
+}
+#endif /* __aarch64__*/
+
 #endif /* ENABLE_TRF_FOR_NS */
 
 #endif /* TRF_H */
diff --git a/include/lib/psa/cca_attestation.h b/include/lib/psa/cca_attestation.h
new file mode 100644
index 0000000..4062dde
--- /dev/null
+++ b/include/lib/psa/cca_attestation.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_ATTESTATION_H
+#define CCA_ATTESTATION_H
+
+#include <stdint.h>
+#include <psa/crypto_types.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type);
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size);
+
+#endif /* CCA_ATTESTATION_H */
diff --git a/include/lib/psa/rse_crypto_defs.h b/include/lib/psa/rse_crypto_defs.h
index 44936b8..b94664f 100644
--- a/include/lib/psa/rse_crypto_defs.h
+++ b/include/lib/psa/rse_crypto_defs.h
@@ -16,7 +16,7 @@
  * to the corresponding API implementation in the Crypto service backend.
  *
  */
-#define RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x701)
+#define RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x206)
 
 /*
  * The persistent key identifiers for RSE builtin keys.
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 5bea270..1b5ec2d 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -29,7 +29,22 @@
  * Version of the register convention used.
  * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
  */
-#define REGISTER_CONVENTION_VERSION_MASK (1 << 24)
+#define REGISTER_CONVENTION_VERSION_SHIFT_64	UL(32)
+#define REGISTER_CONVENTION_VERSION_SHIFT_32	UL(24)
+#define REGISTER_CONVENTION_VERSION_MASK	UL(0xff)
+#define REGISTER_CONVENTION_VERSION 	UL(1)
+
+#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_64))
+
+#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_32))
 
 #ifndef __ASSEMBLER__
 
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 8a03c7d..c3f767e 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -19,8 +19,13 @@
 
 #define SIZE_FROM_LOG2_WORDS(n)		(U(4) << (n))
 
+#if defined(__LINKER__) || defined(__ASSEMBLER__)
 #define BIT_32(nr)			(U(1) << (nr))
 #define BIT_64(nr)			(ULL(1) << (nr))
+#else
+#define BIT_32(nr)			(((uint32_t)(1U)) << (nr))
+#define BIT_64(nr)			(((uint64_t)(1ULL)) << (nr))
+#endif
 
 #ifdef __aarch64__
 #define BIT				BIT_64
@@ -29,22 +34,22 @@
 #endif
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #if defined(__LINKER__) || defined(__ASSEMBLER__)
-#define GENMASK_32(h, l) \
-	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	(((0xFFFFFFFF) << (low)) & (0xFFFFFFFF >> (32 - 1 - (high))))
 
-#define GENMASK_64(h, l) \
-	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~0 << (low)) & (~0 >> (64 - 1 - (high))))
 #else
-#define GENMASK_32(h, l) \
-	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	((~UINT32_C(0) >> (32U - 1U - (high))) ^ ((BIT_32(low) - 1U)))
 
-#define GENMASK_64(h, l) \
-	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~UINT64_C(0) >> (64U - 1U - (high))) ^ ((BIT_64(low) - 1U)))
 #endif
 
 #ifdef __aarch64__
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 2d0949b..5434a9a 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -171,8 +171,10 @@
 #define SHAREABILITY_SHIFT		8
 /* The Access Flag, AF. */
 #define ACCESS_FLAG_SHIFT		10
-/* The not global bit, nG. */
+/* The not global bit, nG */
 #define NOT_GLOBAL_SHIFT		11
+/* The Non-secure Extension bit, NSE */
+#define NSE_SHIFT			11
 /* Contiguous hint bit. */
 #define CONT_HINT_SHIFT			52
 /* Execute-never bits, XN. */
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index cb11dac..43a77e3 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -17,6 +17,7 @@
 
 /* V2M motherboard system registers & offsets */
 #define V2M_SYSREGS_BASE		UL(0x1c010000)
+#define V2M_SYSREGS_SIZE		UL(0x00010000)
 #define V2M_SYS_ID			UL(0x0)
 #define V2M_SYS_SWITCH			UL(0x4)
 #define V2M_SYS_LED			UL(0x8)
@@ -78,6 +79,8 @@
 /* NOR Flash */
 #define V2M_FLASH0_BASE			(V2M_OFFSET + UL(0x08000000))
 #define V2M_FLASH0_SIZE			UL(0x04000000)
+#define V2M_FLASH1_BASE			(V2M_OFFSET + UL(0x0c000000))
+#define V2M_FLASH1_SIZE			UL(0x04000000)
 #define V2M_FLASH_BLOCK_SIZE		UL(0x00040000) /* 256 KB */
 
 #define V2M_IOFPGA_BASE			(V2M_OFFSET + UL(0x1c000000))
@@ -126,6 +129,14 @@
 						V2M_FLASH0_SIZE,	\
 						MT_RO_DATA | MT_SECURE)
 
+#define V2M_MAP_FLASH1_RW		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
+						V2M_FLASH1_SIZE,	\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH1_RO		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
+						V2M_FLASH1_SIZE,	\
+						MT_RO_DATA | MT_SECURE)
+
 #define V2M_MAP_IOFPGA			MAP_REGION_FLAT(V2M_IOFPGA_BASE,\
 						V2M_IOFPGA_SIZE,		\
 						MT_DEVICE | MT_RW | MT_SECURE)
@@ -136,5 +147,19 @@
 						V2M_IOFPGA_SIZE,	\
 						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#define V2M_MAP_SECURE_SYSTEMREG_EL0		MAP_REGION_FLAT(	\
+						V2M_SYSREGS_BASE,															\
+						V2M_SYSREGS_SIZE,															\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define V2M_MAP_FLASH0_RW_EL0		MAP_REGION_FLAT(	\
+						V2M_FLASH0_BASE,											\
+						V2M_FLASH0_SIZE,											\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define V2M_MAP_FLASH1_RW_EL0		MAP_REGION_FLAT(	\
+						V2M_FLASH1_BASE,											\
+						V2M_FLASH1_SIZE,											\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
 #endif /* V2M_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index d778201..83a5cd2 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -69,14 +69,16 @@
 
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #define ARM_TZC_REGIONS_DEF						\
-	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
-		TZC_REGION_S_RDWR, 0},					\
 	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
 		PLAT_ARM_TZC_NS_DEV_ACCESS}, 				\
-	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
-		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{ARM_AP_TZC_DRAM1_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE - 1),	\
+		TZC_REGION_S_RDWR, 0},					\
 	{PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE +	\
-		PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+		PLAT_SP_IMAGE_NS_BUF_SIZE - 1), TZC_REGION_S_NONE,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{PLAT_SP_IMAGE_STACK_BASE, ARM_EL3_TZC_DRAM1_END,		\
+		TZC_REGION_S_RDWR, 0},					\
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #elif ENABLE_RME
@@ -282,10 +284,7 @@
 /* Firmware Handoff utility functions */
 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,
-					struct transfer_list_header *ns_tl);
-void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
-				      struct transfer_list_header *ns_tl);
+					struct transfer_list_header *secure_tl);
 
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
@@ -363,6 +362,7 @@
 void plat_arm_interconnect_exit_coherency(void);
 void plat_arm_program_trusted_mailbox(uintptr_t address);
 bool plat_arm_bl1_fwu_needed(void);
+int plat_arm_ni_setup(uintptr_t global_cfg);
 __dead2 void plat_arm_error_handler(int err);
 __dead2 void plat_arm_system_reset(void);
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index ce5e8e0..1015fca 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -41,6 +41,16 @@
 enum fw_enc_status_t;
 
 /*******************************************************************************
+ * Structure populated by platform specific code to export routines which
+ * perform load images functions, and associated pointer to platform ops
+ ******************************************************************************/
+struct plat_try_images_ops {
+	int (*next_instance)(unsigned int image_id);
+};
+
+extern const struct plat_try_images_ops *plat_try_img_ops;
+
+/*******************************************************************************
  * plat_get_rotpk_info() flags
  ******************************************************************************/
 #define ROTPK_IS_HASH			(1 << 0)
@@ -154,7 +164,7 @@
 void plat_system_reset(void) __dead2;
 const char *plat_log_get_prefix(unsigned int log_level);
 void bl2_plat_preload_setup(void);
-int plat_try_next_boot_source(void);
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops);
 
 #if MEASURED_BOOT
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data);
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
index 9cbf839..c70ef22 100644
--- a/include/plat/nuvoton/npcm845x/platform_def.h
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -157,7 +157,8 @@
 
 /* MMU entry for internal (register) space access */
 #define MAP_DEVICE0                                                            \
-	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, MT_DEVICE | MT_RW | MT_NS)
+	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE,                         \
+			MT_DEVICE | MT_RW | MT_SECURE)
 
 #define MAP_DEVICE1                                                            \
 	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE,                            \
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index 8c53ef9..6f89c16 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.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
  */
@@ -30,15 +30,17 @@
 
 /*
  * First undef previous definitions from tbbr_oid.h.
- * CCA ROTPK authenticates BL31 and its configuration image in
+ * CCA ROTPK authenticates BL31, SCP_BL2 and its configuration image in
  * CCA CoT.
  **/
 #undef BL31_IMAGE_KEY_OID
 #undef SOC_FW_CONFIG_KEY_OID
 #undef HW_CONFIG_KEY_OID
+#undef SCP_BL2_IMAGE_KEY_OID
 #define BL31_IMAGE_KEY_OID			ZERO_OID
 #define SOC_FW_CONFIG_KEY_OID			ZERO_OID
 #define HW_CONFIG_KEY_OID			ZERO_OID
+#define SCP_BL2_IMAGE_KEY_OID			ZERO_OID
 #define RMM_IMAGE_KEY_OID			ZERO_OID
 
 #endif /* CCA_OID_H */
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index f9c4baf..93771df 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -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
  */
@@ -15,7 +15,6 @@
 	.globl	zero_normalmem
 	.globl	zeromem
 	.globl	memcpy16
-	.globl	gpt_tlbi_by_pa_ll
 
 	.globl	disable_mmu_el1
 	.globl	disable_mmu_el3
@@ -594,20 +593,3 @@
 	b.lo	1b
 	ret
 endfunc fixup_gdt_reloc
-
-/*
- * TODO: Currently only supports size of 4KB,
- * support other sizes as well.
- */
-func gpt_tlbi_by_pa_ll
-#if ENABLE_ASSERTIONS
-	cmp	x1, #PAGE_SIZE_4KB
-	ASM_ASSERT(eq)
-	tst	x0, #(PAGE_SIZE_MASK)
-	ASM_ASSERT(eq)
-#endif
-	lsr	x0, x0, #FOUR_KB_SHIFT	/* 4KB size encoding is zero */
-	sys	#6, c8, c4, #7, x0 	/* TLBI RPALOS, <Xt> */
-	dsb	sy
-	ret
-endfunc gpt_tlbi_by_pa_ll
diff --git a/lib/cpus/aarch64/cortex_a725.S b/lib/cpus/aarch64/cortex_a725.S
new file mode 100644
index 0000000..c08945f
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-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_a725.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A725 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A725 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_a725
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_a725
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a725_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_A725_CPUPWRCTLR_EL1, CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_a725_core_pwr_dwn
+
+errata_report_shim cortex_a725
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A725 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_a725_regs, "aS"
+cortex_a725_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a725_cpu_reg_dump
+	adr	x6, cortex_a725_regs
+	mrs	x8, CORTEX_A725_CPUECTLR_EL1
+	ret
+endfunc cortex_a725_cpu_reg_dump
+
+declare_cpu_ops cortex_a725, CORTEX_A725_MIDR, \
+	cortex_a725_reset_func, \
+	cortex_a725_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_blackhawk.S
deleted file mode 100644
index b7b7a2d..0000000
--- a/lib/cpus/aarch64/cortex_blackhawk.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2023, 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_blackhawk.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex blackhawk must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_blackhawk
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end cortex_blackhawk
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_blackhawk_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc cortex_blackhawk_core_pwr_dwn
-
-errata_report_shim cortex_blackhawk
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Blackhawk 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_blackhawk_regs, "aS"
-cortex_blackhawk_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_blackhawk_cpu_reg_dump
-	adr	x6, cortex_blackhawk_regs
-	mrs	x8, CORTEX_BLACKHAWK_CPUECTLR_EL1
-	ret
-endfunc cortex_blackhawk_cpu_reg_dump
-
-declare_cpu_ops cortex_blackhawk, CORTEX_BLACKHAWK_MIDR, \
-	cortex_blackhawk_reset_func, \
-	cortex_blackhawk_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_chaberton.S
deleted file mode 100644
index 596fe4a..0000000
--- a/lib/cpus/aarch64/cortex_chaberton.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2023, 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_chaberton.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Chaberton must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_chaberton
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end cortex_chaberton
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_chaberton_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_CHABERTON_CPUPWRCTLR_EL1, CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc cortex_chaberton_core_pwr_dwn
-
-errata_report_shim cortex_chaberton
-
-	/* ---------------------------------------------
-	 * This function provides Cortex Chaberton 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_chaberton_regs, "aS"
-cortex_chaberton_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_chaberton_cpu_reg_dump
-	adr	x6, cortex_chaberton_regs
-	mrs	x8, CORTEX_CHABERTON_CPUECTLR_EL1
-	ret
-endfunc cortex_chaberton_cpu_reg_dump
-
-declare_cpu_ops cortex_chaberton, CORTEX_CHABERTON_MIDR, \
-	cortex_chaberton_reset_func, \
-	cortex_chaberton_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
new file mode 100644
index 0000000..36b442e
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-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_x925.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-X925 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_x925
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_x925
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x925_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_X925_CPUPWRCTLR_EL1, CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_x925_core_pwr_dwn
+
+errata_report_shim cortex_x925
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-X925 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_x925_regs, "aS"
+cortex_x925_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_x925_cpu_reg_dump
+	adr	x6, cortex_x925_regs
+	mrs	x8, CORTEX_X925_CPUECTLR_EL1
+	ret
+endfunc cortex_x925_cpu_reg_dump
+
+declare_cpu_ops cortex_x925, CORTEX_X925_MIDR, \
+	cortex_x925_reset_func, \
+	cortex_x925_core_pwr_dwn
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 8e5b459..3c5bf2e 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -24,6 +24,7 @@
 	 */
 	.globl	check_errata_dsu_798953
 	.globl	errata_dsu_798953_wa
+	.globl	dsu_pwr_dwn
 
 func check_errata_dsu_798953
 	mov	x2, #ERRATA_APPLIES
@@ -202,3 +203,15 @@
 1:
 	ret	x8
 endfunc errata_dsu_2313941_wa
+
+	/* ---------------------------------------------
+	 * controls power features of the cluster
+	 * 1. Cache portion power not request
+	 * 2. Disable the retention circuit
+	 * ---------------------------------------------
+	 */
+func dsu_pwr_dwn
+	msr	CLUSTERPWRCTLR_EL1, xzr
+	isb
+	ret
+endfunc dsu_pwr_dwn
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index 4e9bdfc..27cfc91 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -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
  */
@@ -51,9 +51,9 @@
 		}
 	} else {
 		if (cve) {
-			VERBOSE(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "not applied");
+			VERBOSE(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "not applicable");
 		}  else {
-			VERBOSE(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "not applied");
+			VERBOSE(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "not applicable");
 		}
 	}
 }
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 76aebf9..62895ff 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -14,9 +14,13 @@
 	.global	fpregs_context_save
 	.global	fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
+
+#if ERRATA_SPECULATIVE_AT
+	.global save_and_update_ptw_el1_sys_regs
+#endif /* ERRATA_SPECULATIVE_AT */
+
 	.global	prepare_el3_entry
 	.global	restore_gp_pmcr_pauth_regs
-	.global save_and_update_ptw_el1_sys_regs
 	.global	el3_exit
 
 /* ------------------------------------------------------------------
@@ -329,10 +333,12 @@
 	ret
 endfunc restore_gp_pmcr_pauth_regs
 
-/*
+#if ERRATA_SPECULATIVE_AT
+/* --------------------------------------------------------------------
  * In case of ERRATA_SPECULATIVE_AT, save SCTLR_EL1 and TCR_EL1
  * registers and update EL1 registers to disable stage1 and stage2
- * page table walk
+ * page table walk.
+ * --------------------------------------------------------------------
  */
 func save_and_update_ptw_el1_sys_regs
 	/* ----------------------------------------------------------
@@ -340,9 +346,9 @@
 	 * ----------------------------------------------------------
 	 */
 	mrs	x29, sctlr_el1
-	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1)]
+	str	x29, [sp, #(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1)]
 	mrs	x29, tcr_el1
-	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_TCR_EL1)]
+	str	x29, [sp, #(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_TCR_EL1)]
 
 	/* ------------------------------------------------------------
 	 * Must follow below order in order to disable page table
@@ -367,10 +373,11 @@
 	orr	x29, x29, #SCTLR_M_BIT
 	msr	sctlr_el1, x29
 	isb
-
 	ret
 endfunc save_and_update_ptw_el1_sys_regs
 
+#endif /* ERRATA_SPECULATIVE_AT */
+
 /* -----------------------------------------------------------------
 * The below macro returns the address of the per_world context for
 * the security state, retrieved through "get_security_state" macro.
@@ -454,15 +461,17 @@
 	synchronize_errors
 #endif /* IMAGE_BL31 */
 
-	/* ----------------------------------------------------------
-	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
-	 * ----------------------------------------------------------
+	/* --------------------------------------------------------------
+	 * Restore MDCR_EL3, SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * --------------------------------------------------------------
 	 */
-	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	msr	scr_el3, x18
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldr	x19, [sp, #CTX_EL3STATE_OFFSET + CTX_MDCR_EL3]
 	msr	spsr_el3, x16
 	msr	elr_el3, x17
+	msr	scr_el3, x18
+	msr	mdcr_el3, x19
 
 	restore_ptw_el1_sys_regs
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 35c98f5..15db9e5 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -24,6 +24,8 @@
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
 #include <lib/extensions/brbe.h>
+#include <lib/extensions/debug_v8p9.h>
+#include <lib/extensions/fgt2.h>
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sme.h>
@@ -42,6 +44,7 @@
 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);
@@ -89,8 +92,13 @@
 	 */
 	sctlr_elx |= SCTLR_IESB_BIT;
 #endif
+
 	/* Store the initialised SCTLR_EL1 value in the cpu_context */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx), CTX_ERRATA_SPEC_AT_SCTLR_EL1, sctlr_elx);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, sctlr_elx);
+#endif /* ERRATA_SPECULATIVE_AT */
 
 	/*
 	 * Base the context ACTLR_EL1 on the current value, as it is
@@ -100,7 +108,7 @@
 	 * be zero.
 	 */
 	actlr_elx = read_actlr_el1();
-	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), actlr_el1, actlr_elx);
 }
 
 /******************************************************************************
@@ -261,13 +269,9 @@
 #if CTX_INCLUDE_EL2_REGS
 
 	/*
-	 * Initialize SCTLR_EL2 context register using Endianness value
-	 * taken from the entrypoint attribute.
+	 * Initialize SCTLR_EL2 context register with reset value.
 	 */
-	u_register_t sctlr_el2_val = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
-	sctlr_el2_val |= SCTLR_EL2_RES1;
-	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), sctlr_el2, sctlr_el2_val);
-
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), sctlr_el2, SCTLR_EL2_RES1);
 
 	if (is_feat_hcx_supported()) {
 		/*
@@ -312,6 +316,7 @@
 static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
 	u_register_t scr_el3;
+	u_register_t mdcr_el3;
 	el3_state_t *state;
 	gp_regs_t *gp_regs;
 
@@ -336,6 +341,12 @@
 	u_register_t icc_sre_el2_val = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
 				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
 	write_el2_ctx_common(el2_ctx, icc_sre_el2, icc_sre_el2_val);
+
+	/*
+	 * The actlr_el2 register can be initialized in platform's reset handler
+	 * and it may contain access control bits (e.g. CLUSTERPMUEN bit).
+	 */
+	write_el2_ctx_common(el2_ctx, actlr_el2, read_actlr_el2());
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	/* Start with a clean SCR_EL3 copy as all relevant values are set */
@@ -484,6 +495,37 @@
 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
 
+	/* Start with a clean MDCR_EL3 copy as all relevant values are set */
+	mdcr_el3 = MDCR_EL3_RESET_VAL;
+
+	/* ---------------------------------------------------------------------
+	 * 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.
+	 *
+	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
+	 *  privileged debug from S-EL1.
+	 *
+	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
+	 *  access to the powerdown debug registers do not trap to EL3.
+	 *
+	 * MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
+	 *  debug registers, other than those registers that are controlled by
+	 *  MDCR_EL3.TDOSA.
+	 */
+	mdcr_el3 |= ((MDCR_SDD_BIT | MDCR_SPD32(MDCR_SPD32_DISABLE))
+			& ~(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);
+
 	/*
 	 * Store the X0-X7 value from the entrypoint into the context
 	 * Use memcpy as we are in control of the layout of the structures
@@ -560,10 +602,6 @@
 #if IMAGE_BL31
 void cm_manage_extensions_el3(void)
 {
-	if (is_feat_spe_supported()) {
-		spe_init_el3();
-	}
-
 	if (is_feat_amu_supported()) {
 		amu_init_el3();
 	}
@@ -572,18 +610,6 @@
 		sme_init_el3();
 	}
 
-	if (is_feat_trbe_supported()) {
-		trbe_init_el3();
-	}
-
-	if (is_feat_brbe_supported()) {
-		brbe_init_el3();
-	}
-
-	if (is_feat_trf_supported()) {
-		trf_init_el3();
-	}
-
 	pmuv3_init_el3();
 }
 #endif /* IMAGE_BL31 */
@@ -704,6 +730,48 @@
 }
 
 /*******************************************************************************
+ * 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)
@@ -717,6 +785,14 @@
 		sme_enable(ctx);
 	}
 
+	if (is_feat_fgt2_supported()) {
+		fgt2_enable(ctx);
+	}
+
+	if (is_feat_debugv8p9_supported()) {
+		debugv8p9_extended_bp_wp_enable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 #endif /* IMAGE_BL31 */
 }
@@ -952,7 +1028,7 @@
  ******************************************************************************/
 void cm_prepare_el3_exit(uint32_t security_state)
 {
-	u_register_t sctlr_elx, scr_el3;
+	u_register_t sctlr_el2, scr_el3;
 	cpu_context_t *ctx = cm_get_context(security_state);
 
 	assert(ctx != NULL);
@@ -993,20 +1069,17 @@
 
 			/* Condition to ensure EL2 is being used. */
 			if ((scr_el3 & SCR_HCE_BIT) != 0U) {
-				/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
-				sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-								CTX_SCTLR_EL1);
-				sctlr_elx &= SCTLR_EE_BIT;
-				sctlr_elx |= SCTLR_EL2_RES1;
+				/* Initialize SCTLR_EL2 register with reset value. */
+				sctlr_el2 = SCTLR_EL2_RES1;
 #if ERRATA_A75_764081
 				/*
 				 * If workaround of errata 764081 for Cortex-A75
 				 * is used then set SCTLR_EL2.IESB to enable
 				 * Implicit Error Synchronization Barrier.
 				 */
-				sctlr_elx |= SCTLR_IESB_BIT;
-#endif /* ERRATA_A75_764081 */
-				write_sctlr_el2(sctlr_elx);
+				sctlr_el2 |= SCTLR_IESB_BIT;
+#endif
+				write_sctlr_el2(sctlr_el2);
 			} else {
 				/*
 				 * (scr_el3 & SCR_HCE_BIT==0)
@@ -1046,13 +1119,29 @@
 	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
 }
 
-#if CTX_INCLUDE_MPAM_REGS
+static void el2_sysregs_context_save_fgt2(el2_sysregs_t *ctx)
+{
+	write_el2_ctx_fgt2(ctx, hdfgrtr2_el2, read_hdfgrtr2_el2());
+	write_el2_ctx_fgt2(ctx, hdfgwtr2_el2, read_hdfgwtr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgitr2_el2, read_hfgitr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgrtr2_el2, read_hfgrtr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgwtr2_el2, read_hfgwtr2_el2());
+}
 
-static void el2_sysregs_context_save_mpam(mpam_t *ctx)
+static void el2_sysregs_context_restore_fgt2(el2_sysregs_t *ctx)
+{
+	write_hdfgrtr2_el2(read_el2_ctx_fgt2(ctx, hdfgrtr2_el2));
+	write_hdfgwtr2_el2(read_el2_ctx_fgt2(ctx, hdfgwtr2_el2));
+	write_hfgitr2_el2(read_el2_ctx_fgt2(ctx, hfgitr2_el2));
+	write_hfgrtr2_el2(read_el2_ctx_fgt2(ctx, hfgrtr2_el2));
+	write_hfgwtr2_el2(read_el2_ctx_fgt2(ctx, hfgwtr2_el2));
+}
+
+static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+	write_el2_ctx_mpam(ctx, mpam2_el2, read_mpam2_el2());
 
 	/*
 	 * The context registers that we intend to save would be part of the
@@ -1066,9 +1155,9 @@
 	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
 	 * MPAMIDR_HAS_HCR_BIT == 1.
 	 */
-	write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+	write_el2_ctx_mpam(ctx, mpamhcr_el2, read_mpamhcr_el2());
+	write_el2_ctx_mpam(ctx, mpamvpm0_el2, read_mpamvpm0_el2());
+	write_el2_ctx_mpam(ctx, mpamvpmv_el2, read_mpamvpmv_el2());
 
 	/*
 	 * The number of MPAMVPM registers is implementation defined, their
@@ -1076,71 +1165,67 @@
 	 */
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm7_el2, read_mpamvpm7_el2());
 		__fallthrough;
 	case 6:
-		write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm6_el2, read_mpamvpm6_el2());
 		__fallthrough;
 	case 5:
-		write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm5_el2, read_mpamvpm5_el2());
 		__fallthrough;
 	case 4:
-		write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm4_el2, read_mpamvpm4_el2());
 		__fallthrough;
 	case 3:
-		write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm3_el2, read_mpamvpm3_el2());
 		__fallthrough;
 	case 2:
-		write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm2_el2, read_mpamvpm2_el2());
 		__fallthrough;
 	case 1:
-		write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm1_el2, read_mpamvpm1_el2());
 		break;
 	}
 }
 
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-#if CTX_INCLUDE_MPAM_REGS
-static void el2_sysregs_context_restore_mpam(mpam_t *ctx)
+static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+	write_mpam2_el2(read_el2_ctx_mpam(ctx, mpam2_el2));
 
 	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
 		return;
 	}
 
-	write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
-	write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
-	write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+	write_mpamhcr_el2(read_el2_ctx_mpam(ctx, mpamhcr_el2));
+	write_mpamvpm0_el2(read_el2_ctx_mpam(ctx, mpamvpm0_el2));
+	write_mpamvpmv_el2(read_el2_ctx_mpam(ctx, mpamvpmv_el2));
 
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+		write_mpamvpm7_el2(read_el2_ctx_mpam(ctx, mpamvpm7_el2));
 		__fallthrough;
 	case 6:
-		write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+		write_mpamvpm6_el2(read_el2_ctx_mpam(ctx, mpamvpm6_el2));
 		__fallthrough;
 	case 5:
-		write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+		write_mpamvpm5_el2(read_el2_ctx_mpam(ctx, mpamvpm5_el2));
 		__fallthrough;
 	case 4:
-		write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+		write_mpamvpm4_el2(read_el2_ctx_mpam(ctx, mpamvpm4_el2));
 		__fallthrough;
 	case 3:
-		write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+		write_mpamvpm3_el2(read_el2_ctx_mpam(ctx, mpamvpm3_el2));
 		__fallthrough;
 	case 2:
-		write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+		write_mpamvpm2_el2(read_el2_ctx_mpam(ctx, mpamvpm2_el2));
 		__fallthrough;
 	case 1:
-		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+		write_mpamvpm1_el2(read_el2_ctx_mpam(ctx, mpamvpm1_el2));
 		break;
 	}
 }
-#endif /* CTX_INCLUDE_MPAM_REGS */
 
 /* ---------------------------------------------------------------------------
  * The following registers are not added:
@@ -1283,17 +1368,18 @@
 		write_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_save_mpam(mpam_ctx);
+		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
 	}
 
+	if (is_feat_fgt2_supported()) {
+		el2_sysregs_context_save_fgt2(el2_sysregs_ctx);
+	}
+
 	if (is_feat_ecv_v2_supported()) {
 		write_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2, read_cntpoff_el2());
 	}
@@ -1369,17 +1455,18 @@
 		write_tfsr_el2(read_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2));
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_restore_mpam(mpam_ctx);
+		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
 	}
 
+	if (is_feat_fgt2_supported()) {
+		el2_sysregs_context_restore_fgt2(el2_sysregs_ctx);
+	}
+
 	if (is_feat_ecv_v2_supported()) {
 		write_cntpoff_el2(read_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2));
 	}
@@ -1466,220 +1553,192 @@
 
 static void el1_sysregs_context_save(el1_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_SPSR_EL1, read_spsr_el1());
-	write_ctx_reg(ctx, CTX_ELR_EL1, read_elr_el1());
+	write_el1_ctx_common(ctx, spsr_el1, read_spsr_el1());
+	write_el1_ctx_common(ctx, elr_el1, read_elr_el1());
 
-#if !ERRATA_SPECULATIVE_AT
-	write_ctx_reg(ctx, CTX_SCTLR_EL1, read_sctlr_el1());
-	write_ctx_reg(ctx, CTX_TCR_EL1, read_tcr_el1());
+#if (!ERRATA_SPECULATIVE_AT)
+	write_el1_ctx_common(ctx, sctlr_el1, read_sctlr_el1());
+	write_el1_ctx_common(ctx, tcr_el1, read_tcr_el1());
 #endif /* (!ERRATA_SPECULATIVE_AT) */
 
-	write_ctx_reg(ctx, CTX_CPACR_EL1, read_cpacr_el1());
-	write_ctx_reg(ctx, CTX_CSSELR_EL1, read_csselr_el1());
-	write_ctx_reg(ctx, CTX_SP_EL1, read_sp_el1());
-	write_ctx_reg(ctx, CTX_ESR_EL1, read_esr_el1());
-	write_ctx_reg(ctx, CTX_TTBR0_EL1, read_ttbr0_el1());
-	write_ctx_reg(ctx, CTX_TTBR1_EL1, read_ttbr1_el1());
-	write_ctx_reg(ctx, CTX_MAIR_EL1, read_mair_el1());
-	write_ctx_reg(ctx, CTX_AMAIR_EL1, read_amair_el1());
-	write_ctx_reg(ctx, CTX_ACTLR_EL1, read_actlr_el1());
-	write_ctx_reg(ctx, CTX_TPIDR_EL1, read_tpidr_el1());
-	write_ctx_reg(ctx, CTX_TPIDR_EL0, read_tpidr_el0());
-	write_ctx_reg(ctx, CTX_TPIDRRO_EL0, read_tpidrro_el0());
-	write_ctx_reg(ctx, CTX_PAR_EL1, read_par_el1());
-	write_ctx_reg(ctx, CTX_FAR_EL1, read_far_el1());
-	write_ctx_reg(ctx, CTX_AFSR0_EL1, read_afsr0_el1());
-	write_ctx_reg(ctx, CTX_AFSR1_EL1, read_afsr1_el1());
-	write_ctx_reg(ctx, CTX_CONTEXTIDR_EL1, read_contextidr_el1());
-	write_ctx_reg(ctx, CTX_VBAR_EL1, read_vbar_el1());
-	write_ctx_reg(ctx, CTX_MDCCINT_EL1, read_mdccint_el1());
-	write_ctx_reg(ctx, CTX_MDSCR_EL1, read_mdscr_el1());
+	write_el1_ctx_common(ctx, cpacr_el1, read_cpacr_el1());
+	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());
+	write_el1_ctx_common(ctx, contextidr_el1, read_contextidr_el1());
+	write_el1_ctx_common(ctx, vbar_el1, read_vbar_el1());
+	write_el1_ctx_common(ctx, mdccint_el1, read_mdccint_el1());
+	write_el1_ctx_common(ctx, mdscr_el1, read_mdscr_el1());
 
-#if CTX_INCLUDE_AARCH32_REGS
-	write_ctx_reg(ctx, CTX_SPSR_ABT, read_spsr_abt());
-	write_ctx_reg(ctx, CTX_SPSR_UND, read_spsr_und());
-	write_ctx_reg(ctx, CTX_SPSR_IRQ, read_spsr_irq());
-	write_ctx_reg(ctx, CTX_SPSR_FIQ, read_spsr_fiq());
-	write_ctx_reg(ctx, CTX_DACR32_EL2, read_dacr32_el2());
-	write_ctx_reg(ctx, CTX_IFSR32_EL2, read_ifsr32_el2());
-#endif /* CTX_INCLUDE_AARCH32_REGS */
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		/* Save Aarch32 registers */
+		write_el1_ctx_aarch32(ctx, spsr_abt, read_spsr_abt());
+		write_el1_ctx_aarch32(ctx, spsr_und, read_spsr_und());
+		write_el1_ctx_aarch32(ctx, spsr_irq, read_spsr_irq());
+		write_el1_ctx_aarch32(ctx, spsr_fiq, read_spsr_fiq());
+		write_el1_ctx_aarch32(ctx, dacr32_el2, read_dacr32_el2());
+		write_el1_ctx_aarch32(ctx, ifsr32_el2, read_ifsr32_el2());
+	}
 
-#if NS_TIMER_SWITCH
-	write_ctx_reg(ctx, CTX_CNTP_CTL_EL0, read_cntp_ctl_el0());
-	write_ctx_reg(ctx, CTX_CNTP_CVAL_EL0, read_cntp_cval_el0());
-	write_ctx_reg(ctx, CTX_CNTV_CTL_EL0, read_cntv_ctl_el0());
-	write_ctx_reg(ctx, CTX_CNTV_CVAL_EL0, read_cntv_cval_el0());
-	write_ctx_reg(ctx, CTX_CNTKCTL_EL1, read_cntkctl_el1());
-#endif /* NS_TIMER_SWITCH */
+	if (NS_TIMER_SWITCH) {
+		/* Save NS Timer registers */
+		write_el1_ctx_arch_timer(ctx, cntp_ctl_el0, read_cntp_ctl_el0());
+		write_el1_ctx_arch_timer(ctx, cntp_cval_el0, read_cntp_cval_el0());
+		write_el1_ctx_arch_timer(ctx, cntv_ctl_el0, read_cntv_ctl_el0());
+		write_el1_ctx_arch_timer(ctx, cntv_cval_el0, read_cntv_cval_el0());
+		write_el1_ctx_arch_timer(ctx, cntkctl_el1, read_cntkctl_el1());
+	}
 
-#if ENABLE_FEAT_MTE2
-	write_ctx_reg(ctx, CTX_TFSRE0_EL1, read_tfsre0_el1());
-	write_ctx_reg(ctx, CTX_TFSR_EL1, read_tfsr_el1());
-	write_ctx_reg(ctx, CTX_RGSR_EL1, read_rgsr_el1());
-	write_ctx_reg(ctx, CTX_GCR_EL1, read_gcr_el1());
-#endif /* ENABLE_FEAT_MTE2 */
+	if (is_feat_mte2_supported()) {
+		write_el1_ctx_mte2(ctx, tfsre0_el1, read_tfsre0_el1());
+		write_el1_ctx_mte2(ctx, tfsr_el1, read_tfsr_el1());
+		write_el1_ctx_mte2(ctx, rgsr_el1, read_rgsr_el1());
+		write_el1_ctx_mte2(ctx, gcr_el1, read_gcr_el1());
+	}
 
-#if ENABLE_FEAT_RAS
 	if (is_feat_ras_supported()) {
-		write_ctx_reg(ctx, CTX_DISR_EL1, read_disr_el1());
+		write_el1_ctx_ras(ctx, disr_el1, read_disr_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_S1PIE
 	if (is_feat_s1pie_supported()) {
-		write_ctx_reg(ctx, CTX_PIRE0_EL1, read_pire0_el1());
-		write_ctx_reg(ctx, CTX_PIR_EL1, read_pir_el1());
+		write_el1_ctx_s1pie(ctx, pire0_el1, read_pire0_el1());
+		write_el1_ctx_s1pie(ctx, pir_el1, read_pir_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_S1POE
 	if (is_feat_s1poe_supported()) {
-		write_ctx_reg(ctx, CTX_POR_EL1, read_por_el1());
+		write_el1_ctx_s1poe(ctx, por_el1, read_por_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_S2POE
 	if (is_feat_s2poe_supported()) {
-		write_ctx_reg(ctx, CTX_S2POR_EL1, read_s2por_el1());
+		write_el1_ctx_s2poe(ctx, s2por_el1, read_s2por_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_TCR2
 	if (is_feat_tcr2_supported()) {
-		write_ctx_reg(ctx, CTX_TCR2_EL1, read_tcr2_el1());
+		write_el1_ctx_tcr2(ctx, tcr2_el1, read_tcr2_el1());
 	}
-#endif
 
-#if ENABLE_TRF_FOR_NS
 	if (is_feat_trf_supported()) {
-		write_ctx_reg(ctx, CTX_TRFCR_EL1, read_trfcr_el1());
+		write_el1_ctx_trf(ctx, trfcr_el1, read_trfcr_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_CSV2_2
 	if (is_feat_csv2_2_supported()) {
-		write_ctx_reg(ctx, CTX_SCXTNUM_EL0, read_scxtnum_el0());
-		write_ctx_reg(ctx, CTX_SCXTNUM_EL1, read_scxtnum_el1());
+		write_el1_ctx_csv2_2(ctx, scxtnum_el0, read_scxtnum_el0());
+		write_el1_ctx_csv2_2(ctx, scxtnum_el1, read_scxtnum_el1());
 	}
-#endif
 
-#if ENABLE_FEAT_GCS
 	if (is_feat_gcs_supported()) {
-		write_ctx_reg(ctx, CTX_GCSCR_EL1, read_gcscr_el1());
-		write_ctx_reg(ctx, CTX_GCSCRE0_EL1, read_gcscre0_el1());
-		write_ctx_reg(ctx, CTX_GCSPR_EL1, read_gcspr_el1());
-		write_ctx_reg(ctx, CTX_GCSPR_EL0, read_gcspr_el0());
+		write_el1_ctx_gcs(ctx, gcscr_el1, read_gcscr_el1());
+		write_el1_ctx_gcs(ctx, gcscre0_el1, read_gcscre0_el1());
+		write_el1_ctx_gcs(ctx, gcspr_el1, read_gcspr_el1());
+		write_el1_ctx_gcs(ctx, gcspr_el0, read_gcspr_el0());
 	}
-#endif
 }
 
 static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
 {
-	write_spsr_el1(read_ctx_reg(ctx, CTX_SPSR_EL1));
-	write_elr_el1(read_ctx_reg(ctx, CTX_ELR_EL1));
+	write_spsr_el1(read_el1_ctx_common(ctx, spsr_el1));
+	write_elr_el1(read_el1_ctx_common(ctx, elr_el1));
 
-#if !ERRATA_SPECULATIVE_AT
-	write_sctlr_el1(read_ctx_reg(ctx, CTX_SCTLR_EL1));
-	write_tcr_el1(read_ctx_reg(ctx, CTX_TCR_EL1));
+#if (!ERRATA_SPECULATIVE_AT)
+	write_sctlr_el1(read_el1_ctx_common(ctx, sctlr_el1));
+	write_tcr_el1(read_el1_ctx_common(ctx, tcr_el1));
 #endif /* (!ERRATA_SPECULATIVE_AT) */
 
-	write_cpacr_el1(read_ctx_reg(ctx, CTX_CPACR_EL1));
-	write_csselr_el1(read_ctx_reg(ctx, CTX_CSSELR_EL1));
-	write_sp_el1(read_ctx_reg(ctx, CTX_SP_EL1));
-	write_esr_el1(read_ctx_reg(ctx, CTX_ESR_EL1));
-	write_ttbr0_el1(read_ctx_reg(ctx, CTX_TTBR0_EL1));
-	write_ttbr1_el1(read_ctx_reg(ctx, CTX_TTBR1_EL1));
-	write_mair_el1(read_ctx_reg(ctx, CTX_MAIR_EL1));
-	write_amair_el1(read_ctx_reg(ctx, CTX_AMAIR_EL1));
-	write_actlr_el1(read_ctx_reg(ctx, CTX_ACTLR_EL1));
-	write_tpidr_el1(read_ctx_reg(ctx, CTX_TPIDR_EL1));
-	write_tpidr_el0(read_ctx_reg(ctx, CTX_TPIDR_EL0));
-	write_tpidrro_el0(read_ctx_reg(ctx, CTX_TPIDRRO_EL0));
-	write_par_el1(read_ctx_reg(ctx, CTX_PAR_EL1));
-	write_far_el1(read_ctx_reg(ctx, CTX_FAR_EL1));
-	write_afsr0_el1(read_ctx_reg(ctx, CTX_AFSR0_EL1));
-	write_afsr1_el1(read_ctx_reg(ctx, CTX_AFSR1_EL1));
-	write_contextidr_el1(read_ctx_reg(ctx, CTX_CONTEXTIDR_EL1));
-	write_vbar_el1(read_ctx_reg(ctx, CTX_VBAR_EL1));
-	write_mdccint_el1(read_ctx_reg(ctx, CTX_MDCCINT_EL1));
-	write_mdscr_el1(read_ctx_reg(ctx, CTX_MDSCR_EL1));
+	write_cpacr_el1(read_el1_ctx_common(ctx, cpacr_el1));
+	write_csselr_el1(read_el1_ctx_common(ctx, csselr_el1));
+	write_sp_el1(read_el1_ctx_common(ctx, sp_el1));
+	write_esr_el1(read_el1_ctx_common(ctx, esr_el1));
+	write_ttbr0_el1(read_el1_ctx_common(ctx, ttbr0_el1));
+	write_ttbr1_el1(read_el1_ctx_common(ctx, ttbr1_el1));
+	write_mair_el1(read_el1_ctx_common(ctx, mair_el1));
+	write_amair_el1(read_el1_ctx_common(ctx, amair_el1));
+	write_actlr_el1(read_el1_ctx_common(ctx, actlr_el1));
+	write_tpidr_el1(read_el1_ctx_common(ctx, tpidr_el1));
+	write_tpidr_el0(read_el1_ctx_common(ctx, tpidr_el0));
+	write_tpidrro_el0(read_el1_ctx_common(ctx, tpidrro_el0));
+	write_par_el1(read_el1_ctx_common(ctx, par_el1));
+	write_far_el1(read_el1_ctx_common(ctx, far_el1));
+	write_afsr0_el1(read_el1_ctx_common(ctx, afsr0_el1));
+	write_afsr1_el1(read_el1_ctx_common(ctx, afsr1_el1));
+	write_contextidr_el1(read_el1_ctx_common(ctx, contextidr_el1));
+	write_vbar_el1(read_el1_ctx_common(ctx, vbar_el1));
+	write_mdccint_el1(read_el1_ctx_common(ctx, mdccint_el1));
+	write_mdscr_el1(read_el1_ctx_common(ctx, mdscr_el1));
 
-#if CTX_INCLUDE_AARCH32_REGS
-	write_spsr_abt(read_ctx_reg(ctx, CTX_SPSR_ABT));
-	write_spsr_und(read_ctx_reg(ctx, CTX_SPSR_UND));
-	write_spsr_irq(read_ctx_reg(ctx, CTX_SPSR_IRQ));
-	write_spsr_fiq(read_ctx_reg(ctx, CTX_SPSR_FIQ));
-	write_dacr32_el2(read_ctx_reg(ctx, CTX_DACR32_EL2));
-	write_ifsr32_el2(read_ctx_reg(ctx, CTX_IFSR32_EL2));
-#endif /* CTX_INCLUDE_AARCH32_REGS */
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		/* Restore Aarch32 registers */
+		write_spsr_abt(read_el1_ctx_aarch32(ctx, spsr_abt));
+		write_spsr_und(read_el1_ctx_aarch32(ctx, spsr_und));
+		write_spsr_irq(read_el1_ctx_aarch32(ctx, spsr_irq));
+		write_spsr_fiq(read_el1_ctx_aarch32(ctx, spsr_fiq));
+		write_dacr32_el2(read_el1_ctx_aarch32(ctx, dacr32_el2));
+		write_ifsr32_el2(read_el1_ctx_aarch32(ctx, ifsr32_el2));
+	}
 
-#if NS_TIMER_SWITCH
-	write_cntp_ctl_el0(read_ctx_reg(ctx, CTX_CNTP_CTL_EL0));
-	write_cntp_cval_el0(read_ctx_reg(ctx, CTX_CNTP_CVAL_EL0));
-	write_cntv_ctl_el0(read_ctx_reg(ctx, CTX_CNTV_CTL_EL0));
-	write_cntv_cval_el0(read_ctx_reg(ctx, CTX_CNTV_CVAL_EL0));
-	write_cntkctl_el1(read_ctx_reg(ctx, CTX_CNTKCTL_EL1));
-#endif /* NS_TIMER_SWITCH */
+	if (NS_TIMER_SWITCH) {
+		/* Restore NS Timer registers */
+		write_cntp_ctl_el0(read_el1_ctx_arch_timer(ctx, cntp_ctl_el0));
+		write_cntp_cval_el0(read_el1_ctx_arch_timer(ctx, cntp_cval_el0));
+		write_cntv_ctl_el0(read_el1_ctx_arch_timer(ctx, cntv_ctl_el0));
+		write_cntv_cval_el0(read_el1_ctx_arch_timer(ctx, cntv_cval_el0));
+		write_cntkctl_el1(read_el1_ctx_arch_timer(ctx, cntkctl_el1));
+	}
 
-#if ENABLE_FEAT_MTE2
-	write_tfsre0_el1(read_ctx_reg(ctx, CTX_TFSRE0_EL1));
-	write_tfsr_el1(read_ctx_reg(ctx, CTX_TFSR_EL1));
-	write_rgsr_el1(read_ctx_reg(ctx, CTX_RGSR_EL1));
-	write_gcr_el1(read_ctx_reg(ctx, CTX_GCR_EL1));
-#endif /* ENABLE_FEAT_MTE2 */
+	if (is_feat_mte2_supported()) {
+		write_tfsre0_el1(read_el1_ctx_mte2(ctx, tfsre0_el1));
+		write_tfsr_el1(read_el1_ctx_mte2(ctx, tfsr_el1));
+		write_rgsr_el1(read_el1_ctx_mte2(ctx, rgsr_el1));
+		write_gcr_el1(read_el1_ctx_mte2(ctx, gcr_el1));
+	}
 
-#if ENABLE_FEAT_RAS
 	if (is_feat_ras_supported()) {
-		write_disr_el1(read_ctx_reg(ctx, CTX_DISR_EL1));
+		write_disr_el1(read_el1_ctx_ras(ctx, disr_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_S1PIE
 	if (is_feat_s1pie_supported()) {
-		write_pire0_el1(read_ctx_reg(ctx, CTX_PIRE0_EL1));
-		write_pir_el1(read_ctx_reg(ctx, CTX_PIR_EL1));
+		write_pire0_el1(read_el1_ctx_s1pie(ctx, pire0_el1));
+		write_pir_el1(read_el1_ctx_s1pie(ctx, pir_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_S1POE
 	if (is_feat_s1poe_supported()) {
-		write_por_el1(read_ctx_reg(ctx, CTX_POR_EL1));
+		write_por_el1(read_el1_ctx_s1poe(ctx, por_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_S2POE
 	if (is_feat_s2poe_supported()) {
-		write_s2por_el1(read_ctx_reg(ctx, CTX_S2POR_EL1));
+		write_s2por_el1(read_el1_ctx_s2poe(ctx, s2por_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_TCR2
 	if (is_feat_tcr2_supported()) {
-		write_tcr2_el1(read_ctx_reg(ctx, CTX_TCR2_EL1));
+		write_tcr2_el1(read_el1_ctx_tcr2(ctx, tcr2_el1));
 	}
-#endif
 
-#if ENABLE_TRF_FOR_NS
 	if (is_feat_trf_supported()) {
-		write_trfcr_el1(read_ctx_reg(ctx, CTX_TRFCR_EL1));
+		write_trfcr_el1(read_el1_ctx_trf(ctx, trfcr_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_CSV2_2
 	if (is_feat_csv2_2_supported()) {
-		write_scxtnum_el0(read_ctx_reg(ctx, CTX_SCXTNUM_EL0));
-		write_scxtnum_el1(read_ctx_reg(ctx, CTX_SCXTNUM_EL1));
+		write_scxtnum_el0(read_el1_ctx_csv2_2(ctx, scxtnum_el0));
+		write_scxtnum_el1(read_el1_ctx_csv2_2(ctx, scxtnum_el1));
 	}
-#endif
 
-#if ENABLE_FEAT_GCS
 	if (is_feat_gcs_supported()) {
-		write_gcscr_el1(read_ctx_reg(ctx, CTX_GCSCR_EL1));
-		write_gcscre0_el1(read_ctx_reg(ctx, CTX_GCSCRE0_EL1));
-		write_gcspr_el1(read_ctx_reg(ctx, CTX_GCSPR_EL1));
-		write_gcspr_el0(read_ctx_reg(ctx, CTX_GCSPR_EL0));
+		write_gcscr_el1(read_el1_ctx_gcs(ctx, gcscr_el1));
+		write_gcscre0_el1(read_el1_ctx_gcs(ctx, gcscre0_el1));
+		write_gcspr_el1(read_el1_ctx_gcs(ctx, gcspr_el1));
+		write_gcspr_el0(read_el1_ctx_gcs(ctx, gcspr_el0));
 	}
-#endif
 }
 
 /*******************************************************************************
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index 37bd834..dde0266 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -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
  */
@@ -9,9 +9,10 @@
 #include <arch_helpers.h>
 #include <lib/extensions/brbe.h>
 
-void brbe_init_el3(void)
+void brbe_enable(cpu_context_t *ctx)
 {
-	uint64_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.SBRBE = 0b01
@@ -19,8 +20,7 @@
 	 * Allows BRBE usage in non-secure world and prohibited in
 	 * secure world.
 	 */
-	val = read_mdcr_el3();
-	val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
-	val |= (0x1UL << MDCR_SBRBE_SHIFT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+	mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
diff --git a/lib/extensions/debug/debugv8p9.c b/lib/extensions/debug/debugv8p9.c
new file mode 100644
index 0000000..f3cffa7
--- /dev/null
+++ b/lib/extensions/debug/debugv8p9.c
@@ -0,0 +1,26 @@
+/*
+ * 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/debug_v8p9.h>
+
+void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
+
+	/* When FEAT_Debugv8p9 is implemented:
+	 *
+	 * MDCR_EL3.EBWE: Set to 0b1
+	 * Enables use of additional breakpoints or watchpoints,
+	 * and disables trap to EL3 on accesses to debug register.
+	 */
+
+	mdcr_el3_val |= MDCR_EBWE_BIT;
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
diff --git a/lib/extensions/fgt/fgt2.c b/lib/extensions/fgt/fgt2.c
new file mode 100644
index 0000000..78f1a82
--- /dev/null
+++ b/lib/extensions/fgt/fgt2.c
@@ -0,0 +1,27 @@
+/*
+ * 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/fgt2.h>
+
+void fgt2_enable(cpu_context_t *context)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(context);
+
+	/* Set the FGTEN2 bit in SCR_EL3 to enable access to HFGITR2_EL2,
+	 * HFGRTR2_EL2, HFGWTR_EL2, HDFGRTR2_EL2, and HDFGWTR2_EL2.
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg |= SCR_FGTEN2_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
+
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d1fb182..d653222 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -29,9 +29,10 @@
 	__asm__ volatile("hint #17");
 }
 
-void spe_init_el3(void)
+void spe_enable(cpu_context_t *ctx)
 {
-	uint64_t v;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state
@@ -46,10 +47,30 @@
 	 * Setting this bit to 1 doesn't have any effect on it when
 	 * FEAT_SPEv1p2 not implemented.
 	 */
-	v = read_mdcr_el3();
-	v |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
-	v &= ~(MDCR_NSPBE_BIT);
-	write_mdcr_el3(v);
+	mdcr_el3_val |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
+	mdcr_el3_val &= ~(MDCR_NSPBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
+
+void spe_disable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	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.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);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void spe_init_el2_unused(void)
@@ -70,7 +91,7 @@
 	write_mdcr_el2(v);
 }
 
-void spe_disable(void)
+void spe_stop(void)
 {
 	uint64_t v;
 
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index d4fbdfb..8c1c421 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,10 @@
 	__asm__ volatile("hint #18");
 }
 
-void trbe_init_el3(void)
+void trbe_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSTBE = 0b0
@@ -33,10 +34,28 @@
 	 *  NS-EL2, tracing is prohibited in Secure and Realm state (if
 	 *  implemented).
 	 */
-	val = read_mdcr_el3();
-	val |= MDCR_NSTB(MDCR_NSTB_EL1);
-	val &= ~(MDCR_NSTBE_BIT);
-	write_mdcr_el3(val);
+	mdcr_el3_val |= MDCR_NSTB(MDCR_NSTB_EL1);
+	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
+
+void trbe_disable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	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_val &= ~(MDCR_NSTB(MDCR_NSTB_EL1));
+	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trbe_init_el2_unused(void)
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index 83fbf85..d36853a 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,10 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-void trf_init_el3(void)
+void trf_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.STE = b0
@@ -22,9 +23,8 @@
 	 * Allow access of trace filter control registers from NS-EL2
 	 * and NS-EL1 when NS-EL2 is implemented but not used
 	 */
-	val = read_mdcr_el3();
-	val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trf_init_el2_unused(void)
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 72e905e..d028fce 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -57,6 +57,13 @@
  */
 static const gpt_p_val_e gpt_p_lookup[] = {PGS_4KB_P, PGS_64KB_P, PGS_16KB_P};
 
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+
 /*
  * This structure contains GPT configuration data
  */
@@ -70,10 +77,187 @@
 
 static gpt_config_t gpt_config;
 
+/*
+ * Number of L1 entries in 2MB, depending on GPCCR_EL3.PGS:
+ * +-------+------------+
+ * |  PGS  | L1 entries |
+ * +-------+------------+
+ * |  4KB  |     32     |
+ * +-------+------------+
+ * |  16KB |     8      |
+ * +-------+------------+
+ * |  64KB |     2      |
+ * +-------+------------+
+ */
+static unsigned int gpt_l1_cnt_2mb;
+
+/*
+ * Mask for the L1 index field, depending on
+ * GPCCR_EL3.L0GPTSZ and GPCCR_EL3.PGS:
+ * +---------+-------------------------------+
+ * |         |             PGS               |
+ * +---------+----------+----------+---------+
+ * | L0GPTSZ |   4KB    |   16KB   |   64KB  |
+ * +---------+----------+----------+---------+
+ * |  1GB    |  0x3FFF  |  0xFFF   |  0x3FF  |
+ * +---------+----------+----------+---------+
+ * |  16GB   | 0x3FFFF  |  0xFFFF  | 0x3FFF  |
+ * +---------+----------+----------+---------+
+ * |  64GB   | 0xFFFFF  | 0x3FFFF  | 0xFFFF  |
+ * +---------+----------+----------+---------+
+ * |  512GB  | 0x7FFFFF | 0x1FFFFF | 0x7FFFF |
+ * +---------+----------+----------+---------+
+ */
+static uint64_t gpt_l1_index_mask;
+
+/* Number of 128-bit L1 entries in 2MB, 32MB and 512MB */
+#define L1_QWORDS_2MB	(gpt_l1_cnt_2mb / 2U)
+#define L1_QWORDS_32MB	(L1_QWORDS_2MB * 16U)
+#define L1_QWORDS_512MB	(L1_QWORDS_32MB * 16U)
+
+/* Size in bytes of L1 entries in 2MB, 32MB */
+#define L1_BYTES_2MB	(gpt_l1_cnt_2mb * sizeof(uint64_t))
+#define L1_BYTES_32MB	(L1_BYTES_2MB * 16U)
+
+/* Get the index into the L1 table from a physical address */
+#define GPT_L1_INDEX(_pa)	\
+	(((_pa) >> (unsigned int)GPT_L1_IDX_SHIFT(gpt_config.p)) & gpt_l1_index_mask)
+
 /* These variables are used during initialization of the L1 tables */
-static unsigned int gpt_next_l1_tbl_idx;
 static uintptr_t gpt_l1_tbl;
 
+/* These variable is used during runtime */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * The GPTs are protected by a global spinlock to ensure
+ * that multiple CPUs do not attempt to change the descriptors at once.
+ */
+static spinlock_t gpt_lock;
+#else
+
+/* Bitlocks base address */
+static bitlock_t *gpt_bitlock_base;
+#endif
+
+/* Lock/unlock macros for GPT entries */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * Access to GPT is controlled by a global lock to ensure
+ * that no more than one CPU is allowed to make changes at any
+ * given time.
+ */
+#define GPT_LOCK	spin_lock(&gpt_lock)
+#define GPT_UNLOCK	spin_unlock(&gpt_lock)
+#else
+/*
+ * Access to a block of memory is controlled by a bitlock.
+ * Size of block = RME_GPT_BITLOCK_BLOCK * 512MB.
+ */
+#define GPT_LOCK	bit_lock(gpi_info.lock, gpi_info.mask)
+#define GPT_UNLOCK	bit_unlock(gpi_info.lock, gpi_info.mask)
+#endif
+
+static void tlbi_page_dsbosh(uintptr_t base)
+{
+	/* Look-up table for invalidation TLBs for 4KB, 16KB and 64KB pages */
+	static const gpt_tlbi_lookup_t tlbi_page_lookup[] = {
+		{ tlbirpalos_4k, ~(SZ_4K - 1UL) },
+		{ tlbirpalos_64k, ~(SZ_64K - 1UL) },
+		{ tlbirpalos_16k, ~(SZ_16K - 1UL) }
+	};
+
+	tlbi_page_lookup[gpt_config.pgs].function(
+			base & tlbi_page_lookup[gpt_config.pgs].mask);
+	dsbosh();
+}
+
+/*
+ * Helper function to fill out GPI entries in a single L1 table
+ * with Granules or Contiguous descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to 2MB, 32MB or 512MB aligned L1 table entry to fill out
+ *   l1_desc		GPT Granules or Contiguous descriptor set this range to
+ *   cnt		Number of double 128-bit L1 entries to fill
+ *
+ */
+static void fill_desc(uint64_t *l1, uint64_t l1_desc, unsigned int cnt)
+{
+	uint128_t *l1_quad = (uint128_t *)l1;
+	uint128_t l1_quad_desc = (uint128_t)l1_desc | ((uint128_t)l1_desc << 64);
+
+	VERBOSE("GPT: %s(%p 0x%"PRIx64" %u)\n", __func__, l1, l1_desc, cnt);
+
+	for (unsigned int i = 0U; i < cnt; i++) {
+		*l1_quad++ = l1_quad_desc;
+	}
+}
+
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Convert 2MB Contiguous block to Granules */
+	fill_desc(&gpi_info->gpt_l1_addr[idx], l1_desc, L1_QWORDS_2MB);
+}
+
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+	const uint64_t *l1_gran = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 32MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 2MB blocks in 32MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		/* Fill with Granules or Contiguous descriptors */
+		fill_desc(l1, (l1 == l1_gran) ? l1_desc : l1_cont_desc,
+							L1_QWORDS_2MB);
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_2MB);
+	}
+}
+
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	const uint64_t *l1_32mb = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 512MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_512MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 32MB blocks in 512MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		if (l1 == l1_32mb) {
+			/* Shatter this 32MB block */
+			shatter_32mb(base, gpi_info, l1_desc);
+		} else {
+			/* Fill 32MB with Contiguous descriptors */
+			fill_desc(l1, l1_cont_desc, L1_QWORDS_32MB);
+		}
+
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_32MB);
+	}
+}
+
 /*
  * This function checks to see if a GPI value is valid.
  *
@@ -213,10 +397,11 @@
 		 * to see if this PAS would fall into one that has already been
 		 * initialized.
 		 */
-		for (unsigned int i = GPT_L0_IDX(pas_regions[idx].base_pa);
-		     i <= GPT_L0_IDX(pas_regions[idx].base_pa +
-						pas_regions[idx].size - 1UL);
-		     i++) {
+		for (unsigned int i =
+			(unsigned int)GPT_L0_IDX(pas_regions[idx].base_pa);
+			i <= GPT_L0_IDX(pas_regions[idx].base_pa +
+					pas_regions[idx].size - 1UL);
+			i++) {
 			if ((GPT_L0_TYPE(l0_desc[i]) == GPT_L0_TYPE_BLK_DESC) &&
 			    (GPT_L0_BLKD_GPI(l0_desc[i]) == GPT_GPI_ANY)) {
 				/* This descriptor is unused so continue */
@@ -227,7 +412,7 @@
 			 * This descriptor has been initialized in a previous
 			 * call to this function so cannot be initialized again.
 			 */
-			ERROR("GPT: PAS[%u] overlaps with previous L0[%d]!\n",
+			ERROR("GPT: PAS[%u] overlaps with previous L0[%u]!\n",
 			      idx, i);
 			return -EFAULT;
 		}
@@ -318,7 +503,7 @@
 static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
 				size_t l0_mem_size)
 {
-	size_t l0_alignment;
+	size_t l0_alignment, locks_size = 0;
 
 	/*
 	 * Make sure PPS is valid and then store it since macros need this value
@@ -344,12 +529,28 @@
 		return -EFAULT;
 	}
 
-	/* Check size */
-	if (l0_mem_size < GPT_L0_TABLE_SIZE(gpt_config.t)) {
-		ERROR("%sL0%s\n", "GPT: Inadequate ", " memory\n");
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/*
+	 * Size of bitlocks in bytes for the protected address space
+	 * with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
+	 */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+			(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, check for a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+#endif
+	/* Check size for L0 tables and bitlocks */
+	if (l0_mem_size < (GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size)) {
+		ERROR("GPT: Inadequate L0 memory\n");
 		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
-		      GPT_L0_TABLE_SIZE(gpt_config.t),
-		      l0_mem_size);
+			GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size,
+			l0_mem_size);
 		return -ENOMEM;
 	}
 
@@ -397,9 +598,10 @@
 
 	/* Make sure enough space was supplied */
 	if (l1_mem_size < l1_gpt_mem_sz) {
-		ERROR("%sL1 GPTs%s", "GPT: Inadequate ", " memory\n");
+		ERROR("%sL1 GPTs%s", (const char *)"GPT: Inadequate ",
+			(const char *)" memory\n");
 		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
-		      l1_gpt_mem_sz, l1_mem_size);
+			l1_gpt_mem_sz, l1_mem_size);
 		return -ENOMEM;
 	}
 
@@ -418,8 +620,7 @@
 static void generate_l0_blk_desc(pas_region_t *pas)
 {
 	uint64_t gpt_desc;
-	unsigned int end_idx;
-	unsigned int idx;
+	unsigned long idx, end_idx;
 	uint64_t *l0_gpt_arr;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
@@ -448,7 +649,7 @@
 	/* Generate the needed block descriptors */
 	for (; idx < end_idx; idx++) {
 		l0_gpt_arr[idx] = gpt_desc;
-		VERBOSE("GPT: L0 entry (BLOCK) index %u [%p]: GPI = 0x%"PRIx64" (0x%"PRIx64")\n",
+		VERBOSE("GPT: L0 entry (BLOCK) index %lu [%p]: GPI = 0x%"PRIx64" (0x%"PRIx64")\n",
 			idx, &l0_gpt_arr[idx],
 			(gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) &
 			GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]);
@@ -482,51 +683,205 @@
 		return end_pa;
 	}
 
-	return (cur_idx + 1U) << GPT_L0_IDX_SHIFT;
+	return (cur_idx + 1UL) << GPT_L0_IDX_SHIFT;
 }
 
 /*
- * Helper function to fill out GPI entries in a single L1 table. This function
- * fills out entire L1 descriptors at a time to save memory writes.
+ * Helper function to fill out GPI entries from 'first' granule address of
+ * the specified 'length' in a single L1 table with 'l1_desc' Contiguous
+ * descriptor.
  *
  * Parameters
- *   gpi		GPI to set this range to
  *   l1			Pointer to L1 table to fill out
- *   first		Address of first granule in range.
- *   last		Address of last granule in range (inclusive).
+ *   first		Address of first granule in range
+ *   length		Length of the range in bytes
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
  */
-static void fill_l1_tbl(uint64_t gpi, uint64_t *l1, uintptr_t first,
-			    uintptr_t last)
+__unused static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
+					    size_t length, unsigned int gpi)
 {
-	uint64_t gpi_field = GPT_BUILD_L1_DESC(gpi);
-	uint64_t gpi_mask = ULONG_MAX;
+	/*
+	 * Look up table for contiguous blocks and descriptors.
+	 * Entries should be defined in descending block sizes:
+	 * 512MB, 32MB and 2MB.
+	 */
+	static const gpt_fill_lookup_t gpt_fill_lookup[] = {
+#if (RME_GPT_MAX_BLOCK == 512)
+		{ SZ_512M, GPT_L1_CONT_DESC_512MB },
+#endif
+#if (RME_GPT_MAX_BLOCK >= 32)
+		{ SZ_32M, GPT_L1_CONT_DESC_32MB },
+#endif
+#if (RME_GPT_MAX_BLOCK != 0)
+		{ SZ_2M, GPT_L1_CONT_DESC_2MB }
+#endif
+	};
 
-	assert(first <= last);
-	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
-	assert(l1 != NULL);
+	/*
+	 * Iterate through all block sizes (512MB, 32MB and 2MB)
+	 * starting with maximum supported.
+	 */
+	for (unsigned long i = 0UL; i < ARRAY_SIZE(gpt_fill_lookup); i++) {
+		/* Calculate index */
+		unsigned long idx = GPT_L1_INDEX(first);
+
+		/* Contiguous block size */
+		size_t cont_size = gpt_fill_lookup[i].size;
+
+		if (GPT_REGION_IS_CONT(length, first, cont_size)) {
+
+			/* Generate Contiguous descriptor */
+			uint64_t l1_desc = GPT_L1_GPI_CONT_DESC(gpi,
+						gpt_fill_lookup[i].desc);
+
+			/* Number of 128-bit L1 entries in block */
+			unsigned int cnt;
+
+			switch (cont_size) {
+			case SZ_512M:
+				cnt = L1_QWORDS_512MB;
+				break;
+			case SZ_32M:
+				cnt = L1_QWORDS_32MB;
+				break;
+			default:			/* SZ_2MB */
+				cnt = L1_QWORDS_2MB;
+			}
+
+			VERBOSE("GPT: Contiguous descriptor 0x%"PRIxPTR" %luMB\n",
+				first, cont_size / SZ_1M);
+
+			/* Fill Contiguous descriptors */
+			fill_desc(&l1[idx], l1_desc, cnt);
+			first += cont_size;
+			length -= cont_size;
+
+			if (length == 0UL) {
+				break;
+			}
+		}
+	}
+
+	return first;
+}
+
+/* Build Granules descriptor with the same 'gpi' for every GPI entry */
+static uint64_t build_l1_desc(unsigned int gpi)
+{
+	uint64_t l1_desc = (uint64_t)gpi | ((uint64_t)gpi << 4);
+
+	l1_desc |= (l1_desc << 8);
+	l1_desc |= (l1_desc << 16);
+	return (l1_desc | (l1_desc << 32));
+}
+
+/*
+ * Helper function to fill out GPI entries from 'first' to 'last' granule
+ * address in a single L1 table with 'l1_desc' Granules descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
+ */
+static uintptr_t fill_l1_gran_desc(uint64_t *l1, uintptr_t first,
+				   uintptr_t last, unsigned int gpi)
+{
+	uint64_t gpi_mask;
+	unsigned long i;
+
+	/* Generate Granules descriptor */
+	uint64_t l1_desc = build_l1_desc(gpi);
 
 	/* Shift the mask if we're starting in the middle of an L1 entry */
-	gpi_mask = gpi_mask << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
+	gpi_mask = ULONG_MAX << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
 
 	/* Fill out each L1 entry for this region */
-	for (unsigned int i = GPT_L1_IDX(gpt_config.p, first);
-	     i <= GPT_L1_IDX(gpt_config.p, last); i++) {
+	for (i = GPT_L1_INDEX(first); i <= GPT_L1_INDEX(last); i++) {
+
 		/* Account for stopping in the middle of an L1 entry */
-		if (i == GPT_L1_IDX(gpt_config.p, last)) {
+		if (i == GPT_L1_INDEX(last)) {
 			gpi_mask &= (gpi_mask >> ((15U -
 				    GPT_L1_GPI_IDX(gpt_config.p, last)) << 2));
 		}
 
+		assert((l1[i] & gpi_mask) == (GPT_L1_ANY_DESC & gpi_mask));
+
 		/* Write GPI values */
-		assert((l1[i] & gpi_mask) ==
-		       (GPT_BUILD_L1_DESC(GPT_GPI_ANY) & gpi_mask));
-		l1[i] = (l1[i] & ~gpi_mask) | (gpi_mask & gpi_field);
+		l1[i] = (l1[i] & ~gpi_mask) | (l1_desc & gpi_mask);
 
 		/* Reset mask */
 		gpi_mask = ULONG_MAX;
 	}
+
+	return last + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+}
+
+/*
+ * Helper function to fill out GPI entries in a single L1 table.
+ * This function fills out an entire L1 table with either Granules or Contiguous
+ * (RME_GPT_MAX_BLOCK != 0) descriptors depending on region length and alignment.
+ * Note. If RME_GPT_MAX_BLOCK == 0, then the L1 tables are filled with regular
+ * Granules descriptors.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ */
+static void fill_l1_tbl(uint64_t *l1, uintptr_t first, uintptr_t last,
+			unsigned int gpi)
+{
+	assert(l1 != NULL);
+	assert(first <= last);
+	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
+
+#if (RME_GPT_MAX_BLOCK != 0)
+	while (first <= last) {
+		/* Region length */
+		size_t length = last - first + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+		if (length < SZ_2M) {
+			/*
+			 * Fill with Granule descriptors in case of
+			 * region length < 2MB.
+			 */
+			first = fill_l1_gran_desc(l1, first, last, gpi);
+
+		} else if ((first & (SZ_2M - UL(1))) == UL(0)) {
+			/*
+			 * For region length >= 2MB and at least 2MB aligned
+			 * call to fill_l1_cont_desc will iterate through
+			 * all block sizes (512MB, 32MB and 2MB) supported and
+			 * fill corresponding Contiguous descriptors.
+			 */
+			first = fill_l1_cont_desc(l1, first, length, gpi);
+		} else {
+			/*
+			 * For not aligned region >= 2MB fill with Granules
+			 * descriptors up to the next 2MB aligned address.
+			 */
+			uintptr_t new_last = ALIGN_2MB(first + SZ_2M) -
+					GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+			first = fill_l1_gran_desc(l1, first, new_last, gpi);
+		}
+	}
+#else
+	/* Fill with Granule descriptors */
+	first = fill_l1_gran_desc(l1, first, last, gpi);
+#endif
+	assert(first == (last + GPT_PGS_ACTUAL_SIZE(gpt_config.p)));
 }
 
 /*
@@ -543,16 +898,14 @@
 static uint64_t *get_new_l1_tbl(void)
 {
 	/* Retrieve the next L1 table */
-	uint64_t *l1 = (uint64_t *)((uint64_t)(gpt_l1_tbl) +
-		       (GPT_L1_TABLE_SIZE(gpt_config.p) *
-		       gpt_next_l1_tbl_idx));
+	uint64_t *l1 = (uint64_t *)gpt_l1_tbl;
 
-	/* Increment L1 counter */
-	gpt_next_l1_tbl_idx++;
+	/* Increment L1 GPT address */
+	gpt_l1_tbl += GPT_L1_TABLE_SIZE(gpt_config.p);
 
 	/* Initialize all GPIs to GPT_GPI_ANY */
 	for (unsigned int i = 0U; i < GPT_L1_ENTRY_COUNT(gpt_config.p); i++) {
-		l1[i] = GPT_BUILD_L1_DESC(GPT_GPI_ANY);
+		l1[i] = GPT_L1_ANY_DESC;
 	}
 
 	return l1;
@@ -573,7 +926,7 @@
 	uintptr_t last_gran_pa;
 	uint64_t *l0_gpt_base;
 	uint64_t *l1_gpt_arr;
-	unsigned int l0_idx;
+	unsigned int l0_idx, gpi;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
 	assert(pas != NULL);
@@ -582,18 +935,19 @@
 	 * Checking of PAS parameters has already been done in
 	 * validate_pas_mappings so no need to check the same things again.
 	 */
-
 	end_pa = pas->base_pa + pas->size;
 	l0_gpt_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	/* We start working from the granule at base PA */
 	cur_pa = pas->base_pa;
 
-	/* Iterate over each L0 region in this memory range */
-	for (l0_idx = GPT_L0_IDX(pas->base_pa);
-	     l0_idx <= GPT_L0_IDX(end_pa - 1U);
-	     l0_idx++) {
+	/* Get GPI */
+	gpi = GPT_PAS_ATTR_GPI(pas->attrs);
 
+	/* Iterate over each L0 region in this memory range */
+	for (l0_idx = (unsigned int)GPT_L0_IDX(pas->base_pa);
+	     l0_idx <= (unsigned int)GPT_L0_IDX(end_pa - 1UL);
+	     l0_idx++) {
 		/*
 		 * See if the L0 entry is already a table descriptor or if we
 		 * need to create one.
@@ -623,8 +977,7 @@
 		 * function needs the addresses of the first granule and last
 		 * granule in the range.
 		 */
-		fill_l1_tbl(GPT_PAS_ATTR_GPI(pas->attrs), l1_gpt_arr,
-				cur_pa, last_gran_pa);
+		fill_l1_tbl(l1_gpt_arr, cur_pa, last_gran_pa, gpi);
 
 		/* Advance cur_pa to first granule in next L0 region */
 		cur_pa = get_l1_end_pa(cur_pa, end_pa);
@@ -644,9 +997,9 @@
  */
 static void flush_l0_for_pas_array(pas_region_t *pas, unsigned int pas_count)
 {
-	unsigned int idx;
-	unsigned int start_idx;
-	unsigned int end_idx;
+	unsigned long idx;
+	unsigned long start_idx;
+	unsigned long end_idx;
 	uint64_t *l0 = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	assert(pas != NULL);
@@ -657,7 +1010,7 @@
 	end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1UL);
 
 	/* Find lowest and highest L0 indices used in this PAS array */
-	for (idx = 1U; idx < pas_count; idx++) {
+	for (idx = 1UL; idx < pas_count; idx++) {
 		if (GPT_L0_IDX(pas[idx].base_pa) < start_idx) {
 			start_idx = GPT_L0_IDX(pas[idx].base_pa);
 		}
@@ -671,7 +1024,7 @@
 	 * the end index value.
 	 */
 	flush_dcache_range((uintptr_t)&l0[start_idx],
-			   ((end_idx + 1U) - start_idx) * sizeof(uint64_t));
+			   ((end_idx + 1UL) - start_idx) * sizeof(uint64_t));
 }
 
 /*
@@ -767,8 +1120,10 @@
 int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
 		       size_t l0_mem_size)
 {
-	int ret;
 	uint64_t gpt_desc;
+	size_t locks_size = 0;
+	__unused bitlock_t *bit_locks;
+	int ret;
 
 	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
@@ -787,9 +1142,31 @@
 		((uint64_t *)l0_mem_base)[i] = gpt_desc;
 	}
 
-	/* Flush updated L0 tables to memory */
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Initialise bitlocks at the end of L0 table */
+	bit_locks = (bitlock_t *)(l0_mem_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+
+	/* Size of bitlocks in bytes */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+					(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, initialise a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+
+	for (size_t i = 0UL; i < (locks_size/LOCK_SIZE); i++) {
+		bit_locks[i].lock = 0U;
+	}
+#endif
+
+	/* Flush updated L0 tables and bitlocks to memory */
 	flush_dcache_range((uintptr_t)l0_mem_base,
-			   (size_t)GPT_L0_TABLE_SIZE(gpt_config.t));
+				GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size);
 
 	/* Stash the L0 base address once initial setup is complete */
 	gpt_config.plat_gpt_l0_base = l0_mem_base;
@@ -806,7 +1183,7 @@
  * This function can be called multiple times with different L1 memory ranges
  * and PAS regions if it is desirable to place L1 tables in different locations
  * in memory. (ex: you have multiple DDR banks and want to place the L1 tables
- * in the DDR bank that they control)
+ * in the DDR bank that they control).
  *
  * Parameters
  *   pgs		PGS value to use for table generation.
@@ -822,8 +1199,7 @@
 			   size_t l1_mem_size, pas_region_t *pas_regions,
 			   unsigned int pas_count)
 {
-	int ret;
-	int l1_gpt_cnt;
+	int l1_gpt_cnt, ret;
 
 	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
@@ -860,9 +1236,14 @@
 
 		/* Set up parameters for L1 table generation */
 		gpt_l1_tbl = l1_mem_base;
-		gpt_next_l1_tbl_idx = 0U;
 	}
 
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
 	INFO("GPT: Boot Configuration\n");
 	INFO("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	INFO("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
@@ -894,7 +1275,7 @@
 	if (l1_gpt_cnt > 0) {
 		flush_dcache_range(l1_mem_base,
 				   GPT_L1_TABLE_SIZE(gpt_config.p) *
-				   l1_gpt_cnt);
+				   (size_t)l1_gpt_cnt);
 	}
 
 	/* Make sure that all the entries are written to the memory */
@@ -946,23 +1327,29 @@
 	gpt_config.pgs = (reg >> GPCCR_PGS_SHIFT) & GPCCR_PGS_MASK;
 	gpt_config.p = gpt_p_lookup[gpt_config.pgs];
 
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Bitlocks at the end of L0 table */
+	gpt_bitlock_base = (bitlock_t *)(gpt_config.plat_gpt_l0_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+#endif
 	VERBOSE("GPT: Runtime Configuration\n");
 	VERBOSE("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	VERBOSE("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
 	VERBOSE("  L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
 	VERBOSE("  L0 base:   0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
-
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	VERBOSE("  Bitlocks:  0x%"PRIxPTR"\n", (uintptr_t)gpt_bitlock_base);
+#endif
 	return 0;
 }
 
 /*
- * The L1 descriptors are protected by a spinlock to ensure that multiple
- * CPUs do not attempt to change the descriptors at once. In the future it
- * would be better to have separate spinlocks for each L1 descriptor.
- */
-static spinlock_t gpt_lock;
-
-/*
  * A helper to write the value (target_pas << gpi_shift) to the index of
  * the gpt_l1_addr.
  */
@@ -973,6 +1360,8 @@
 	*gpt_l1_desc &= ~(GPT_L1_GRAN_DESC_GPI_MASK << gpi_shift);
 	*gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift);
 	gpt_l1_addr[idx] = *gpt_l1_desc;
+
+	dsboshst();
 }
 
 /*
@@ -982,6 +1371,7 @@
 static int get_gpi_params(uint64_t base, gpi_info_t *gpi_info)
 {
 	uint64_t gpt_l0_desc, *gpt_l0_base;
+	__unused unsigned int block_idx;
 
 	gpt_l0_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 	gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)];
@@ -993,19 +1383,311 @@
 
 	/* Get the table index and GPI shift from PA */
 	gpi_info->gpt_l1_addr = GPT_L0_TBLD_ADDR(gpt_l0_desc);
-	gpi_info->idx = GPT_L1_IDX(gpt_config.p, base);
+	gpi_info->idx = (unsigned int)GPT_L1_INDEX(base);
 	gpi_info->gpi_shift = GPT_L1_GPI_IDX(gpt_config.p, base) << 2;
 
-	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
-	gpi_info->gpi = (gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
-		GPT_L1_GRAN_DESC_GPI_MASK;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Block index */
+	block_idx = (unsigned int)(base / (RME_GPT_BITLOCK_BLOCK * SZ_512M));
+
+	/* Bitlock address and mask */
+	gpi_info->lock = &gpt_bitlock_base[block_idx / LOCK_BITS];
+	gpi_info->mask = 1U << (block_idx & (LOCK_BITS - 1U));
+#endif
 	return 0;
 }
 
 /*
+ * Helper to retrieve the gpt_l1_desc and GPI information from gpi_info.
+ * This function is called with bitlock or spinlock acquired.
+ */
+static void read_gpi(gpi_info_t *gpi_info)
+{
+	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
+
+	if ((gpi_info->gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+				 GPT_L1_TYPE_CONT_DESC) {
+		/* Read GPI from Contiguous descriptor */
+		gpi_info->gpi = (unsigned int)GPT_L1_CONT_GPI(gpi_info->gpt_l1_desc);
+	} else {
+		/* Read GPI from Granules descriptor */
+		gpi_info->gpi = (unsigned int)((gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
+						GPT_L1_GRAN_DESC_GPI_MASK);
+	}
+}
+
+static void flush_page_to_popa(uintptr_t addr)
+{
+	size_t size = GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+	if (is_feat_mte2_supported()) {
+		flush_dcache_to_popa_range_mte2(addr, size);
+	} else {
+		flush_dcache_to_popa_range(addr, size);
+	}
+}
+
+/*
+ * Helper function to check if all L1 entries in 2MB block have
+ * the same Granules descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ *
+ * Return
+ *   true if L1 all entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* Last L1 entry index in 2MB block */
+	unsigned int long idx = GPT_L1_INDEX(ALIGN_2MB(base)) +
+						gpt_l1_cnt_2mb - 1UL;
+
+	/* Number of L1 entries in 2MB block */
+	unsigned int cnt = gpt_l1_cnt_2mb;
+
+	/*
+	 * Start check from the last L1 entry and continue until the first
+	 * non-matching to the passed Granules descriptor value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx--] != l1_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+	}
+
+	return true;
+}
+
+__unused static void fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 2MB block */
+	unsigned long idx_2 = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_2], l1_cont_desc, L1_QWORDS_2MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 2MB blocks
+ * in 32MB have the same 2MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 2MB block in 32MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base)) +
+					(15UL * gpt_l1_cnt_2mb);
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	/* Number of 2MB blocks in 32MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_2MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 2MB block and
+	 * continue until the first non-matching to 2MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 32MB block */
+	unsigned long idx_32 = GPT_L1_INDEX(ALIGN_32MB(base));
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_32], l1_cont_desc, L1_QWORDS_32MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 32MB blocks
+ * in 512MB have the same 32MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 32MB block in 512MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_512MB(base)) +
+					(15UL * 16UL * gpt_l1_cnt_2mb);
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	/* Number of 32MB blocks in 512MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_32MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 32MB block and
+	 * continue until the first non-matching to 32MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= 16UL * gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 512MB block */
+	unsigned long idx_512 = GPT_L1_INDEX(ALIGN_512MB(base));
+
+	/* 512MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 512MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_512], l1_cont_desc, L1_QWORDS_512MB);
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Granules to Contiguous descriptor.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ */
+__unused static void fuse_block(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* Start with check for 2MB block */
+	if (!check_fuse_2mb(base, gpi_info, l1_desc)) {
+		/* Check for 2MB fusing failed */
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 2)
+	fuse_2mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 32MB block */
+	if (!check_fuse_32mb(base, gpi_info, l1_desc)) {
+		/* Check for 32MB fusing failed, fuse to 2MB */
+		fuse_2mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 32)
+	fuse_32mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 512MB block */
+	if (!check_fuse_512mb(base, gpi_info, l1_desc)) {
+		/* Check for 512MB fusing failed, fuse to 32MB */
+		fuse_32mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+	/* Fuse to 512MB */
+	fuse_512mb(base, gpi_info, l1_desc);
+
+#endif	/* RME_GPT_MAX_BLOCK == 32 */
+#endif	/* RME_GPT_MAX_BLOCK == 2 */
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Contiguous to Granules descriptor. This function updates
+ * descriptor to Granules in passed 'gpt_config_t' structure as
+ * the result of shuttering.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor set this range to.
+ */
+__unused static void shatter_block(uint64_t base, gpi_info_t *gpi_info,
+				   uint64_t l1_desc)
+{
+	/* Look-up table for 2MB, 32MB and 512MB locks shattering */
+	static const gpt_shatter_func gpt_shatter_lookup[] = {
+		shatter_2mb,
+		shatter_32mb,
+		shatter_512mb
+	};
+
+	/* Look-up table for invalidation TLBs for 2MB, 32MB and 512MB blocks */
+	static const gpt_tlbi_lookup_t tlbi_lookup[] = {
+		{ tlbirpalos_2m, ~(SZ_2M - 1UL) },
+		{ tlbirpalos_32m, ~(SZ_32M - 1UL) },
+		{ tlbirpalos_512m, ~(SZ_512M - 1UL) }
+	};
+
+	/* Get shattering level from Contig field of Contiguous descriptor */
+	unsigned long level = GPT_L1_CONT_CONTIG(gpi_info->gpt_l1_desc) - 1UL;
+
+	/* Shatter contiguous block */
+	gpt_shatter_lookup[level](base, gpi_info, l1_desc);
+
+	tlbi_lookup[level].function(base & tlbi_lookup[level].mask);
+	dsbosh();
+
+	/*
+	 * Update 'gpt_config_t' structure's descriptor to Granules to reflect
+	 * the shattered GPI back to caller.
+	 */
+	gpi_info->gpt_l1_desc = l1_desc;
+}
+
+/*
  * This function is the granule transition delegate service. When a granule
  * transition request occurs it is routed to this function to have the request,
- * if valid, fulfilled following A1.1.1 Delegate of RME supplement
+ * if valid, fulfilled following A1.1.1 Delegate of RME supplement.
  *
  * TODO: implement support for transitioning multiple granules at once.
  *
@@ -1022,9 +1704,9 @@
 int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
-	int res;
+	uint64_t nse, __unused l1_desc;
 	unsigned int target_pas;
+	int res;
 
 	/* Ensure that the tables have been set up before taking requests */
 	assert(gpt_config.plat_gpt_l0_base != 0UL);
@@ -1032,10 +1714,6 @@
 	/* Ensure that caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
 	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
@@ -1060,70 +1738,80 @@
 		return -EINVAL;
 	}
 
-	target_pas = GPT_GPI_REALM;
-	if (src_sec_state == SMC_FROM_SECURE) {
+	/* Delegate request can only come from REALM or SECURE */
+	if ((src_sec_state != SMC_FROM_REALM) &&
+	    (src_sec_state != SMC_FROM_SECURE)) {
+		VERBOSE("GPT: Invalid caller security state 0x%x\n",
+							src_sec_state);
+		return -EINVAL;
+	}
+
+	if (src_sec_state == SMC_FROM_REALM) {
+		target_pas = GPT_GPI_REALM;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_REALM_DESC;
+	} else {
 		target_pas = GPT_GPI_SECURE;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_SECURE_DESC;
+	}
+
+	res = get_gpi_params(base, &gpi_info);
+	if (res != 0) {
+		return res;
 	}
 
 	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
 	 */
-	spin_lock(&gpt_lock);
-	res = get_gpi_params(base, &gpi_info);
-	if (res != 0) {
-		spin_unlock(&gpt_lock);
-		return res;
-	}
+	GPT_LOCK;
+	read_gpi(&gpi_info);
 
 	/* Check that the current address is in NS state */
 	if (gpi_info.gpi != GPT_GPI_NS) {
 		VERBOSE("GPT: Only Granule in NS state can be delegated.\n");
 		VERBOSE("      Caller: %u, Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, GPT_L1_NS_DESC);
 	}
-
+#endif
 	/*
 	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove any data speculatively fetched into the target
-	 * physical address space. Issue DC CIPAPA over address range.
+	 * physical address space.
+	 * Issue DC CIPAPA or DC_CIGDPAPA on implementations with FEAT_MTE2.
 	 */
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	flush_page_to_popa(base | nse);
 
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, target_pas);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	/* Ensure that all agents observe the new configuration */
+	tlbi_page_dsbosh(base);
 
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
 
-	/* Unlock access to the L1 tables */
-	spin_unlock(&gpt_lock);
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == l1_desc) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, l1_desc);
+	}
+#endif
+
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
@@ -1155,7 +1843,7 @@
 int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
+	uint64_t nse, __unused l1_desc;
 	int res;
 
 	/* Ensure that the tables have been set up before taking requests */
@@ -1164,10 +1852,6 @@
 	/* Ensure that MMU and caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
 	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
@@ -1192,84 +1876,80 @@
 		return -EINVAL;
 	}
 
-	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
-	 */
-	spin_lock(&gpt_lock);
-
 	res = get_gpi_params(base, &gpi_info);
 	if (res != 0) {
-		spin_unlock(&gpt_lock);
 		return res;
 	}
 
+	/*
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
+	 */
+	GPT_LOCK;
+	read_gpi(&gpi_info);
+
 	/* Check that the current address is in the delegated state */
-	if ((src_sec_state == SMC_FROM_REALM  &&
-	     gpi_info.gpi != GPT_GPI_REALM) ||
-	    (src_sec_state == SMC_FROM_SECURE &&
-	     gpi_info.gpi != GPT_GPI_SECURE)) {
-		VERBOSE("GPT: Only Granule in REALM or SECURE state can be undelegated.\n");
+	if ((src_sec_state == SMC_FROM_REALM) &&
+		(gpi_info.gpi == GPT_GPI_REALM)) {
+		l1_desc = GPT_L1_REALM_DESC;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+	} else if ((src_sec_state == SMC_FROM_SECURE) &&
+		(gpi_info.gpi == GPT_GPI_SECURE)) {
+		l1_desc = GPT_L1_SECURE_DESC;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+	} else {
+		VERBOSE("GPT: Only Granule in REALM or SECURE state can be undelegated\n");
 		VERBOSE("      Caller: %u Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-
-	/* In order to maintain mutual distrust between Realm and Secure
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, l1_desc);
+	}
+#endif
+	/*
+	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove access now, in order to guarantee that writes
 	 * to the currently-accessible physical address space will not
 	 * later become observable.
 	 */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NO_ACCESS);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	/* Ensure that all agents observe the new NO_ACCESS configuration */
+	tlbi_page_dsbosh(base);
 
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
-	}
-
-	/* Ensure that the scrubbed data has made it past the PoPA */
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
 
 	/*
-	 * Remove any data loaded speculatively
-	 * in NS space from before the scrubbing
+	 * Remove any data loaded speculatively in NS space from before
+	 * the scrubbing.
 	 */
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	if (is_feat_mte2_supported()) {
-		flush_dcache_to_popa_range_mte2(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	} else {
-		flush_dcache_to_popa_range(nse | base,
-					   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	}
+	flush_page_to_popa(base | nse);
 
-	/* Clear existing GPI encoding and transition granule. */
+	/* Clear existing GPI encoding and transition granule */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NS);
-	dsboshst();
 
 	/* Ensure that all agents observe the new NS configuration */
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	tlbi_page_dsbosh(base);
 
-	/* Unlock access to the L1 tables. */
-	spin_unlock(&gpt_lock);
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == GPT_L1_NS_DESC) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, GPT_L1_NS_DESC);
+	}
+#endif
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
diff --git a/lib/gpt_rme/gpt_rme.mk b/lib/gpt_rme/gpt_rme.mk
index 60176f4..7d6b61f 100644
--- a/lib/gpt_rme/gpt_rme.mk
+++ b/lib/gpt_rme/gpt_rme.mk
@@ -1,8 +1,22 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Process RME_GPT_BITLOCK_BLOCK value
+ifeq ($(filter 0 1 2 4 8 16 32 64 128 256 512, ${RME_GPT_BITLOCK_BLOCK}),)
+    $(error "Invalid value for RME_GPT_BITLOCK_BLOCK: ${RME_GPT_BITLOCK_BLOCK}")
+endif
+
+ifeq (${RME_GPT_BITLOCK_BLOCK},0)
+    $(warning "GPT library uses global spinlock")
+endif
+
+# Process RME_GPT_MAX_BLOCK value
+ifeq ($(filter 0 2 32 512, ${RME_GPT_MAX_BLOCK}),)
+    $(error "Invalid value for RME_GPT_MAX_BLOCK: ${RME_GPT_MAX_BLOCK}")
+endif
+
 GPT_LIB_SRCS	:=	$(addprefix lib/gpt_rme/,        \
 			gpt_rme.c)
diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h
index b2a5dae..31dad20 100644
--- a/lib/gpt_rme/gpt_rme_private.h
+++ b/lib/gpt_rme/gpt_rme_private.h
@@ -9,6 +9,7 @@
 
 #include <arch.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#include <lib/spinlock.h>
 #include <lib/utils_def.h>
 
 /******************************************************************************/
@@ -19,7 +20,7 @@
 #define GPT_L0_TYPE_MASK		UL(0xF)
 #define GPT_L0_TYPE_SHIFT		U(0)
 
-/* For now, we don't support contiguous descriptors, only table and block */
+/* GPT level 0 table and block descriptors */
 #define GPT_L0_TYPE_TBL_DESC		UL(3)
 #define GPT_L0_TYPE_BLK_DESC		UL(1)
 
@@ -29,29 +30,63 @@
 #define GPT_L0_BLK_DESC_GPI_MASK	UL(0xF)
 #define GPT_L0_BLK_DESC_GPI_SHIFT	U(4)
 
-/* GPT level 1 descriptor bit definitions */
+/* GPT level 1 Contiguous descriptor */
+#define GPT_L1_TYPE_CONT_DESC_MASK	UL(0xF)
+#define GPT_L1_TYPE_CONT_DESC		UL(1)
+
+/* GPT level 1 Contiguous descriptor definitions */
+#define GPT_L1_CONTIG_2MB		UL(1)
+#define GPT_L1_CONTIG_32MB		UL(2)
+#define GPT_L1_CONTIG_512MB		UL(3)
+
+#define GPT_L1_CONT_DESC_GPI_SHIFT	U(4)
+#define GPT_L1_CONT_DESC_GPI_MASK	UL(0xF)
+#define GPT_L1_CONT_DESC_CONTIG_SHIFT	U(8)
+#define GPT_L1_CONT_DESC_CONTIG_MASK	UL(3)
+
+/* GPT level 1 Granules descriptor bit definitions */
 #define GPT_L1_GRAN_DESC_GPI_MASK	UL(0xF)
 
+/* L1 Contiguous descriptors templates */
+#define GPT_L1_CONT_DESC_2MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_2MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_32MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_32MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_512MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_512MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and template */
+#define GPT_L1_GPI_CONT_DESC(_gpi, _desc)	\
+			((_desc) | ((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from Granules descriptor and size */
+#define GPT_L1_CONT_DESC(_desc, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((_desc) & GPT_L1_GRAN_DESC_GPI_MASK) << \
+				GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and size */
+#define GPT_L1_CONT_DESC_SIZE(_gpi, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+#define GPT_L1_GPI_BYTE(_gpi)		(uint64_t)((_gpi) | ((_gpi) << 4))
+#define GPT_L1_GPI_HALF(_gpi)		(GPT_L1_GPI_BYTE(_gpi) | (GPT_L1_GPI_BYTE(_gpi) << 8))
+#define GPT_L1_GPI_WORD(_gpi)		(GPT_L1_GPI_HALF(_gpi) | (GPT_L1_GPI_HALF(_gpi) << 16))
+
 /*
- * This macro fills out every GPI entry in a granules descriptor to the same
- * value.
+ * This macro generates a Granules descriptor
+ * with the same value for every GPI entry.
  */
-#define GPT_BUILD_L1_DESC(_gpi)		(((uint64_t)(_gpi) << 4*0) | \
-					 ((uint64_t)(_gpi) << 4*1) | \
-					 ((uint64_t)(_gpi) << 4*2) | \
-					 ((uint64_t)(_gpi) << 4*3) | \
-					 ((uint64_t)(_gpi) << 4*4) | \
-					 ((uint64_t)(_gpi) << 4*5) | \
-					 ((uint64_t)(_gpi) << 4*6) | \
-					 ((uint64_t)(_gpi) << 4*7) | \
-					 ((uint64_t)(_gpi) << 4*8) | \
-					 ((uint64_t)(_gpi) << 4*9) | \
-					 ((uint64_t)(_gpi) << 4*10) | \
-					 ((uint64_t)(_gpi) << 4*11) | \
-					 ((uint64_t)(_gpi) << 4*12) | \
-					 ((uint64_t)(_gpi) << 4*13) | \
-					 ((uint64_t)(_gpi) << 4*14) | \
-					 ((uint64_t)(_gpi) << 4*15))
+#define GPT_BUILD_L1_DESC(_gpi)		(GPT_L1_GPI_WORD(_gpi) | (GPT_L1_GPI_WORD(_gpi) << 32))
+
+#define GPT_L1_SECURE_DESC	GPT_BUILD_L1_DESC(GPT_GPI_SECURE)
+#define GPT_L1_NS_DESC		GPT_BUILD_L1_DESC(GPT_GPI_NS)
+#define GPT_L1_REALM_DESC	GPT_BUILD_L1_DESC(GPT_GPI_REALM)
+#define GPT_L1_ANY_DESC		GPT_BUILD_L1_DESC(GPT_GPI_ANY)
 
 /******************************************************************************/
 /* GPT platform configuration                                                 */
@@ -106,17 +141,46 @@
 	PGS_64KB_P =	16U
 } gpt_p_val_e;
 
+#define LOCK_SIZE	sizeof(((bitlock_t *)NULL)->lock)
+#define LOCK_TYPE	typeof(((bitlock_t *)NULL)->lock)
+#define LOCK_BITS	(LOCK_SIZE * 8U)
+
 /*
- * Internal structure to retrieve the values from get_gpi_info();
+ * Internal structure to retrieve the values from get_gpi_params();
  */
-typedef struct gpi_info {
+typedef struct {
 	uint64_t gpt_l1_desc;
 	uint64_t *gpt_l1_addr;
 	unsigned int idx;
 	unsigned int gpi_shift;
 	unsigned int gpi;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	bitlock_t *lock;
+	LOCK_TYPE mask;
+#endif
 } gpi_info_t;
 
+/*
+ * Look up structure for contiguous blocks and descriptors
+ */
+typedef struct {
+	size_t size;
+	unsigned int desc;
+} gpt_fill_lookup_t;
+
+typedef void (*gpt_shatter_func)(uintptr_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc);
+typedef void (*gpt_tlbi_func)(uintptr_t base);
+
+/*
+ * Look-up structure for
+ * invalidating TLBs of GPT entries by Physical address, last level.
+ */
+typedef struct {
+	gpt_tlbi_func function;
+	size_t mask;
+} gpt_tlbi_lookup_t;
+
 /* Max valid value for PGS */
 #define GPT_PGS_MAX			(2U)
 
@@ -136,8 +200,8 @@
  * special case we'll get a negative width value which does not make sense and
  * would cause problems.
  */
-#define GPT_L0_IDX_WIDTH(_t)		(((_t) > GPT_S_VAL) ? \
-					((_t) - GPT_S_VAL) : (0U))
+#define GPT_L0_IDX_WIDTH(_t)		(((unsigned int)(_t) > GPT_S_VAL) ? \
+					((unsigned int)(_t) - GPT_S_VAL) : (0U))
 
 /* Bit shift for the L0 index field in a PA */
 #define GPT_L0_IDX_SHIFT		(GPT_S_VAL)
@@ -173,10 +237,11 @@
  * the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ
  * (s) will result in a positive width value.
  */
-#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - ((_p) + 3U))
+#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - \
+					((unsigned int)(_p) + 3U))
 
 /* Bit shift for the L1 index field */
-#define GPT_L1_IDX_SHIFT(_p)		((_p) + 4U)
+#define GPT_L1_IDX_SHIFT(_p)		((unsigned int)(_p) + 4U)
 
 /*
  * Mask for the L1 index field, must be shifted.
@@ -196,7 +261,10 @@
 #define GPT_L1_GPI_IDX_MASK		(0xF)
 
 /* Total number of entries in each L1 table */
-#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1U)
+#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1UL)
+
+/* Number of L1 entries in 2MB block */
+#define GPT_L1_ENTRY_COUNT_2MB(_p)	(SZ_2M >> GPT_L1_IDX_SHIFT(_p))
 
 /* Total size in bytes of each L1 table */
 #define GPT_L1_TABLE_SIZE(_p)		((GPT_L1_ENTRY_COUNT(_p)) << 3U)
@@ -206,10 +274,13 @@
 /******************************************************************************/
 
 /* Protected space actual size in bytes */
-#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (_t))
+#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (unsigned int)(_t))
 
 /* Granule actual size in bytes */
-#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (_p))
+#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (unsigned int)(_p))
+
+/* Number of granules in 2MB block */
+#define GPT_PGS_COUNT_2MB(_p)	(1UL << (21U - (unsigned int)(_p)))
 
 /* L0 GPT region size in bytes */
 #define GPT_L0GPTSZ_ACTUAL_SIZE	(1UL << GPT_S_VAL)
@@ -221,7 +292,8 @@
  * This definition is used to determine if a physical address lies on an L0
  * region boundary.
  */
-#define GPT_IS_L0_ALIGNED(_pa)	(((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0))
+#define GPT_IS_L0_ALIGNED(_pa)	\
+	(((_pa) & (GPT_L0_REGION_SIZE - UL(1))) == UL(0))
 
 /* Get the type field from an L0 descriptor */
 #define GPT_L0_TYPE(_desc)	(((_desc) >> GPT_L0_TYPE_SHIFT) & \
@@ -246,16 +318,43 @@
 				(GPT_L0_TBL_DESC_L1ADDR_MASK << \
 				GPT_L0_TBL_DESC_L1ADDR_SHIFT))))
 
+/* Get the GPI from L1 Contiguous descriptor */
+#define GPT_L1_CONT_GPI(_desc)		\
+	(((_desc) >> GPT_L1_CONT_DESC_GPI_SHIFT) & GPT_L1_CONT_DESC_GPI_MASK)
+
+/* Get the GPI from L1 Granules descriptor */
+#define GPT_L1_GRAN_GPI(_desc)	((_desc) & GPT_L1_GRAN_DESC_GPI_MASK)
+
+/* Get the Contig from L1 Contiguous descriptor */
+#define GPT_L1_CONT_CONTIG(_desc)	\
+	(((_desc) >> GPT_L1_CONT_DESC_CONTIG_SHIFT) & \
+					GPT_L1_CONT_DESC_CONTIG_MASK)
+
 /* Get the index into the L1 table from a physical address */
-#define GPT_L1_IDX(_p, _pa)	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \
-				GPT_L1_IDX_MASK(_p))
+#define GPT_L1_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & GPT_L1_IDX_MASK(_p))
 
 /* Get the index of the GPI within an L1 table entry from a physical address */
-#define GPT_L1_GPI_IDX(_p, _pa)	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \
-				GPT_L1_GPI_IDX_MASK)
+#define GPT_L1_GPI_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & GPT_L1_GPI_IDX_MASK)
 
 /* Determine if an address is granule-aligned */
-#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \
-				   == U(0))
+#define GPT_IS_L1_ALIGNED(_p, _pa)	\
+	(((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - UL(1))) == UL(0))
+
+/* Get aligned addresses */
+#define ALIGN_2MB(_addr)	((_addr) & ~(SZ_2M - 1UL))
+#define ALIGN_32MB(_addr)	((_addr) & ~(SZ_32M - 1UL))
+#define ALIGN_512MB(_addr)	((_addr) & ~(SZ_512M - 1UL))
+
+/* Determine if region is contiguous */
+#define GPT_REGION_IS_CONT(_len, _addr, _size)	\
+	(((_len) >= (_size)) && (((_addr) & ((_size) - UL(1))) == UL(0)))
+
+/* Get 32MB block number in 512MB block: 0-15 */
+#define GET_32MB_NUM(_addr)	((_addr >> 25) & 0xF)
+
+/* Get 2MB block number in 32MB block: 0-15 */
+#define GET_2MB_NUM(_addr)	((_addr >> 21) & 0xF)
 
 #endif /* GPT_RME_PRIVATE_H */
diff --git a/lib/psa/cca_attestation.c b/lib/psa/cca_attestation.c
new file mode 100644
index 0000000..9e9e0c1
--- /dev/null
+++ b/lib/psa/cca_attestation.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <psa/crypto_sizes.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <cca_attestation.h>
+#include <delegated_attestation.h>
+#include <services/rmmd_svc.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type)
+{
+	size_t dak_len;
+	psa_status_t ret = PSA_SUCCESS;
+
+	/*
+	 * Current RMM implementations only support the public key size for
+	 * ECC-P384, i.e. ATTEST_KEY_CURVE_ECC_SECP384R1 attestation key.
+	 *
+	 * This ECC key has following properties:
+	 * ecc_curve:	0x12 (PSA_ECC_FAMILY_SECP_R1)
+	 * key_bits:	384
+	 * hash_alg:	0x02000009 (PSA_ALG_SHA_256)
+	 */
+	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+
+	ret = rse_delegated_attest_get_delegated_key(PSA_ECC_FAMILY_SECP_R1,
+						     384, (uint8_t *)buf, *len,
+						     &dak_len, PSA_ALG_SHA_256);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	if (dak_len != PSA_BITS_TO_BYTES(384)) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
+
+	*len = dak_len;
+
+	return ret;
+}
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size)
+{
+	size_t token_len = 0;
+	psa_status_t ret = PSA_SUCCESS;
+
+	ret = rse_delegated_attest_get_token((const uint8_t *)hash, hash_size,
+					     (uint8_t *)buf, *len, &token_len);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	*len = token_len;
+
+	return ret;
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 60449f6..9f0b190 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1303,7 +1303,7 @@
 	 * before exiting coherency.
 	 */
 	if (is_feat_spe_supported()) {
-		spe_disable();
+		spe_stop();
 	}
 
 }
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 62cbf3e..9859ce1 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -4,8 +4,14 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := aarch64
+ifeq ($(filter-out clean,$(or $(MAKECMDGOALS),all)),)
+        toolchains :=
+else
+        toolchains := aarch64
+endif
 
+include ../../make_helpers/build-rules.mk
+include ../../make_helpers/common.mk
 include ../../make_helpers/toolchain.mk
 
 ROMLIB_GEN  = ./romlib_generator.py
@@ -19,15 +25,10 @@
 MAPFILE     = $(BUILD_PLAT)/romlib/romlib.map
 
 ifneq ($(PLAT_DIR),)
-  WRAPPER_SOURCES   = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i)
-  WRAPPER_OBJS      = $(WRAPPER_SOURCES:.s=.o)
-endif
+        WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+                $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
+        WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
 endif
 
 LDFLAGS := -Wl,--gc-sections -nostdlib
@@ -46,53 +47,50 @@
 
 all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
 
-%.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
+%.o: %.s | $$(@D)/
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/%.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
+$(BUILD_DIR)/%.o: %.s | $$(@D)/
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/romlib.ld: romlib.ld.S
-	@echo "  PP      $@"
-	$(Q)$(aarch64-cpp) -E $(PPFLAGS) -o $@ romlib.ld.S
+$(BUILD_DIR)/romlib.ld: romlib.ld.S | $$(@D)/
+	$(s)echo "  PP      $@"
+	$(q)$(aarch64-cpp) -E $(PPFLAGS) -o $@ romlib.ld.S
 
-$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld
-	@echo "  LD      $@"
-	$(Q)$(aarch64-ld) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld | $$(@D)/
+	$(s)echo "  LD      $@"
+	$(q)$(aarch64-ld) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
 
-$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf
-	@echo "  BIN     $@"
-	$(Q)$(aarch64-oc) -O binary $(BUILD_DIR)/romlib.elf $@
+$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf | $$(@D)/
+	$(s)echo "  BIN     $@"
+	$(q)$(aarch64-oc) -O binary $(BUILD_DIR)/romlib.elf $@
 
-$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf
-	@echo "  VAR     $@"
-	$(Q)$(ROMLIB_GEN) genvar --output $@ $<
+$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf | $$(@D)/
+	$(s)echo "  VAR     $@"
+	$(q)$(ROMLIB_GEN) genvar --output $@ $<
 
-$(LIB_DIR)/libwrappers.a: $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
-	@echo "  AR      $@"
-	$(Q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
+$(LIB_DIR)/libwrappers.a: $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS) | $$(@D)/
+	$(s)echo "  AR      $@"
+	$(q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
 
-$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i
-	@echo "  PRE     $@"
-	$(Q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
+$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  PRE     $@"
+	$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
 
-$(BUILD_DIR)/wrappers.stamp: $(BUILD_DIR)/jmptbl.i
-	@echo "  WRP     $<"
-	$(Q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
-	@touch $@
+$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  WRP     $<"
+	$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
 
-$(WRAPPER_SOURCES): $(BUILD_DIR)/wrappers.stamp
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s | $$(@D)/
 
-$(WRAPPER_OBJS): $(WRAPPER_SOURCES) $(BUILD_DIR)/wrappers.stamp
-
-$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
-	@echo "  TBL     $@"
-	$(Q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
+$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  TBL     $@"
+	$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
 
 clean:
-	@rm -f $(BUILD_DIR)/*
+	$(q)rm -f $(BUILD_DIR)/*
 
 -include $(BUILD_DIR)/romlib.d
 -include $(BUILD_DIR)/jmptbl.d
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index b7fedfa..8d82d25 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -63,20 +63,21 @@
 	te = transfer_list_find(tl, TL_TAG_FDT);
 	dt = transfer_list_entry_data(te);
 
-	ep_info->args.arg1 = TRANSFER_LIST_SIGNATURE |
-			     REGISTER_CONVENTION_VERSION_MASK;
-	ep_info->args.arg3 = (uintptr_t)tl;
-
-	if (GET_RW(ep_info->spsr) == MODE_RW_32) {
-		/* aarch32 */
-		ep_info->args.arg0 = 0;
-		ep_info->args.arg2 = (uintptr_t)dt;
-	} else {
-		/* aarch64 */
+#ifdef __aarch64__
+	if (GET_RW(ep_info->spsr) == MODE_RW_64) {
 		ep_info->args.arg0 = (uintptr_t)dt;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
 		ep_info->args.arg2 = 0;
+	} else
+#endif
+	{
+		ep_info->args.arg0 = 0;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		ep_info->args.arg2 = (uintptr_t)dt;
 	}
 
+	ep_info->args.arg3 = (uintptr_t)tl;
+
 	return ep_info;
 }
 
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index f3a53cc..a3b913c 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 
 #include <platform_def.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/utils_def.h>
@@ -419,10 +420,59 @@
 			*attributes |= MT_USER;
 	}
 
-	uint64_t ns_bit = (desc >> NS_SHIFT) & 1U;
+	uint64_t ns_bit = (desc >> NS_SHIFT) & 1ULL;
 
-	if (ns_bit == 1U)
+#if ENABLE_RME
+	uint64_t nse_bit = (desc >> NSE_SHIFT) & 1ULL;
+	uint32_t sec_state = (uint32_t)(ns_bit | (nse_bit << 1ULL));
+
+/*
+ * =========================================================
+ *  NSE    NS  |  Output PA space
+ * =========================================================
+ *    0    0   |  Secure (if S-EL2 is present, else invalid)
+ *    0    1   |  Non-secure
+ *    1    0   |  Root
+ *    1    1   |  Realm
+ *==========================================================
+ */
+	switch (sec_state) {
+	case 0U:
+		/*
+		 * We expect to get Secure mapping on an RME system only if
+		 * S-EL2 is enabled.
+		 * Hence panic() if we hit the case without EEL2 being enabled.
+		 */
+		if ((read_scr_el3() & SCR_EEL2_BIT) == 0ULL) {
+			ERROR("A secure descriptor is not supported when"
+			      "FEAT_RME is implemented and FEAT_SEL2 is"
+			      "not enabled\n");
+			panic();
+		} else {
+			*attributes |= MT_SECURE;
+		}
+		break;
+	case 1U:
 		*attributes |= MT_NS;
+		break;
+	case 2U:
+		*attributes |= MT_ROOT;
+		break;
+	case 3U:
+		*attributes |= MT_REALM;
+		break;
+	default:
+		/* unreachable code */
+		assert(false);
+		break;
+	}
+#else /* !ENABLE_RME */
+	if (ns_bit == 1ULL) {
+		*attributes |= MT_NS;
+	} else {
+		*attributes |= MT_SECURE;
+	}
+#endif /* ENABLE_RME */
 
 	uint64_t xn_mask = xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
 
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index ac47960..ceff4ba 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -90,7 +90,7 @@
 
 # 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
+armv8-9-a-feats         := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9
 # 8.8 Compliant
 armv8-9-a-feats         += ${armv8-8-a-feats}
 FEAT_LIST               := ${armv8-9-a-feats}
@@ -280,7 +280,7 @@
 ENABLE_FEAT_AMU				?=	0
 ENABLE_AMU_AUXILIARY_COUNTERS		?=	0
 ENABLE_AMU_FCONF			?=	0
-AMU_RESTRICT_COUNTERS			?=	0
+AMU_RESTRICT_COUNTERS			?=	1
 
 # Build option to enable MPAM for lower ELs.
 # Enabling it by default
@@ -337,6 +337,9 @@
 # Disable MTPMU if FEAT_MTPMU is supported.
 DISABLE_MTPMU				?=	0
 
+# Flag to enable FEAT_FGT2 (Fine Granular Traps 2)
+ENABLE_FEAT_FGT2			?=	0
+
 #----
 # 8.9
 #----
@@ -353,6 +356,9 @@
 # Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE).
 ENABLE_FEAT_S1POE			?=	0
 
+# Flag to enable access to Arm v8.9 Debug extension
+ENABLE_FEAT_DEBUGV8P9			?=	0
+
 #----
 # 9.0
 #----
diff --git a/make_helpers/build-rules.mk b/make_helpers/build-rules.mk
new file mode 100644
index 0000000..d325b3a
--- /dev/null
+++ b/make_helpers/build-rules.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef build-rules-mk
+        build-rules-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(build-rules-mk))common.mk
+        include $(dir $(build-rules-mk))utilities.mk
+
+        .SECONDEXPANSION:
+
+        %/:
+		$(s)echo '  MD      '$(call escape-shell,$(abspath $@))
+		$(q)mkdir -p $(call escape-shell,$@)
+endif
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
index a545cd0..13acaae 100644
--- a/make_helpers/build_env.mk
+++ b/make_helpers/build_env.mk
@@ -15,8 +15,6 @@
     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.")
-    MD                  :=      $$(error "Replace MD with call to MAKE_PREREQ_DIR.")
-    MKDIR               :=      $$(error "Replace MKDIR with call to MAKE_PREREQ_DIR.")
     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.")
@@ -62,9 +60,6 @@
     ifndef SHELL_DELETE
         $(error "SHELL_DELETE not defined for build environment.")
     endif
-    ifndef MAKE_PREREQ_DIR
-        $(error "MAKE_PREREQ_DIR not defined for build environment.")
-    endif
     ifndef SHELL_REMOVE_DIR
         $(error "SHELL_REMOVE_DIR not defined for build environment.")
     endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index cf4595c..7050916 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -17,22 +17,6 @@
 $(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
 endef
 
-# This table is used in converting lower case to upper case.
-uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
-
-# Internal macro used for converting lower case to upper case.
-#   $(1) = upper case table
-#   $(2) = String to convert
-define uppercase_internal
-$(if $(1),$$(subst $(firstword $(1)),$(call uppercase_internal,$(wordlist 2,$(words $(1)),$(1)),$(2))),$(2))
-endef
-
-# A macro for converting a string to upper case
-#   $(1) = String to convert
-define uppercase
-$(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
-endef
-
 # Convenience function for setting a variable to 0 if not previously set
 # $(eval $(call default_zero,FOO))
 define default_zero
@@ -164,8 +148,8 @@
 #   $(2) = output encrypted firmware binary
 define ENCRYPT_FW
 $(2): $(1) enctool
-	$$(ECHO) "  ENC     $$<"
-	$$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+	$$(s)echo "  ENC     $$<"
+	$$(q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
 endef
 
 # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
@@ -283,8 +267,8 @@
 # GZIP
 define GZIP_RULE
 $(1): $(2)
-	$(ECHO) "  GZIP    $$@"
-	$(Q)gzip -n -f -9 $$< --stdout > $$@
+	$(s)echo "  GZIP    $$@"
+	$(q)gzip -n -f -9 $$< --stdout > $$@
 endef
 
 GZIP_SUFFIX := .gz
@@ -305,9 +289,9 @@
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 $(eval LIB := $(call uppercase, $(notdir $(1))))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -321,9 +305,9 @@
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(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 $$@
 
 -include $(DEP)
 
@@ -344,9 +328,9 @@
 $(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))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(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 $$@
 
 -include $(DEP)
 
@@ -367,9 +351,9 @@
 $(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))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(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 $$@
 
 -include $(DEP)
 
@@ -388,9 +372,9 @@
 $(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))
 
-$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  PP      $$<"
-	$$(Q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+$(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 $$@ $$<
 
 -include $(DEP)
 
@@ -440,17 +424,6 @@
 
 .PHONY: libraries
 
-# MAKE_LIB_DIRS macro defines the target for the directory where
-# libraries are created
-define MAKE_LIB_DIRS
-        $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
-        $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
-        $(eval LIBWRAPPER_DIR := ${BUILD_PLAT}/libwrapper)
-        $(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
-        $(eval $(call MAKE_PREREQ_DIR,${ROMLIB_DIR},${BUILD_PLAT}))
-        $(eval $(call MAKE_PREREQ_DIR,${LIBWRAPPER_DIR},${BUILD_PLAT}))
-endef
-
 # MAKE_LIB macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = Library name
@@ -461,11 +434,8 @@
         $(eval SOURCES    := $(LIB$(call uppercase,$(1))_SRCS))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
 $(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
 
-.PHONY : lib${1}_dirs
-lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR}  ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
 libraries: ${LIB_DIR}/lib$(1).a
 ifeq ($($(ARCH)-ld-id),arm-link)
 LDPATHS = --userlibpath=${LIB_DIR}
@@ -481,9 +451,9 @@
 
 all: ${LIB_DIR}/lib$(1).a
 
-${LIB_DIR}/lib$(1).a: $(OBJS)
-	$$(ECHO) "  AR      $$@"
-	$$(Q)$($(ARCH)-ar) cr $$@ $$?
+${LIB_DIR}/lib$(1).a: $(OBJS) | $$$$(@D)/
+	$$(s)echo "  AR      $$@"
+	$$(q)$($(ARCH)-ar) cr $$@ $$?
 endef
 
 # Generate the path to one or more preprocessed linker scripts given the paths
@@ -519,26 +489,6 @@
         $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
         $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
 
-        # We use sort only to get a list of unique object directory names.
-        # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${DEFAULT_LINKER_SCRIPT} ${LINKER_SCRIPTS})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval OBJ_DIRS   := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
-
-# Create generators for object directory structure
-
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
-
-$(eval $(foreach objd,${OBJ_DIRS},
-        $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-
-.PHONY : ${1}_dirs
-
-# We use order-only prerequisites to ensure that directories are created,
-# but do not cause re-builds every time a file is written.
-${1}_dirs: | ${OBJ_DIRS}
-
 $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
 
 # Generate targets to preprocess each required linker script
@@ -548,46 +498,46 @@
 $(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
-$(ELF): romlib.bin
+$(ELF): romlib.bin | $$$$(@D)/
 endif
 
 # MODULE_OBJS can be assigned by vendors with different compiled
 # object file path, and prebuilt object file path.
 $(eval OBJS += $(MODULE_OBJS))
 
-$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
-	$$(ECHO) "  LD      $$@"
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $$$$(@D)/ libraries $(BL_LIBS)
+	$$(s)echo "  LD      $$@"
 ifeq ($($(ARCH)-ld-id),arm-link)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
-		--predefine="-D__LINKER__=$(__LINKER__)" \
-		--predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
+		--predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
+		--predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
 		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
 		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
 else ifeq ($($(ARCH)-ld-id),gnu-gcc)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
 		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
 		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 endif
 
-$(DUMP): $(ELF)
-	$${ECHO} "  OD      $$@"
-	$${Q}$($(ARCH)-od) -dx $$< > $$@
+$(DUMP): $(ELF) | $$$$(@D)/
+	$$(s)echo "  OD      $$@"
+	$$(q)$($(ARCH)-od) -dx $$< > $$@
 
-$(BIN): $(ELF)
-	$${ECHO} "  BIN     $$@"
-	$$(Q)$($(ARCH)-oc) -O binary $$< $$@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+$(BIN): $(ELF) | $$$$(@D)/
+	$$(s)echo "  BIN     $$@"
+	$$(q)$($(ARCH)-oc) -O binary $$< $$@
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 
 .PHONY: $(1)
 ifeq ($(DISABLE_BIN_GENERATION),1)
@@ -614,22 +564,6 @@
         $(notdir $(patsubst %.dts,%.dtb,$(filter %.dts,$(1))))
 endef
 
-# MAKE_FDT_DIRS macro creates the prerequisite directories that host the
-# FDT binaries
-#   $(1) = output directory
-#   $(2) = input dts
-define MAKE_FDT_DIRS
-        $(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-        $(eval TEMP_DTB_DIRS := $(sort $(dir ${DTBS})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval DTB_DIRS   := $(patsubst %/,%,$(TEMP_DTB_DIRS)))
-
-$(eval $(foreach objd,${DTB_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-
-fdt_dirs: ${DTB_DIRS}
-endef
-
 # MAKE_DTB generate the Flattened device tree binary
 #   $(1) = output directory
 #   $(2) = input dts
@@ -644,14 +578,14 @@
 # Dependencies of the DT compilation on its pre-compiled DTS
 $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 
-$(DPRE): $(2) | fdt_dirs
-	$${ECHO} "  CPP     $$<"
+$(DPRE): $(2) | $$$$(@D)/
+	$$(s)echo "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+	$$(q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
 
-$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
-	$${ECHO} "  DTC     $$<"
-	$$(Q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
+$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  DTC     $$<"
+	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
 
 -include $(DTBDEP)
 -include $(DTSDEP)
@@ -667,8 +601,6 @@
         $(and $(REMAIN),$(error FDT_SOURCES contain non-DTS files: $(REMAIN)))
         $(eval $(foreach obj,$(DOBJS),$(call MAKE_DTB,$(1),$(obj))))
 
-        $(eval $(call MAKE_FDT_DIRS,$(1),$(2)))
-
-dtbs: $(DTBS)
+dtbs: $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2)))
 all: dtbs
 endef
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
new file mode 100644
index 0000000..75d9f71
--- /dev/null
+++ b/make_helpers/common.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef common-mk
+        common-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(common-mk))utilities.mk
+
+        silent = $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
+        verbose = $(if $(silent),,$(call bool,$(V)))
+
+        s = @$(if $(or $(verbose),$(silent)),: )
+        q = $(if $(verbose),,@)
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 2685195..368d26d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -139,6 +139,12 @@
 # For Chain of Trust
 GENERATE_COT			:= 0
 
+# Default number of 512 blocks per bitlock
+RME_GPT_BITLOCK_BLOCK		:= 1
+
+# Default maximum size of GPT contiguous block
+RME_GPT_MAX_BLOCK		:= 2
+
 # Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
 # default, they are for Secure EL1.
 GICV2_G0_FOR_EL3		:= 0
@@ -288,9 +294,6 @@
 # Use tbbr_oid.h instead of platform_oid.h
 USE_TBBR_DEFS			:= 1
 
-# Build verbosity
-V				:= 0
-
 # Whether to enable D-Cache early during warm boot. This is usually
 # applicable for platforms wherein interconnect programming is not
 # required to enable cache coherency after warm reset (eg: single cluster
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
index 25bb936..8e73116 100644
--- a/make_helpers/march.mk
+++ b/make_helpers/march.mk
@@ -21,7 +21,7 @@
 # armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
 # [...]
 #
-GCC_MARCH_OUTPUT := $(shell $($(ARCH)-cc) -march=foo -Q --help=target -v 2>&1)
+GCC_MARCH_OUTPUT := $(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -march=foo -Q --help=target -v 2>&1))
 
 # This function is used to find the best march value supported by the given compiler.
 # We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
index 8e55619..96e43a8 100644
--- a/make_helpers/toolchain.mk
+++ b/make_helpers/toolchain.mk
@@ -8,355 +8,339 @@
 # TF-A uses three toolchains:
 #
 #   - The host toolchain (`host`) for building native tools
-#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
+#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
 #   - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images
 #
 # In the main Makefile only one of the two Arm toolchains is enabled in any
 # given build, but individual tools and libraries may need access to both.
 #
 
-toolchains ?= host $(ARCH)
+ifndef toolchain-mk
+        toolchain-mk := $(lastword $(MAKEFILE_LIST))
 
-include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk
+        toolchains ?= host $(ARCH)
 
-include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
-        $(addsuffix .mk,$(toolchains)))
+        include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
+        include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk
 
-#
-# Configure tool classes that we recognize.
-#
-# In the context of this build system, a tool class identifies a specific role
-# or type of tool in the toolchain.
-#
+        include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
+                $(addsuffix .mk,$(toolchains)))
 
-tool-classes := cc
-tool-class-name-cc := C compiler
+        #
+        # Configure tool classes that we recognize.
+        #
+        # In the context of this build system, a tool class identifies a
+        # specific role or type of tool in the toolchain.
+        #
 
-tool-classes += cpp
-tool-class-name-cpp := C preprocessor
+        tool-classes := cc
+        tool-class-name-cc := C compiler
 
-tool-classes += as
-tool-class-name-as := assembler
+        tool-classes += cpp
+        tool-class-name-cpp := C preprocessor
 
-tool-classes += ld
-tool-class-name-ld := linker
+        tool-classes += as
+        tool-class-name-as := assembler
 
-tool-classes += oc
-tool-class-name-oc := object copier
+        tool-classes += ld
+        tool-class-name-ld := linker
 
-tool-classes += od
-tool-class-name-od := object dumper
+        tool-classes += oc
+        tool-class-name-oc := object copier
 
-tool-classes += ar
-tool-class-name-ar := archiver
+        tool-classes += od
+        tool-class-name-od := object dumper
 
-tool-classes += dtc
-tool-class-name-dtc := device tree compiler
+        tool-classes += ar
+        tool-class-name-ar := archiver
 
-#
-# Configure tools that we recognize.
-#
-# Here we declare the list of specific toolchain tools that we know how to
-# interact with. We don't organize these into tool classes yet - that happens
-# further down.
-#
+        tool-classes += dtc
+        tool-class-name-dtc := device tree compiler
 
-# Arm® Compiler for Embedded
-tools := arm-clang
-tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
+        #
+        # Configure tools that we recognize.
+        #
+        # Here we declare the list of specific toolchain tools that we know how
+        # to interact with. We don't organize these into tool classes yet - that
+        # happens further down.
+        #
 
-tools += arm-link
-tool-name-arm-link := Arm® Compiler for Embedded `armlink`
+        # Arm® Compiler for Embedded
+        tools := arm-clang
+        tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
 
-tools += arm-ar
-tool-name-arm-ar := Arm® Compiler for Embedded `armar`
+        tools += arm-link
+        tool-name-arm-link := Arm® Compiler for Embedded `armlink`
 
-tools += arm-fromelf
-tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
+        tools += arm-ar
+        tool-name-arm-ar := Arm® Compiler for Embedded `armar`
 
-# LLVM Project
-tools += llvm-clang
-tool-name-llvm-clang := LLVM Clang (`clang`)
+        tools += arm-fromelf
+        tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
 
-tools += llvm-lld
-tool-name-llvm-lld := LLVM LLD (`lld`)
+        # LLVM Project
+        tools += llvm-clang
+        tool-name-llvm-clang := LLVM Clang (`clang`)
 
-tools += llvm-objcopy
-tool-name-llvm-objcopy := LLVM `llvm-objcopy`
+        tools += llvm-lld
+        tool-name-llvm-lld := LLVM LLD (`lld`)
 
-tools += llvm-objdump
-tool-name-llvm-objdump := LLVM `llvm-objdump`
+        tools += llvm-objcopy
+        tool-name-llvm-objcopy := LLVM `llvm-objcopy`
 
-tools += llvm-ar
-tool-name-llvm-ar := LLVM `llvm-ar`
+        tools += llvm-objdump
+        tool-name-llvm-objdump := LLVM `llvm-objdump`
 
-# GNU Compiler Collection & GNU Binary Utilities
-tools += gnu-gcc
-tool-name-gnu-gcc := GNU GCC (`gcc`)
+        tools += llvm-ar
+        tool-name-llvm-ar := LLVM `llvm-ar`
 
-tools += gnu-ld
-tool-name-gnu-ld := GNU LD (`ld.bfd`)
+        # GNU Compiler Collection & GNU Binary Utilities
+        tools += gnu-gcc
+        tool-name-gnu-gcc := GNU GCC (`gcc`)
 
-tools += gnu-objcopy
-tool-name-gnu-objcopy := GNU `objcopy`
+        tools += gnu-ld
+        tool-name-gnu-ld := GNU LD (`ld.bfd`)
 
-tools += gnu-objdump
-tool-name-gnu-objdump := GNU `objdump`
+        tools += gnu-objcopy
+        tool-name-gnu-objcopy := GNU `objcopy`
 
-tools += gnu-ar
-tool-name-gnu-ar := GNU `ar`
+        tools += gnu-objdump
+        tool-name-gnu-objdump := GNU `objdump`
 
-# Other tools
-tools += generic-dtc
-tool-name-generic-dtc := Device Tree Compiler (`dtc`)
+        tools += gnu-ar
+        tool-name-gnu-ar := GNU `ar`
 
-#
-# Assign tools to tool classes.
-#
-# Multifunctional tools, i.e. tools which can perform multiple roles in a
-# toolchain, may be specified in multiple tool class lists. For example, a C
-# compiler which can also perform the role of a linker may be placed in both
-# `tools-cc` and `tools-ld`.
-#
+        # Other tools
+        tools += generic-dtc
+        tool-name-generic-dtc := Device Tree Compiler (`dtc`)
 
-# C-related tools
-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
+        #
+        # Assign tools to tool classes.
+        #
+        # Multifunctional tools, i.e. tools which can perform multiple roles in
+        # a toolchain, may be specified in multiple tool class lists. For
+        # example, a C compiler which can also perform the role of a linker may
+        # be placed in both `tools-cc` and `tools-ld`.
+        #
 
-# Assembly-related tools
-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
+        # C-related tools
+        tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
+        tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
 
-# Linking and object-handling tools
-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
-tools-ar := arm-ar llvm-ar gnu-ar # Archivers
+        # Assembly-related tools
+        tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
 
-# Other tools
-tools-dtc := generic-dtc # Device tree compilers
+        # Linking and object-handling tools
+        tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
+        tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
+        tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
+        tools-ar := arm-ar llvm-ar gnu-ar # Archivers
 
-define check-tool-class-tools
-        $(eval tool-class := $(1))
+        # Other tools
+        tools-dtc := generic-dtc # Device tree compilers
 
-        ifndef tools-$(tool-class)
-                $$(error no tools registered to handle tool class `$(tool-class)`)
-        endif
-endef
+        define check-tool-class-tools
+                $(eval tool-class := $(1))
 
-$(foreach tool-class,$(tool-classes), \
-        $(eval $(call check-tool-class-tools,$(tool-class))))
-
-#
-# Default tools for each toolchain.
-#
-# Toolchains can specify a default path to any given tool with a tool class.
-# These values are used in the absence of user-specified values, and are
-# configured by the makefile for each toolchain using variables of the form:
-#
-#   - $(toolchain)-$(tool-class)-default
-#
-# For example, the default C compiler for the AArch32 and AArch64 toolchains
-# could be configured with:
-#
-#   - aarch32-cc-default
-#   - aarch64-cc-default
-#
-
-define check-toolchain-tool-class-default
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
-
-        ifndef $(toolchain)-$(tool-class)-default
-                $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
-        endif
-endef
-
-define check-toolchain-tool-class-defaults
-        $(eval toolchain := $(1))
+                ifndef tools-$(tool-class)
+                        $$(error no tools registered to handle tool class `$(tool-class)`)
+                endif
+        endef
 
         $(foreach tool-class,$(tool-classes), \
-                $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
-endef
+                $(eval $(call check-tool-class-tools,$(tool-class))))
 
-$(foreach toolchain,$(toolchains), \
-        $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
+        #
+        # Default tools for each toolchain.
+        #
+        # Toolchains can specify a default path to any given tool with a tool
+        # class. These values are used in the absence of user-specified values,
+        # and are configured by the makefile for each toolchain using variables
+        # of the form:
+        #
+        #   - $(toolchain)-$(tool-class)-default
+        #
+        # For example, the default C compiler for the AArch32 and AArch64
+        # toolchains could be configured with:
+        #
+        #   - aarch32-cc-default
+        #   - aarch64-cc-default
+        #
 
-#
-# Helper functions to identify toolchain tools.
-#
-# The functions defined in this section return a tool identifier when given a
-# path to a binary. We generally check a help or version string to more reliably
-# identify tools than by looking at the path alone (e.g. `gcc` on macOS is
-# actually Apple Clang).
-#
-# Each tool-guessing function (`guess-tool-$(tool)`) takes a single argument
-# giving the path to the tool to guess, and returns a non-empty value if the
-# tool corresponds to the tool identifier `$(tool)`:
-#
-#     $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
-#     $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
-#
-# The `guess-tool` function tries to find the corresponding tool identifier
-# for a tool given its path. It takes two arguments:
-#
-#   - $(1): a list of candidate tool identifiers to check
-#   - $(2): the path to the tool to identify
-#
-# If any of the guess functions corresponding to candidate tool identifiers
-# return a non-empty value then the tool identifier of the first function to do
-# so is returned:
-#
-#     $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
-#     $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
-#     $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
-#
-# Tools are checked in the order that they appear in `tools-$(tool-class)`, and
-# the first match is returned.
-#
+        define check-toolchain-tool-class-default
+                $(eval toolchain := $(1))
+                $(eval tool-class := $(2))
 
-# Arm Compiler for Embedded
-guess-tool-arm-clang = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
-guess-tool-arm-link = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
-guess-tool-arm-fromelf = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
-guess-tool-arm-ar = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Tool: armar")
-
-# LLVM Project
-guess-tool-llvm-clang = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "clang version")
-guess-tool-llvm-lld = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
-guess-tool-llvm-objcopy = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
-guess-tool-llvm-objdump = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
-guess-tool-llvm-ar = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
-
-# GNU Compiler Collection & GNU Binary Utilities
-guess-tool-gnu-gcc = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "gcc version")
-guess-tool-gnu-ld = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "GNU ld")
-guess-tool-gnu-objcopy = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
-guess-tool-gnu-objdump = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU objdump")
-guess-tool-gnu-ar = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU ar")
-
-# Other tools
-guess-tool-generic-dtc = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Version: DTC")
-
-guess-tool = $(firstword $(foreach candidate,$(1), \
-        $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
-
-#
-# Locate and identify tools belonging to each toolchain.
-#
-# Each tool class in each toolchain receives a variable of the form
-# `$(toolchain)-$(tool)` giving the associated path to the program. For example:
-#
-#   - `aarch64-ld` gives the linker for the AArch64 toolchain,
-#   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
-#   - `host-cc` gives the C compiler for the host toolchain.
-#
-# For each of these variables, if no program path is explicitly provided by the
-# parent Makefile then the C compiler is queried (if supported) for its
-# location. This is done via the `guess-$(tool)-$(tool-class)` set of functions.
-# For example:
-#
-#   - `guess-arm-clang-ld` guesses the linker via Arm Clang,
-#   - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
-#   - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
-#
-# If the C compiler cannot provide the location (or the tool class is the C
-# compiler), then it is assigned the value of the `$(toolchain)-$(tool)-default`
-# variable.
-#
-
-guess-arm-clang-cpp = $(1)
-guess-arm-clang-as = $(1)
-guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
-guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
-guess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
-guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
-
-guess-llvm-clang-cpp = $(1)
-guess-llvm-clang-as = $(1)
-guess-llvm-clang-ld = $(shell $(call escape-shell,$(1)) --print-prog-name ld.lld 2>$(nul))
-guess-llvm-clang-oc = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-objcopy 2>$(nul))
-guess-llvm-clang-od = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-objdump 2>$(nul))
-guess-llvm-clang-ar = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-ar 2>$(nul))
-
-guess-gnu-gcc-cpp = $(1)
-guess-gnu-gcc-as = $(1)
-guess-gnu-gcc-ld = $(1)
-guess-gnu-gcc-oc = $(shell $(call escape-shell,$(1)) --print-prog-name objcopy 2>$(nul))
-guess-gnu-gcc-od = $(shell $(call escape-shell,$(1)) --print-prog-name objdump 2>$(nul))
-guess-gnu-gcc-ar = $(call which,$(call decompat-path,$(patsubst %$(call file-name,$(1)),%$(subst gcc,gcc-ar,$(call file-name,$(1))),$(call compat-path,$(1)))))
-
-define warn-unrecognized-tool
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
-
-        $$(warning )
-        $$(warning The configured $$($(toolchain)-name) $$(tool-class-name-$(tool-class)) could not be identified and may not be supported:)
-        $$(warning )
-        $$(warning $$(space)   $$($(toolchain)-$(tool-class)))
-        $$(warning )
-        $$(warning The default $$($(toolchain)-name) $$(tool-class-name-$(tool-class)) is:)
-        $$(warning )
-        $$(warning $$(space)   $$($(toolchain)-$(tool-class)-default))
-        $$(warning )
-        $$(warning The following tools are supported:)
-        $$(warning )
-
-        $$(foreach tool,$$(tools-$(tool-class)), \
-                $$(warning $$(space) - $$(tool-name-$$(tool))))
-
-        $$(warning )
-        $$(warning The build system will treat this $$(tool-class-name-$(tool-class)) as $$(tool-name-$$($(toolchain)-$(tool-class)-id-default)).)
-        $$(warning )
-endef
-
-define locate-toolchain-tool-cc
-        $(eval toolchain := $(1))
-
-        $(toolchain)-cc := $$(or $$($(toolchain)-cc),$$($(toolchain)-cc-default))
-        $(toolchain)-cc-id := $$(call guess-tool,$$(tools-cc),$$($(toolchain)-cc))
-
-        ifndef $(toolchain)-cc-id
-                $(toolchain)-cc-id := $$($(toolchain)-cc-id-default)
-
-                $$(eval $$(call warn-unrecognized-tool,$(toolchain),cc))
-        endif
-
-        $(toolchain)-cc-path := $$($(toolchain)-cc)
-        $(toolchain)-cc := $$(call escape-shell,$$($(toolchain)-cc))
-endef
-
-define locate-toolchain-tool
-        $(eval toolchain := $(1))
-        $(eval tool-class := $(2))
-
-        ifndef $(toolchain)-$(tool-class)
-                $(toolchain)-$(tool-class) := $$(call guess-$$($(toolchain)-cc-id)-$(tool-class),$$($(toolchain)-cc-path))
-
-                ifndef $(toolchain)-$(tool-class)
-                        $(toolchain)-$(tool-class) := $$($(toolchain)-$(tool-class)-default)
+                ifndef $(toolchain)-$(tool-class)-default
+                        $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
                 endif
-        endif
+        endef
 
-        $(toolchain)-$(tool-class)-id := $$(call guess-tool,$$(tools-$(tool-class)),$$($(toolchain)-$(tool-class)))
+        define check-toolchain-tool-class-defaults
+                $(eval toolchain := $(1))
 
-        ifndef $(toolchain)-$(tool-class)-id
-                $(toolchain)-$(tool-class)-id := $$($(toolchain)-$(tool-class)-id-default)
+                $(foreach tool-class,$(tool-classes), \
+                        $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
+        endef
 
-                $$(eval $$(call warn-unrecognized-tool,$(toolchain),$(tool-class)))
-        endif
+        $(foreach toolchain,$(toolchains), \
+                $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
 
-        $(toolchain)-$(tool-class) := $$(call escape-shell,$$($(toolchain)-$(tool-class)))
-endef
+        #
+        # Helper functions to identify toolchain tools.
+        #
+        # The functions defined in this section return a tool identifier when
+        # given a path to a binary. We generally check a help or version string
+        # to more reliably identify tools than by looking at the path alone
+        # (e.g. `gcc` on macOS is actually Apple Clang).
+        #
+        # Each tool-guessing function (`guess-tool-$(tool)`) takes a single
+        # argument giving the path to the tool to guess, and returns a non-empty
+        # value if the tool corresponds to the tool identifier `$(tool)`:
+        #
+        #     $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
+        #     $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
+        #
+        # The `guess-tool` function tries to find the corresponding tool
+        # identifier for a tool given its path. It takes two arguments:
+        #
+        #   - $(1): a list of candidate tool identifiers to check
+        #   - $(2): the path to the tool to identify
+        #
+        # If any of the guess functions corresponding to candidate tool
+        # identifiers return a non-empty value then the tool identifier of the
+        # first function to do so is returned:
+        #
+        #     $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
+        #     $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
+        #     $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
+        #
+        # Tools are checked in the order that they appear in
+        # `tools-$(tool-class)`, and the first match is returned.
+        #
 
-define locate-toolchain
-        $(eval toolchain := $(1))
+        # Arm Compiler for Embedded
+        guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
+        guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
+        guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
+        guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
 
-        $$(eval $$(call locate-toolchain-tool-cc,$(toolchain)))
+        # LLVM Project
+        guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
+        guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
+        guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
+        guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
+        guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
 
-        $$(foreach tool-class,$$(filter-out cc,$$(tool-classes)), \
-                $$(eval $$(call locate-toolchain-tool,$(toolchain),$$(tool-class))))
-endef
+        # GNU Compiler Collection & GNU Binary Utilities
+        guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
+        guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
+        guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
+        guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
+        guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
 
-$(foreach toolchain,$(toolchains), \
-        $(eval $(call locate-toolchain,$(toolchain))))
+        # Other tools
+        guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
+
+        guess-tool = $(firstword $(foreach candidate,$(1), \
+                $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
+
+        #
+        # Locate and identify tools belonging to each toolchain.
+        #
+        # Each tool class in each toolchain receives a variable of the form
+        # `$(toolchain)-$(tool)` giving the associated path to the program. For
+        # example:
+        #
+        #   - `aarch64-ld` gives the linker for the AArch64 toolchain,
+        #   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
+        #   - `host-cc` gives the C compiler for the host toolchain.
+        #
+        # For each of these variables, if no program path is explicitly provided
+        # by the parent Makefile then the C compiler is queried (if supported)
+        # for its location. This is done via the `guess-$(tool)-$(tool-class)`
+        # set of functions. For example:
+        #
+        #   - `guess-arm-clang-ld` guesses the linker via Arm Clang,
+        #   - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
+        #   - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
+        #
+        # If the C compiler cannot provide the location (or the tool class is
+        # the C compiler), then it is assigned the value of the
+        # `$(toolchain)-$(tool)-default` variable.
+        #
+
+        guess-arm-clang-cpp = $(1)
+        guess-arm-clang-as = $(1)
+        guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
+        guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
+        guess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
+        guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
+
+        guess-llvm-clang-cpp = $(1)
+        guess-llvm-clang-as = $(1)
+        guess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
+        guess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
+        guess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
+        guess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
+
+        guess-gnu-gcc-cpp = $(1)
+        guess-gnu-gcc-as = $(1)
+        guess-gnu-gcc-ld = $(1)
+        guess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
+        guess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
+        guess-gnu-gcc-ar = $(call which,$(call decompat-path,$(patsubst %$(call file-name,$(1)),%$(subst gcc,gcc-ar,$(call file-name,$(1))),$(call compat-path,$(1)))))
+
+        define toolchain-warn-unrecognized
+                $$(warning )
+                $$(warning The configured $$($(1)-name) $$(tool-class-name-$(2)) could not be identified and may not be supported:)
+                $$(warning )
+                $$(warning $$(space)   $$($(1)-$(2)))
+                $$(warning )
+                $$(warning The default $$($(1)-name) $$(tool-class-name-$(2)) is:)
+                $$(warning )
+                $$(warning $$(space)   $$($(1)-$(2)-default))
+                $$(warning )
+                $$(warning The following tools are supported:)
+                $$(warning )
+
+                $$(foreach tool,$$(tools-$(2)), \
+                        $$(warning $$(space) - $$(tool-name-$$(tool))))
+
+                $$(warning )
+                $$(warning The build system will treat this $$(tool-class-name-$(2)) as $$(tool-name-$$($(1)-$(2)-id-default)).)
+                $$(warning )
+        endef
+
+        define toolchain-determine-tool
+                $(1)-$(2)-guess = $$(if $$(filter-out cc,$(2)),$\
+                        $$(call guess-$$($(1)-cc-id)-$(2),$$($(1)-cc)))
+
+                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-guess))
+                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-default))
+
+                ifneq ($$(call which,$$($(1)-$(2))),)
+                        # If we can resolve this tool to a program on the `PATH`
+                        # then escape it for use in a shell, which allows us to
+                        # preserve spaces.
+
+                        $(1)-$(2) := $$(call escape-shell,$$($(1)-$(2)))
+                endif
+
+                $(1)-$(2)-id := $$(call guess-tool,$$(tools-$(2)),$$($(1)-$(2)))
+
+                ifndef $(1)-$(2)-id
+                        $(1)-$(2)-id := $$($(1)-$(2)-id-default)
+
+                        $$(eval $$(call toolchain-warn-unrecognized,$(1),$(2)))
+                endif
+        endef
+
+        define toolchain-determine
+                $$(foreach tool-class,$$(tool-classes), \
+                        $$(eval $$(call toolchain-determine-tool,$(1),$$(tool-class))))
+        endef
+
+        $(foreach toolchain,$(toolchains), \
+                $(eval $(call toolchain-determine,$(toolchain))))
+endif
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
index 93e1fcc..fa7722a 100644
--- a/make_helpers/unix.mk
+++ b/make_helpers/unix.mk
@@ -9,9 +9,6 @@
 ifndef UNIX_MK
     UNIX_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := echo
-    ECHO_QUIET := @\#
-
     DIR_DELIM := /
     PATH_SEP := :
 
@@ -21,40 +18,28 @@
     # ${1} is the file to be copied.
     # ${2} is the destination file name.
     define SHELL_COPY
-	${Q}cp -f  "${1}"  "${2}"
+	$(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}"
+	$(q)cp -rf  "${1}"  "${2}"
     endef
 
     # ${1} is the file to be deleted.
     define SHELL_DELETE
-	-${Q}rm -f  "${1}"
+	-$(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
-
-    # ${1} is the directory to be generated.
-    # ${2} is optional, and allows a prerequisite to be specified.
-    # Do nothing if $1 == $2, to ignore self dependencies.
-    define MAKE_PREREQ_DIR
-        ifneq (${1},${2})
-
-${1} : ${2}
-	${Q}mkdir -p  "${1}"
-
-        endif
+	-$(q)rm -rf  ${1}
     endef
 
     define SHELL_REMOVE_DIR
-	-${Q}rm -rf  "${1}"
+	-$(q)rm -rf  "${1}"
     endef
 
     nul := /dev/null
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
index 62769fb..45ef12e 100644
--- a/make_helpers/utilities.mk
+++ b/make_helpers/utilities.mk
@@ -20,3 +20,83 @@
 directory-name = $(call decompat-path,$(dir $(call compat-path,$(1))))
 
 escape-shell = '$(subst ','\'',$(1))'
+
+#
+# Upper-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to upper-case.
+#
+# Example usage:
+#
+#     $(call uppercase,HeLlO wOrLd) # "HELLO WORLD"
+#
+
+uppercase = $(shell echo $(call escape-shell,$(1)) | tr '[:lower:]' '[:upper:]')
+
+#
+# Lower-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to lower-case.
+#
+# Example usage:
+#
+#     $(call lowercase,HeLlO wOrLd) # "hello world"
+#
+
+lowercase = $(shell echo $(call escape-shell,$(1)) | tr '[:upper:]' '[:lower:]')
+
+#
+# Determine the "truthiness" of a value.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "y"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # <empty>
+#
+
+bool = $(filter-out 0 n no f false,$(call lowercase,$(1)))
+
+#
+# Determine the "truthiness" of a value, returning 0 or 1.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "1"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # "0"
+#
+
+bool-01 = $(if $(call bool,$(1)),1,0)
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index de34eaf..c24aa08 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -12,8 +12,6 @@
 ifndef WINDOWS_MK
     WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := @cmd /c echo.
-    ECHO_QUIET := @rem
     DIR_DELIM := $(strip \)
     BIN_EXT   := .exe
     PATH_SEP  := ;
@@ -49,19 +47,6 @@
 	$(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
     endef
 
-    # ${1} is the directory to be generated.
-    # ${2} is optional, and allows prerequisites to be specified.
-    # Do nothing if $1 == $2, to ignore self dependencies.
-    define MAKE_PREREQ_DIR
-        ifneq (${1},${2})
-
-${1} : ${2}
-	$(eval tmp_dir:=$(subst /,\,${1}))
-	-@if not exist "$(tmp_dir)"  mkdir "${tmp_dir}"
-
-        endif
-    endef
-
     # ${1} is the directory to be removed.
     define SHELL_REMOVE_DIR
 	$(eval tmp_dir:=$(subst /,\,${1}))
diff --git a/package-lock.json b/package-lock.json
index e60c44e..26caae4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
+  "version": "2.11.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.10.0",
+      "version": "2.11.0",
       "license": "BSD-3-Clause",
       "devDependencies": {
         "@commitlint/cli": "^19.0.0",
@@ -1172,12 +1172,12 @@
       }
     },
     "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
       "dev": true,
       "dependencies": {
-        "fill-range": "^7.0.1"
+        "fill-range": "^7.1.1"
       },
       "engines": {
         "node": ">=8"
@@ -2395,9 +2395,9 @@
       }
     },
     "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
       "dev": true,
       "dependencies": {
         "to-regex-range": "^5.0.1"
@@ -4903,7 +4903,7 @@
       }
     },
     "tools/conventional-changelog-tf-a": {
-      "version": "2.10.0",
+      "version": "2.11.0",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
diff --git a/package.json b/package.json
index 7ad5c58..e4c6475 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
+  "version": "2.11.0",
   "license": "BSD-3-Clause",
   "type": "module",
   "private": true,
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6a38657..b9ca3f6 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -58,4 +58,12 @@
 }
 #endif
 
+#ifdef PLAT_sun50i_h616
+void sunxi_soc_fdt_fixup(void *dtb);
+#else
+static inline void sunxi_soc_fdt_fixup(void *dtb)
+{
+}
+#endif
+
 #endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 24edd79..263083b 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -14,7 +14,6 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
diff --git a/plat/allwinner/common/sunxi_prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
index 66af35a..0f68974 100644
--- a/plat/allwinner/common/sunxi_prepare_dtb.c
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -34,6 +34,8 @@
 	}
 #endif
 
+	sunxi_soc_fdt_fixup(fdt);
+
 	if (sunxi_psci_is_scpi()) {
 		ret = fdt_add_cpu_idle_states(fdt, sunxi_idle_states);
 		if (ret < 0) {
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
index de494a2..6f44e8c 100644
--- a/plat/allwinner/sun50i_h616/platform.mk
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -18,5 +18,8 @@
     $(error "H616 does not support SCPI PSCI ops")
 endif
 
-BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
+BL31_SOURCES		+=	common/fdt_wrappers.c			\
+				drivers/allwinner/axp/axp805.c		\
 				drivers/allwinner/sunxi_rsb.c		\
+				drivers/mentor/i2c/mi2cv.c		\
+				${AW_PLAT}/${PLAT}/sunxi_h616_dtb.c
diff --git a/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c b/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
new file mode 100644
index 0000000..58bad53
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Amend the device tree to adjust the L2 cache size, which is different
+ * between the revisions of the H616 chips: earlier versions have 256 KB of L2,
+ * later versions 1 MB.
+ * Read the cache ID registers and adjust the size and number of sets entries
+ * in the L2 cache DT node.
+ */
+
+#include <common/fdt_wrappers.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#define CACHE_L1D		0x0
+#define CACHE_L1I		0x1
+#define CACHE_L2U		0x2
+
+#define CCSIDR_SETS_SHIFT	13
+#define CCSIDR_SETS_MASK	GENMASK(14, 0)
+#define CCSIDR_ASSOC_SHIFT	3
+#define CCSIDR_ASSOC_MASK	GENMASK(9, 0)
+#define CCSIDR_LSIZE_SHIFT	0
+#define CCSIDR_LSIZE_MASK	GENMASK(2, 0)
+
+static uint32_t armv8_get_ccsidr(unsigned int sel)
+{
+	uint32_t reg;
+
+	__asm__ volatile ("msr CSSELR_EL1, %0\n" :: "r" (sel));
+	__asm__ volatile ("mrs %0, CCSIDR_EL1\n" : "=r" (reg));
+
+	return reg;
+}
+
+void sunxi_soc_fdt_fixup(void *dtb)
+{
+	int node = fdt_path_offset(dtb, "/cpus/cpu@0");
+	uint32_t phandle, ccsidr, cell;
+	int sets, line_size, assoc;
+	int ret;
+
+	if (node < 0) {
+		return;
+	}
+
+	ret = fdt_read_uint32(dtb, node, "next-level-cache", &phandle);
+	if (ret != 0) {
+		return;
+	}
+
+	node = fdt_node_offset_by_phandle(dtb, phandle);
+	if (node < 0) {
+		return;
+	}
+
+	ccsidr = armv8_get_ccsidr(CACHE_L2U);
+	sets = ((ccsidr >> CCSIDR_SETS_SHIFT) & CCSIDR_SETS_MASK) + 1;
+	line_size = 16U << ((ccsidr >> CCSIDR_LSIZE_SHIFT) & CCSIDR_LSIZE_MASK);
+	assoc = ((ccsidr >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK) + 1;
+
+	cell = cpu_to_fdt32(sets);
+	fdt_setprop(dtb, node, "cache-sets", &cell, sizeof(cell));
+
+	cell = cpu_to_fdt32(line_size);
+	fdt_setprop(dtb, node, "cache-line-size", &cell, sizeof(cell));
+
+	cell = cpu_to_fdt32(sets * assoc * line_size);
+	fdt_setprop(dtb, node, "cache-size", &cell, sizeof(cell));
+}
diff --git a/plat/allwinner/sun50i_h616/sunxi_power.c b/plat/allwinner/sun50i_h616/sunxi_power.c
index dd6ebba..cab7e46 100644
--- a/plat/allwinner/sun50i_h616/sunxi_power.c
+++ b/plat/allwinner/sun50i_h616/sunxi_power.c
@@ -10,97 +10,254 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <drivers/mentor/mi2cv.h>
 #include <lib/mmio.h>
+#include <libfdt.h>
 
 #include <sunxi_cpucfg.h>
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
-#define AXP305_I2C_ADDR	0x36
-#define AXP305_HW_ADDR	0x745
-#define AXP305_RT_ADDR	0x3a
+static uint16_t pmic_bus_addr;
+static uint8_t rsb_rt_addr;
+
+static bool is_using_rsb(void)
+{
+	return rsb_rt_addr != 0;
+}
 
 static enum pmic_type {
 	UNKNOWN,
 	AXP305,
+	AXP313,
+	AXP717,
 } pmic;
 
+static uint8_t get_rsb_rt_address(uint16_t hw_addr)
+{
+	switch (hw_addr) {
+	case 0x3a3: return 0x2d;
+	case 0x745: return 0x3a;
+	}
+
+	return 0;
+}
+
 int axp_read(uint8_t reg)
 {
-	return rsb_read(AXP305_RT_ADDR, reg);
+	uint8_t val;
+	int ret;
+
+	if (is_using_rsb()) {
+		return rsb_read(rsb_rt_addr, reg);
+	}
+
+	ret = i2c_write(pmic_bus_addr, 0, 0, &reg, 1);
+	if (ret == 0) {
+		ret = i2c_read(pmic_bus_addr, 0, 0, &val, 1);
+	}
+	if (ret) {
+		ERROR("PMIC: Cannot read PMIC register %02x\n", reg);
+		return ret;
+	}
+
+	return val;
 }
 
 int axp_write(uint8_t reg, uint8_t val)
 {
-	return rsb_write(AXP305_RT_ADDR, reg, val);
+	int ret;
+
+	if (is_using_rsb()) {
+		return rsb_write(rsb_rt_addr, reg, val);
+	}
+
+	ret = i2c_write(pmic_bus_addr, reg, 1, &val, 1);
+	if (ret) {
+		ERROR("PMIC: Cannot write PMIC register %02x\n", reg);
+	}
+
+	return ret;
 }
 
-static int rsb_init(void)
+static int rsb_init(int rsb_hw_addr)
 {
 	int ret;
 
 	ret = rsb_init_controller();
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Switch to the recommended 3 MHz bus clock. */
 	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Initiate an I2C transaction to switch the PMIC to RSB mode. */
 	ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Associate the 8-bit runtime address with the 12-bit bus address. */
-	ret = rsb_assign_runtime_address(AXP305_HW_ADDR, AXP305_RT_ADDR);
-	if (ret)
+	ret = rsb_assign_runtime_address(rsb_hw_addr, rsb_rt_addr);
+	if (ret) {
 		return ret;
+	}
 
-	return axp_check_id();
+	return 0;
+}
+
+static int pmic_bus_init(uint16_t socid, uint16_t rsb_hw_addr)
+{
+	int ret;
+
+	ret = sunxi_init_platform_r_twi(socid, is_using_rsb());
+	if (ret) {
+		INFO("Could not init platform bus: %d\n", ret);
+		pmic = UNKNOWN;
+		return ret;
+	}
+
+	if (is_using_rsb()) {
+		ret = rsb_init(rsb_hw_addr);
+		if (ret) {
+			pmic = UNKNOWN;
+			return ret;
+		}
+	} else {
+		/* initialise mi2cv driver */
+		i2c_init((void *)SUNXI_R_I2C_BASE);
+	}
+
+	return 0;
 }
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
-	int ret;
+	int node, parent, ret;
+	uint32_t reg;
 
-	INFO("PMIC: Probing AXP305 on RSB\n");
+	node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp806");
+	if (node >= 0) {
+		pmic = AXP305;
+	}
 
-	ret = sunxi_init_platform_r_twi(socid, true);
+	if (pmic == UNKNOWN) {
+		node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp313a");
+		if (node >= 0) {
+			pmic = AXP313;
+		}
+	}
+
+	if (pmic == UNKNOWN) {
+		node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp717");
+		if (node >= 0) {
+			pmic = AXP717;
+		}
+	}
+
+	if (pmic == UNKNOWN) {
+		INFO("PMIC: No known PMIC in DT, skipping setup.\n");
+		return -ENODEV;
+	}
+
+	if (fdt_read_uint32(fdt, node, "reg", &reg)) {
+		ERROR("PMIC: PMIC DT node does not contain reg property.\n");
+		return -EINVAL;
+	}
+
+	pmic_bus_addr = reg;
+	parent = fdt_parent_offset(fdt, node);
+	ret = fdt_node_check_compatible(fdt, parent, "allwinner,sun8i-a23-rsb");
+	if (ret == 0) {
+		rsb_rt_addr = get_rsb_rt_address(pmic_bus_addr);
+		if (rsb_rt_addr == 0) {
+			ERROR("PMIC: no mapping for RSB address 0x%x\n",
+			      pmic_bus_addr);
+			return -EINVAL;
+		}
+	}
+
+	INFO("Probing for PMIC on %s:\n", is_using_rsb() ? "RSB" : "I2C");
+
+	ret = pmic_bus_init(socid, pmic_bus_addr);
 	if (ret) {
-		INFO("Could not init platform bus: %d\n", ret);
 		return ret;
 	}
 
-	ret = rsb_init();
-	if (ret) {
-		INFO("Could not init RSB: %d\n", ret);
-		return ret;
+	ret = axp_read(0x03);
+	switch (ret & 0xcf) {
+	case 0x40:				/* AXP305 */
+		if (pmic == AXP305) {
+			INFO("PMIC: found AXP305, setting up regulators\n");
+			axp_setup_regulators(fdt);
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
+	case 0x48:				/* AXP1530 */
+	case 0x4b:				/* AXP313A */
+	case 0x4c:				/* AXP313B */
+		if (pmic == AXP313) {
+			INFO("PMIC: found AXP313\n");
+			/* no regulators to set up */
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
+	case 0xcf:		/* version reg not implemented on AXP717 */
+		if (pmic == AXP717) {
+			INFO("PMIC: found AXP717\n");
+			/* no regulators to set up, U-Boot takes care of this */
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
 	}
 
-	pmic = AXP305;
-	axp_setup_regulators(fdt);
+	if (is_using_rsb()) {
+		/* Switch the PMIC back to I2C mode. */
+		return rsb_write(rsb_rt_addr, AXP20X_MODE_REG, AXP20X_MODE_I2C);
+	}
 
-	/* Switch the PMIC back to I2C mode. */
-	ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
-	if (ret)
-		return ret;
+	if (pmic == UNKNOWN) {
+		INFO("Incompatible or unknown PMIC found.\n");
+		return -ENODEV;
+	}
 
 	return 0;
 }
 
 void sunxi_power_down(void)
 {
+	int ret;
+
+	if (pmic == UNKNOWN) {
+		return;
+	}
+
+	/* Re-initialise after rich OS might have used it. */
+	ret = pmic_bus_init(SUNXI_SOC_H616, pmic_bus_addr);
+	if (ret) {
+		return;
+	}
+
 	switch (pmic) {
 	case AXP305:
-		/* Re-initialise after rich OS might have used it. */
-		sunxi_init_platform_r_twi(SUNXI_SOC_H616, true);
-		rsb_init();
-		axp_power_off();
+		axp_setbits(0x32, BIT(7));
+		break;
+	case AXP313:
+		axp_setbits(0x1a, BIT(7));
+		break;
+	case AXP717:
+		axp_setbits(0x27, BIT(0));
 		break;
 	default:
 		break;
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
new file mode 100644
index 0000000..3ab3dca
--- /dev/null
+++ b/plat/amd/versal2/aarch64/common.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <def.h>
+#include <plat_common.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+uint32_t platform_id, platform_version;
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	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)
+	MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_BASE + FW_HANDOFF_SIZE,
+			MT_MEMORY | MT_RW | MT_NS),
+#endif
+	{ 0 }
+};
+
+const mmap_region_t *plat_get_mmap(void)
+{
+	return plat_mmap;
+}
+
+/* For saving cpu clock for certain platform */
+uint32_t cpu_clock;
+
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case SPP:
+		platform = "IPP";
+		break;
+	case EMU:
+		platform = "EMU";
+		break;
+	case SILICON:
+		platform = "Silicon";
+		break;
+	case QEMU:
+		platform = "QEMU";
+		break;
+	default:
+		platform = "Unknown";
+	}
+
+	return platform;
+}
+
+void board_detection(void)
+{
+	uint32_t version;
+
+	version = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+
+	if (platform_id == QEMU_COSIM) {
+		platform_id = QEMU;
+	}
+
+	/* Make sure that console is setup to see this message */
+	VERBOSE("Platform id: %d version: %d.%d\n", platform_id,
+		platform_version / 10U, platform_version % 10U);
+}
+
+uint32_t get_uart_clk(void)
+{
+	uint32_t uart_clock = 0;
+
+	switch (platform_id) {
+	case SPP:
+	case SPP_MMD:
+		uart_clock = cpu_clock;
+		break;
+	case EMU:
+	case EMU_MMD:
+		uart_clock = 25000000;
+		break;
+	case QEMU:
+		/* Random values now */
+		uart_clock = 25000000;
+		break;
+	case SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
+}
+
+void config_setup(void)
+{
+	uint32_t val;
+	uintptr_t crl_base, iou_scntrs_base, psx_base;
+
+	crl_base = CRL;
+	iou_scntrs_base = IOU_SCNTRS;
+	psx_base = PSX_CRF;
+
+	/* Reset for system timestamp generator in FPX */
+	mmio_write_32(psx_base + PSX_CRF_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Global timer init - Program time stamp reference clk */
+	val = mmio_read_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET);
+	val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+	mmio_write_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET, val);
+
+	/* Clear reset of timestamp reg */
+	mmio_write_32(crl_base + CRL_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Program freq register in System counter and enable system counter. */
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_BASE_FREQ_OFFSET,
+		      cpu_clock);
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
+		      IOU_SCNTRS_CONTROL_EN);
+
+	generic_delay_timer_init();
+
+	/* Configure IPI data */
+	soc_ipi_config_table_init();
+}
+
+uint32_t plat_get_syscnt_freq2(void)
+{
+	return cpu_clock;
+}
diff --git a/plat/amd/versal2/aarch64/helpers.S b/plat/amd/versal2/aarch64/helpers.S
new file mode 100644
index 0000000..580bb76
--- /dev/null
+++ b/plat/amd/versal2/aarch64/helpers.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/gicv3.h>
+
+#include <platform_def.h>
+
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_is_my_cpu_primary
+	.globl	platform_mem_init
+	.globl	plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * TODO: Should we read the PSYS register to make sure
+	 * that the request has gone through.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	mrs	x0, mpidr_el1
+
+	/*
+	 * There is no sane reason to come out of this wfi. This
+	 * cpu will be powered on and reset by the cpu_on pm api
+	 */
+	dsb	sy
+	bl	plat_panic_handler
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+	mov	x9, x30
+	bl	plat_my_core_pos
+	cmp	x0, #PRIMARY_CPU
+	cset	x0, eq
+	ret	x9
+endfunc plat_is_my_cpu_primary
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_core_pos_by_mpidr()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on platform
+	 * The Secure RAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
new file mode 100644
index 0000000..e878863
--- /dev/null
+++ b/plat/amd/versal2/bl31_setup.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/dcc.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+#include <scmi.h>
+
+#include <def.h>
+#include <plat_fdt.h>
+#include <plat_private.h>
+#include <plat_startup.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/*
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	}
+
+	return &bl32_image_ep_info;
+}
+
+/*
+ * Set the build time defaults,if we can't find any config data.
+ */
+static inline void bl31_set_default_config(void)
+{
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+#if defined(SPD_opteed)
+	/* NS dtb addr passed to optee_os */
+	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,
+					  DISABLE_ALL_EXCEPTIONS);
+}
+
+/*
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables.
+ */
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	uint32_t uart_clock;
+	int32_t rc;
+
+	board_detection();
+
+	/* FIXME */
+	switch (platform_id) {
+	case SPP:
+		switch (platform_version) {
+		case SPP_PSXC_MMI_V2_0:
+			cpu_clock = 770000;
+			break;
+		case SPP_PSXC_MMI_V3_0:
+			cpu_clock = 908000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case SPP_MMD:
+		switch (platform_version) {
+		case SPP_PSXC_ISP_AIE_V2_0:
+		case SPP_PSXC_MMD_AIE_FRZ_EA:
+		case SPP_PSXC_MMD_AIE_V3_0:
+			cpu_clock = 760000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case EMU:
+	case EMU_MMD:
+		cpu_clock = 112203;
+		break;
+	case QEMU:
+		/* Random values now */
+		cpu_clock = 3333333;
+		break;
+	case SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	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 */
+	}
+
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
+	       platform_version / 10U, platform_version % 10U);
+
+	/* Initialize the platform config for future decision making */
+	config_setup();
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+
+	/* Populate common information for BL32 and BL33 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	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();
+
+	long rev_var = cpu_get_rev_var();
+
+	INFO("CPU Revision = 0x%lx\n", rev_var);
+	INFO("cpu_clock = %dHz, uart_clock = %dHz\n", cpu_clock, uart_clock);
+	NOTICE("BL31: Executing from 0x%x\n", BL31_BASE);
+	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
+	NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
+
+}
+
+static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
+
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+{
+	static uint32_t index;
+	uint32_t i;
+
+	/* Validate 'handler' and 'id' parameters */
+	if (handler == NULL || index >= MAX_INTR_EL3) {
+		return -EINVAL;
+	}
+
+	/* Check if a handler has already been registered */
+	for (i = 0; i < index; i++) {
+		if (id == type_el3_interrupt_table[i].id) {
+			return -EALREADY;
+		}
+	}
+
+	type_el3_interrupt_table[index].id = id;
+	type_el3_interrupt_table[index].handler = handler;
+
+	index++;
+
+	return 0;
+}
+
+static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
+					  void *handle, void *cookie)
+{
+	uint32_t intr_id;
+	uint32_t i;
+	interrupt_type_handler_t handler = NULL;
+
+	intr_id = plat_ic_get_pending_interrupt_id();
+
+	for (i = 0; i < MAX_INTR_EL3; i++) {
+		if (intr_id == type_el3_interrupt_table[i].id) {
+			handler = type_el3_interrupt_table[i].handler;
+		}
+	}
+
+	if (handler != NULL) {
+		(void)handler(intr_id, flags, handle, cookie);
+	}
+
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	prepare_dtb();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	if (platform_id != EMU) {
+		init_scmi_server();
+	}
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	uint64_t flags = 0;
+	int32_t rc;
+
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     rdo_el3_interrupt_handler, flags);
+	if (rc != 0) {
+		panic();
+	}
+}
+
+/*
+ * Perform the very early platform specific architectural setup here.
+ */
+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,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+				MT_RO_DATA | MT_SECURE),
+		MAP_REGION_FLAT(SMT_BUFFER_BASE, 0x1000,
+			MT_DEVICE | MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER | MT_NS),
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_get_mmap());
+	enable_mmu(0);
+}
diff --git a/plat/amd/versal2/gicv3.c b/plat/amd/versal2/gicv3.c
new file mode 100644
index 0000000..c7b44e1
--- /dev/null
+++ b/plat/amd/versal2/gicv3.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+
+/******************************************************************************
+ * The following functions are defined as weak to allow a platform to override
+ * the way the GICv3 driver is initialised and used.
+ *****************************************************************************/
+#pragma weak plat_gic_driver_init
+#pragma weak plat_gic_init
+#pragma weak plat_gic_cpuif_enable
+#pragma weak plat_gic_cpuif_disable
+#pragma weak plat_gic_pcpu_init
+#pragma weak plat_gic_redistif_on
+#pragma weak plat_gic_redistif_off
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static const interrupt_prop_t _interrupt_props[] = {
+	PLAT_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * We save and restore the GICv3 context on system suspend. Allocate the
+ * data in the designated EL3 Secure carve-out memory.
+ */
+static gicv3_redist_ctx_t rdist_ctx __section("._el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section("._el3_tzc_dram");
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ *   - No CPUs implemented in the system use affinity level 3.
+ */
+static uint32_t _gicv3_mpidr_hash(u_register_t mpidr)
+{
+	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t _gic_data __unused = {
+	.gicd_base = PLAT_GICD_BASE_VALUE,
+	.gicr_base = PLAT_GICR_BASE_VALUE,
+	.interrupt_props = _interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+	.mpidr_to_core_pos = _gicv3_mpidr_hash
+};
+
+void __init plat_gic_driver_init(void)
+{
+	/*
+	 * The GICv3 driver is initialized in EL3 and does not need
+	 * to be initialized again in SEL1. This is because the S-EL1
+	 * can use GIC system registers to manage interrupts and does
+	 * not need GIC interface base addresses to be configured.
+	 */
+#if IMAGE_BL31
+	gicv3_driver_init(&_gic_data);
+#endif
+}
+
+/******************************************************************************
+ * common helper to initialize the GIC. Only invoked by BL31
+ *****************************************************************************/
+void __init plat_gic_init(void)
+{
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to enable the GIC CPU interface
+ *****************************************************************************/
+void plat_gic_cpuif_enable(void)
+{
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to disable the GIC CPU interface
+ *****************************************************************************/
+void plat_gic_cpuif_disable(void)
+{
+	gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to initialize the per-cpu redistributor interface in GICv3
+ *****************************************************************************/
+void plat_gic_pcpu_init(void)
+{
+	gicv3_rdistif_init(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helpers to power GIC redistributor interface
+ *****************************************************************************/
+void plat_gic_redistif_on(void)
+{
+	gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_gic_redistif_off(void)
+{
+	gicv3_rdistif_off(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * common helper to save & restore the GICv3 on resume from system suspend
+ *****************************************************************************/
+void plat_gic_save(void)
+{
+	/*
+	 * If an ITS is available, save its context before
+	 * the Redistributor using:
+	 * gicv3_its_save_disable(gits_base, &its_ctx[i])
+	 * Additionnaly, an implementation-defined sequence may
+	 * be required to save the whole ITS state.
+	 */
+
+	/*
+	 * Save the GIC Redistributors and ITS contexts before the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to save the context of the CPU that is issuing
+	 * the SYSTEM SUSPEND call, i.e. the current CPU.
+	 */
+	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+
+	/* Save the GIC Distributor context */
+	gicv3_distif_save(&dist_ctx);
+
+	/*
+	 * From here, all the components of the GIC can be safely powered down
+	 * as long as there is an alternate way to handle wakeup interrupt
+	 * sources.
+	 */
+}
+
+void plat_gic_resume(void)
+{
+	/* Restore the GIC Distributor context */
+	gicv3_distif_init_restore(&dist_ctx);
+
+	/*
+	 * Restore the GIC Redistributor and ITS contexts after the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to restore the context of the CPU that issued
+	 * the SYSTEM SUSPEND call.
+	 */
+	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+
+	/*
+	 * If an ITS is available, restore its context after
+	 * the Redistributor using:
+	 * gicv3_its_restore(gits_base, &its_ctx[i])
+	 * An implementation-defined sequence may be required to
+	 * restore the whole ITS state. The ITS must also be
+	 * re-enabled after this sequence has been executed.
+	 */
+}
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
new file mode 100644
index 0000000..a8cbaaf
--- /dev/null
+++ b/plat/amd/versal2/include/def.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEF_H
+#define DEF_H
+
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+#define MAX_INTR_EL3			2
+
+/* 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 CONSOLE_IS(con)	(CONSOLE_ID_ ## con == CONSOLE)
+
+/* List all platforms */
+#define SILICON		U(0)
+#define SPP			U(1)
+#define EMU			U(2)
+#define QEMU			U(3)
+#define SPP_MMD			U(5)
+#define EMU_MMD			U(6)
+#define QEMU_COSIM		U(7)
+
+/* For platform detection */
+#define PMC_TAP				U(0xF11A0000)
+#define PMC_TAP_VERSION			(PMC_TAP + 0x4U)
+# define PLATFORM_MASK			GENMASK(27U, 24U)
+# define PLATFORM_VERSION_MASK		GENMASK(31U, 28U)
+
+/* Global timer reset */
+#define PSX_CRF			U(0xEC200000)
+#define ACPU0_CLK_CTRL		U(0x10C)
+#define ACPU_CLK_CTRL_CLKACT	BIT(25)
+
+#define RST_APU0_OFFSET		U(0x300)
+#define RST_APU_COLD_RESET	BIT(0)
+#define RST_APU_WARN_RESET	BIT(4)
+#define RST_APU_CLUSTER_COLD_RESET	BIT(8)
+#define RST_APU_CLUSTER_WARM_RESET	BIT(9)
+
+#define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
+
+#define APU_PCLI			(0xECB10000ULL)
+#define APU_PCLI_CPU_STEP		(0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4ULL * APU_PCLI_CPU_STEP)
+#define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
+#define APU_PCLI_CLUSTER_STEP		U(0x1000)
+#define PCLI_PREQ_OFFSET		U(0x4)
+#define PREQ_CHANGE_REQUEST		BIT(0)
+#define PCLI_PSTATE_OFFSET		U(0x8)
+#define PCLI_PSTATE_VAL_SET		U(0x48)
+#define PCLI_PSTATE_VAL_CLEAR		U(0x38)
+
+/* Firmware Image Package */
+#define PRIMARY_CPU		U(0)
+
+#define CORE_0_ISR_WAKE_OFFSET			(0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK		(0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET			(0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK		(0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET			(0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK		(0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET			(0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK		U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018ULL)
+#define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CULL)
+#define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
+#define CORE_PWRDN_EN_BIT_MASK			(0x1U)
+
+/*******************************************************************************
+ * memory map related constants
+ ******************************************************************************/
+/* IPP 1.2/SPP 0.9 mapping */
+#define DEVICE0_BASE		U(0xE8000000) /* psx, crl, iou */
+#define DEVICE0_SIZE		U(0x08000000)
+#define DEVICE1_BASE		U(0xE2000000) /* gic */
+#define DEVICE1_SIZE		U(0x00800000)
+#define DEVICE2_BASE		U(0xF1000000) /* uart, pmc_tap */
+#define DEVICE2_SIZE		U(0x01000000)
+#define CRF_BASE		U(0xFD1A0000)
+#define CRF_SIZE		U(0x00600000)
+#define IPI_BASE		U(0xEB300000)
+#define IPI_SIZE		U(0x00100000)
+
+/* CRL */
+#define CRL					U(0xEB5E0000)
+#define CRL_TIMESTAMP_REF_CTRL_OFFSET	U(0x14C)
+#define CRL_RST_TIMESTAMP_OFFSET		U(0x348)
+
+#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	(1U << 25U)
+
+/* IOU SCNTRS */
+#define IOU_SCNTRS					U(0xEC920000)
+#define IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET			U(0x20)
+
+#define IOU_SCNTRS_CONTROL_EN	U(1)
+
+#define APU_CLUSTER0		U(0xECC00000)
+#define APU_RVBAR_L_0		U(0x40)
+#define APU_RVBAR_H_0		U(0x44)
+#define APU_CLUSTER_STEP	U(0x100000)
+
+#define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+
+/*******************************************************************************
+ * IRQ constants
+ ******************************************************************************/
+#define IRQ_SEC_PHY_TIMER	U(29)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE		U(0xF1920000)
+#define UART1_BASE		U(0xF1930000)
+
+#define UART_BAUDRATE	115200
+
+#if CONSOLE_IS(pl011_1)
+#define UART_BASE		UART1_BASE
+#else
+/* Default console is UART0 */
+#define UART_BASE            UART0_BASE
+#endif
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/plat_ipi.h b/plat/amd/versal2/include/plat_ipi.h
new file mode 100644
index 0000000..503ec1f
--- /dev/null
+++ b/plat/amd/versal2/include/plat_ipi.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal Gen 2 IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_PMC	1U
+#define IPI_ID_APU	2U
+#define IPI_ID_RPU0	3U
+#define IPI_ID_RPU1	4U
+#define IPI_ID_3	5U
+#define IPI_ID_4	6U
+#define IPI_ID_5	7U
+#define IPI_ID_MAX	8U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
+
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMC
+
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + (IPI_LOCAL_ID * 0x200U))
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + (IPI_REMOTE_ID * 0x200U))
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	(IPI_LOCAL_ID * 0x40U)
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	(IPI_REMOTE_ID * 0x40U)
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table */
+extern void soc_ipi_config_table_init(void);
+
+/*******************************************************************************
+ * IPI registers and bitfields
+ ******************************************************************************/
+#define IPI0_REG_BASE		(0xEB330000U)
+#define IPI0_TRIG_BIT		(1 << 2)
+#define PMC_IPI_TRIG_BIT	(1 << 1)
+#define IPI1_REG_BASE		(0xEB340000U)
+#define IPI1_TRIG_BIT		(1 << 3)
+#define IPI2_REG_BASE		(0xEB350000U)
+#define IPI2_TRIG_BIT		(1 << 4)
+#define IPI3_REG_BASE		(0xEB360000U)
+#define IPI3_TRIG_BIT		(1 << 5)
+#define IPI4_REG_BASE		(0xEB370000U)
+#define IPI4_TRIG_BIT		(1 << 6)
+#define IPI5_REG_BASE		(0xEB380000U)
+#define IPI5_TRIG_BIT		(1 << 7)
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/amd/versal2/include/plat_macros.S b/plat/amd/versal2/include/plat_macros.S
new file mode 100644
index 0000000..d20f693
--- /dev/null
+++ b/plat/amd/versal2/include/plat_macros.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include "../include/platform_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+	.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * The below utility macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL31 on platform.
+	 * Expects: GICD base in x16, GICC base in x17
+	 * Clobbers: x0 - x10, sp
+	 * ---------------------------------------------
+	 */
+	.macro _print_gic_regs
+	/* Check for GICv3 system register access */
+	mrs	x7, id_aa64pfr0_el1
+	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+	cmp	x7, #1
+	b.ne	print_gicv2
+
+	/* Check for SRE enable */
+	mrs	x8, ICC_SRE_EL3
+	tst	x8, #ICC_SRE_SRE_BIT
+	b.eq	print_gicv2
+
+	/* Load the icc reg list to x6 */
+	adr	x6, icc_regs
+	/* Load the icc regs to gp regs used by str_in_crash_buf_print */
+	mrs	x8, ICC_HPPIR0_EL1
+	mrs	x9, ICC_HPPIR1_EL1
+	mrs	x10, ICC_CTLR_EL3
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	b	print_gic_common
+
+print_gicv2:
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+print_gic_common:
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant GIC and CCI registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/*
+	 * Empty for now to handle more platforms variant.
+	 * Uncomment it when versions are stable
+	 */
+	/*
+	mov_imm	x17, PLAT_GICD_BASE_VALUE
+	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	_print_gic_regs
+	*/
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/amd/versal2/include/plat_pm_common.h b/plat/amd/versal2/include/plat_pm_common.h
new file mode 100644
index 0000000..5e68472
--- /dev/null
+++ b/plat/amd/versal2/include/plat_pm_common.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include "pm_defs.h"
+
+#define NON_SECURE_FLAG		1U
+#define SECURE_FLAG		0U
+
+#endif /* PLAT_PM_COMMON_H */
diff --git a/plat/amd/versal2/include/plat_private.h b/plat/amd/versal2/include/plat_private.h
new file mode 100644
index 0000000..5a2e5bd
--- /dev/null
+++ b/plat/amd/versal2/include/plat_private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define SPP_PSXC_MMI_V2_0	U(6)
+#define SPP_PSXC_MMI_V3_0	U(8)
+
+/* MMD */
+#define SPP_PSXC_ISP_AIE_V2_0	U(3)
+#define SPP_PSXC_MMD_AIE_FRZ_EA	U(4)
+#define SPP_PSXC_MMD_AIE_V3_0	U(5)
+
+typedef struct versal_intr_info_type_el3 {
+	uint32_t id;
+	interrupt_type_handler_t handler;
+} versal_intr_info_type_el3_t;
+
+void config_setup(void);
+uint32_t get_uart_clk(void);
+
+const mmap_region_t *plat_get_mmap(void);
+
+void plat_gic_driver_init(void);
+void plat_gic_init(void);
+void plat_gic_cpuif_enable(void);
+void plat_gic_cpuif_disable(void);
+void plat_gic_pcpu_init(void);
+void plat_gic_save(void);
+void plat_gic_resume(void);
+void plat_gic_redistif_on(void);
+void plat_gic_redistif_off(void);
+
+extern uint32_t cpu_clock, platform_id, platform_version;
+void board_detection(void);
+const char *board_name_decode(void);
+uint64_t 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);
+int32_t sip_svc_setup_init(void);
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
new file mode 100644
index 0000000..090fe46
--- /dev/null
+++ b/plat/amd/versal2/include/platform_def.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include "def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		U(0x440)
+
+#define PLATFORM_CLUSTER_COUNT		U(4)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	U(2) /* 2 CPUs per cluster */
+
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#ifndef MEM_BASE
+# define BL31_BASE			U(0xBBF00000)
+# define BL31_LIMIT			U(0xBC000000)
+#else
+# define BL31_BASE			U(MEM_BASE)
+# define BL31_LIMIT			U(MEM_BASE + MEM_SIZE)
+# ifdef MEM_PROGBITS_SIZE
+#  define BL31_PROGBITS_LIMIT		U(MEM_BASE + \
+					  MEM_PROGBITS_SIZE)
+# endif
+#endif
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#ifndef BL32_MEM_BASE
+# define BL32_BASE			U(0x60000000)
+# define BL32_LIMIT			U(0x80000000)
+#else
+# define BL32_BASE			U(BL32_MEM_BASE)
+# define BL32_LIMIT			U(BL32_MEM_BASE + BL32_MEM_SIZE)
+#endif
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#ifndef PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
+#else
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
+#endif
+
+/*******************************************************************************
+ * TSP  specific defines.
+ ******************************************************************************/
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
+/* ID of the secure physical generic timer interrupt used by the TSP */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+#define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
+
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+
+#define PLAT_OCM_BASE			U(0xBBF00000)
+#define PLAT_OCM_LIMIT			U(0xBC000000)
+
+#if defined(TRANSFER_LIST)
+/*
+ * FIXME: This address should come from firmware before TF-A
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE         U(0x70000000)
+#define FW_HANDOFF_SIZE         U(0x10000)
+#endif
+
+#define IS_TFA_IN_OCM(x)	((x >= PLAT_OCM_BASE) && (x < PLAT_OCM_LIMIT))
+
+#ifndef MAX_MMAP_REGIONS
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+#define MAX_MMAP_REGIONS		11
+#else
+#define MAX_MMAP_REGIONS		10
+#endif
+#endif
+
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES			U(12)
+#endif
+
+#define CACHE_WRITEBACK_SHIFT	U(6)
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
+#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_IPI_IRQ	89
+#define PLAT_VERSAL_IPI_IRQ	PLAT_IPI_IRQ
+
+#define PLAT_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+#define PLAT_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+
+#define IRQ_MAX		200U
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amd/versal2/include/scmi.h b/plat/amd/versal2/include/scmi.h
new file mode 100644
index 0000000..0ab8b34
--- /dev/null
+++ b/plat/amd/versal2/include/scmi.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_H
+#define SCMI_H
+
+#include "versal2-scmi.h"
+
+#define SIP_SCMI	(0xC200ffffU)
+#define SMT_BUFFER_BASE	0x7fffe000
+
+void init_scmi_server(void);
+
+#define SCMI_VENDOR	"AMD"
+#define SCMI_PRODUCT	"Versal Gen 2"
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
new file mode 100644
index 0000000..4d581e4
--- /dev/null
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Macros IDs for AMD Versal Gen 2
+ *
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#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 RESET_GEM0_0	0
+#define RESET_GEM1_0	1
+#define RESET_SERIAL0_0	2
+#define RESET_SERIAL1_0	3
+#define RESET_UFS0_0	4
+#define RESET_I2C0_0	5
+#define RESET_I2C1_0	6
+#define RESET_I2C2_0	7
+#define RESET_I2C3_0	8
+#define RESET_I2C4_0	9
+#define RESET_I2C5_0	10
+#define RESET_I2C6_0	11
+#define RESET_I2C7_0	12
+#define RESET_I2C8_0	13
+#define RESET_OSPI0_0	14
+#define RESET_USB0_0	15
+#define RESET_USB0_1	16
+#define RESET_USB0_2	17
+#define RESET_USB1_0	18
+#define RESET_USB1_1	19
+#define RESET_USB1_2	20
+#define RESET_MMC0_0	21
+#define RESET_MMC1_0	22
+#define RESET_SPI0_0	23
+#define RESET_SPI1_0	24
+#define RESET_QSPI0_0	25
+#define RESET_I3C0_0	26
+#define RESET_I3C1_0	27
+#define RESET_I3C2_0	28
+#define RESET_I3C3_0	29
+#define RESET_I3C4_0	30
+#define RESET_I3C5_0	31
+#define RESET_I3C6_0	32
+#define RESET_I3C7_0	33
+#define RESET_I3C8_0	34
+
+#endif /* _VERSAL2_SCMI_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
new file mode 100644
index 0000000..4faa434
--- /dev/null
+++ b/plat/amd/versal2/plat_psci.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+#include <pm_defs.h>
+
+#define PM_RET_ERROR_NOFEATURE U(19)
+#define ALWAYSTRUE true
+
+static uintptr_t _sec_entry;
+
+static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
+{
+	dsb();
+	wfi();
+}
+
+#define MPIDR_MT_BIT	(24)
+
+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;
+	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);
+
+	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x, cpu: %x, cluster: %x\n",
+		__func__, mpidr, cpu_id, cpu, cluster);
+
+	if (cpu_id == -1) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	if (cluster > 3) {
+		panic();
+	}
+
+	apu_pcli_cluster = APU_PCLI + APU_PCLI_CLUSTER_OFFSET + ((uint64_t)cluster * APU_PCLI_CLUSTER_STEP);
+	apu_cluster_base = APU_CLUSTER0 + ((uint64_t)cluster * APU_CLUSTER_STEP);
+
+	/* Enable clock */
+	mmio_setbits_32(PSX_CRF + ACPU0_CLK_CTRL + ((uint64_t)cluster * 0x4U), ACPU_CLK_CTRL_CLKACT);
+
+	/* Enable cluster states */
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_SET);
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	/* assert core reset */
+	mmio_setbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* program RVBAR */
+	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);
+
+	/* de-assert core reset */
+	mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* clear cluster resets */
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_WARM_RESET);
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_COLD_RESET);
+
+	apu_pcli_base = APU_PCLI + (APU_PCLI_CPU_STEP * cpu) +
+			(APU_PCLI_CLUSTER_CPU_STEP * cluster);
+
+	mmio_write_32(apu_pcli_base + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_CLEAR);
+	mmio_write_32(apu_pcli_base + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_nopmu_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	plat_gic_cpuif_disable();
+}
+
+static void __dead2 zynqmp_nopmu_system_reset(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint);
+
+	if ((ns_entrypoint) != 0U) {
+		return PSCI_E_SUCCESS;
+	} else {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+}
+
+static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+}
+
+static void __dead2 zynqmp_system_off(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_power_state(uint32_t power_state, psci_power_state_t *req_state)
+{
+	return PSCI_E_SUCCESS;
+}
+
+static const struct plat_psci_ops _nopmc_psci_ops = {
+	.cpu_standby			= zynqmp_cpu_standby,
+	.pwr_domain_on			= zynqmp_nopmu_pwr_domain_on,
+	.pwr_domain_off			= zynqmp_nopmu_pwr_domain_off,
+	.system_reset			= zynqmp_nopmu_system_reset,
+	.validate_ns_entrypoint		= zynqmp_validate_ns_entrypoint,
+	.pwr_domain_on_finish		= zynqmp_pwr_domain_on_finish,
+	.system_off			= zynqmp_system_off,
+	.validate_power_state		= zynqmp_validate_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			    const struct plat_psci_ops **psci_ops)
+{
+	_sec_entry = sec_entrypoint;
+
+	VERBOSE("Setting up entry point %lx\n", _sec_entry);
+
+	*psci_ops = &_nopmc_psci_ops;
+
+	return 0;
+}
+
+int sip_svc_setup_init(void)
+{
+	return 0;
+}
+
+static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
+			   uint32_t arg1, uint32_t arg2)
+{
+	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
+	if (ioctl_id == IOCTL_OSPI_MUX_SELECT) {
+		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
+		return 0;
+	}
+	return PM_RET_ERROR_NOFEATURE;
+}
+
+static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			      uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+	int32_t ret;
+	uint32_t arg[4], api_id;
+
+	arg[0] = (uint32_t)x1;
+	arg[1] = (uint32_t)(x1 >> 32);
+	arg[2] = (uint32_t)x2;
+	arg[3] = (uint32_t)(x2 >> 32);
+
+	api_id = smc_fid & FUNCID_NUM_MASK;
+	VERBOSE("%s: smc_fid: %x, api_id=0x%x\n", __func__, smc_fid, api_id);
+
+	switch (api_id) {
+	case PM_IOCTL:
+	{
+		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
+		SMC_RET1(handle, (uint64_t)ret);
+	}
+	case PM_GET_CHIPID:
+	{
+		uint32_t idcode, version;
+
+		idcode  = mmio_read_32(PMC_TAP);
+		version = mmio_read_32(PMC_TAP_VERSION);
+		SMC_RET2(handle, ((uint64_t)idcode << 32), version);
+	}
+	default:
+		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+uint64_t 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)
+{
+	return no_pm_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
diff --git a/plat/amd/versal2/plat_topology.c b/plat/amd/versal2/plat_topology.c
new file mode 100644
index 0000000..0763139
--- /dev/null
+++ b/plat/amd/versal2/plat_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+
+static const uint8_t plat_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	1,
+	/* Number of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the second cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the third cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the fourth cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+};
+
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return plat_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * 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. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	uint32_t cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -3;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+}
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
new file mode 100644
index 0000000..c07fc36
--- /dev/null
+++ b/plat/amd/versal2/platform.mk
@@ -0,0 +1,127 @@
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+PLAT_PATH := plat/amd/versal2
+
+# A78 Erratum for SoC
+ERRATA_A78_AE_1941500 := 1
+ERRATA_A78_AE_1951502 := 1
+ERRATA_A78_AE_2376748 := 1
+ERRATA_A78_AE_2395408 := 1
+ERRATA_ABI_SUPPORT    := 1
+
+# Platform Supports Armv8.2 extensions
+ARM_ARCH_MAJOR := 8
+ARM_ARCH_MINOR := 2
+
+override PROGRAMMABLE_RESET_ADDRESS := 1
+PSCI_EXTENDED_STATE_ID := 1
+SEPARATE_CODE_AND_RODATA := 1
+override RESET_TO_BL31 := 1
+PL011_GENERIC_UART := 1
+IPI_CRC_CHECK := 0
+GIC_ENABLE_V4_EXTN :=  0
+GICV3_SUPPORT_GIC600 := 1
+
+override CTX_INCLUDE_AARCH32_REGS    := 0
+
+ifdef MEM_BASE
+    $(eval $(call add_define,MEM_BASE))
+
+    ifndef MEM_SIZE
+        $(error "ATF_BASE defined without ATF_SIZE")
+    endif
+    $(eval $(call add_define,MEM_SIZE))
+
+    ifdef MEM_PROGBITS_SIZE
+        $(eval $(call add_define,MEM_PROGBITS_SIZE))
+    endif
+endif
+
+ifdef BL32_MEM_BASE
+    $(eval $(call add_define,BL32_MEM_BASE))
+
+    ifndef BL32_MEM_SIZE
+        $(error "BL32_BASE defined without BL32_SIZE")
+    endif
+    $(eval $(call add_define,BL32_MEM_SIZE))
+endif
+
+ifdef IPI_CRC_CHECK
+    $(eval $(call add_define,IPI_CRC_CHECK))
+endif
+
+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)
+endif
+
+$(eval $(call add_define_val,CONSOLE,CONSOLE_ID_${CONSOLE}))
+
+ifdef XILINX_OF_BOARD_DTB_ADDR
+$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
+endif
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
+				-Iplat/xilinx/common/include/			\
+				-Iplat/xilinx/common/ipi_mailbox_service/	\
+				-I${PLAT_PATH}/include/				\
+				-Iplat/xilinx/versal/pm_service/
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				${GICV3_SOURCES}				\
+				drivers/arm/pl011/aarch64/pl011_console.S	\
+				plat/common/aarch64/crash_console_helpers.S	\
+				plat/arm/common/arm_common.c			\
+				plat/common/plat_gicv3.c			\
+				${PLAT_PATH}/aarch64/helpers.S			\
+				${PLAT_PATH}/aarch64/common.c			\
+				${PLAT_PATH}/plat_topology.c                    \
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a78_ae.S		\
+				lib/cpus/aarch64/cortex_a78.S			\
+				plat/common/plat_psci_common.c			\
+				drivers/scmi-msg/base.c				\
+				drivers/scmi-msg/entry.c			\
+				drivers/scmi-msg/smt.c				\
+				drivers/scmi-msg/clock.c			\
+				drivers/scmi-msg/power_domain.c			\
+				drivers/scmi-msg/reset_domain.c			\
+				${PLAT_PATH}/scmi.c
+
+BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
+
+BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
+				plat/xilinx/common/plat_startup.c		\
+				plat/xilinx/common/ipi.c			\
+				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c	\
+				${PLAT_PATH}/soc_ipi.c				\
+				plat/xilinx/common/versal.c			\
+				${PLAT_PATH}/bl31_setup.c			\
+				common/fdt_fixup.c				\
+				${LIBFDT_SRCS}					\
+				${PLAT_PATH}/sip_svc_setup.c			\
+				${PLAT_PATH}/gicv3.c
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+CORTEX_A78_AE_H_INC     := 1
+$(eval $(call add_define, CORTEX_A78_AE_H_INC))
+endif
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
new file mode 100644
index 0000000..c3c517a
--- /dev/null
+++ b/plat/amd/versal2/scmi.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+#include <scmi.h>
+
+#include "plat_private.h"
+
+#define HIGH (1)
+#define LOW (0)
+
+struct scmi_clk {
+	unsigned long clock_id;
+	unsigned long rate;
+	const char *name;
+	bool enabled;
+};
+
+#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled, _rate) \
+	[_scmi_id] = { \
+		.clock_id = (_id), \
+		.name = (_name), \
+		.enabled = (_init_enabled), \
+		.rate = (_rate), \
+	}
+
+static struct scmi_clk scmi0_clock[] = {
+	CLOCK_CELL(CLK_GEM0_0, CLK_GEM0_0, "gem0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_1, CLK_GEM0_1, "gem0_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_2, CLK_GEM0_2, "gem0_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM0_3, CLK_GEM0_3, "gem0_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_4, CLK_GEM0_4, "gem0_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_0, CLK_GEM1_0, "gem1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_1, CLK_GEM1_1, "gem1_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_2, CLK_GEM1_2, "gem1_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM1_3, CLK_GEM1_3, "gem1_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_4, CLK_GEM1_4, "gem1_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_0, CLK_SERIAL0_0, "uart0_uartclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_1, CLK_SERIAL0_1, "uart0_apb_pclk", true, 100000000),
+	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_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),
+	CLOCK_CELL(CLK_USB1_0, CLK_USB1_0, "usb1_bus_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_1, CLK_USB1_1, "usb1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_2, CLK_USB1_2, "usb1_dwc_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_0, CLK_MMC0_0, "mmc0_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_1, CLK_MMC0_1, "mmc0_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_2, CLK_MMC0_2, "mmc0_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_0, CLK_MMC1_0, "mmc1_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_1, CLK_MMC1_1, "mmc1_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_2, CLK_MMC1_2, "mmc1_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC0_0, CLK_TTC0_0, "ttc0_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC1_0, CLK_TTC1_0, "ttc1_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC2_0, CLK_TTC2_0, "ttc2_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC3_0, CLK_TTC3_0, "ttc3_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC4_0, CLK_TTC4_0, "ttc4_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC5_0, CLK_TTC5_0, "ttc5_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC6_0, CLK_TTC6_0, "ttc6_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC7_0, CLK_TTC7_0, "ttc7_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C0_0, CLK_I2C0_0, "i2c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C1_0, CLK_I2C1_0, "i2c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C2_0, CLK_I2C2_0, "i2c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C3_0, CLK_I2C3_0, "i2c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C4_0, CLK_I2C4_0, "i2c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C5_0, CLK_I2C5_0, "i2c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C6_0, CLK_I2C6_0, "i2c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C7_0, CLK_I2C7_0, "i2c7_clk", true, 100000000),
+	CLOCK_CELL(CLK_OSPI0_0, CLK_OSPI0_0, "ospi0_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_0, CLK_QSPI0_0, "qpsi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_1, CLK_QSPI0_1, "qspi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT0_0, CLK_WWDT0_0, "wwdt0_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT1_0, CLK_WWDT1_0, "wwdt1_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT2_0, CLK_WWDT2_0, "wwdt2_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT3_0, CLK_WWDT3_0, "wwdt3_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_0, CLK_ADMA0_0, "adma0_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_1, CLK_ADMA0_1, "adma0_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_0, CLK_ADMA1_0, "adma1_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_1, CLK_ADMA1_1, "adma1_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_0, CLK_ADMA2_0, "adma2_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_1, CLK_ADMA2_1, "adma2_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_0, CLK_ADMA3_0, "adma3_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_1, CLK_ADMA3_1, "adma3_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_0, CLK_ADMA4_0, "adma4_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_1, CLK_ADMA4_1, "adma4_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_0, CLK_ADMA5_0, "adma5_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_1, CLK_ADMA5_1, "adma5_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_0, CLK_ADMA6_0, "adma6_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_1, CLK_ADMA6_1, "adma6_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_0, CLK_ADMA7_0, "adma7_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_1, CLK_ADMA7_1, "adma7_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_0, CLK_CAN0_0, "can0_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_1, CLK_CAN0_1, "can0_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_0, CLK_CAN1_0, "can1_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_1, CLK_CAN1_1, "can1_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_0, CLK_CAN2_0, "can2_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_1, CLK_CAN2_1, "can2_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_0, CLK_CAN3_0, "can3_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_1, CLK_CAN3_1, "can3_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_PS_GPIO_0, CLK_PS_GPIO_0, "ps_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_PMC_GPIO_0, CLK_PMC_GPIO_0, "pmc_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_0, CLK_SPI0_0, "spi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_1, CLK_SPI0_1, "spi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_0, CLK_SPI1_0, "spi1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_1, CLK_SPI1_1, "spi1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_I3C0_0, CLK_I3C0_0, "i3c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C1_0, CLK_I3C1_0, "i3c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C2_0, CLK_I3C2_0, "i3c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C3_0, CLK_I3C3_0, "i3c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C4_0, CLK_I3C4_0, "i3c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C5_0, CLK_I3C5_0, "i3c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C6_0, CLK_I3C6_0, "i3c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C7_0, CLK_I3C7_0, "i3c7_clk", true, 100000000),
+};
+
+/*
+ * struct scmi_reset - Data for the exposed reset controller
+ * @reset_id: Reset identifier in RCC reset driver
+ * @name: Reset string ID exposed to agent
+ */
+struct scmi_reset {
+	unsigned long reset_id;
+	const char *name;
+};
+
+#define RESET_CELL(_scmi_id, _id, _name) \
+	[_scmi_id] = { \
+		.reset_id = (_id), \
+		.name = (_name), \
+	}
+
+static struct scmi_reset scmi0_reset[] = {
+	RESET_CELL(RESET_GEM0_0, RESET_GEM0_0, "gem0"),
+	RESET_CELL(RESET_GEM1_0, RESET_GEM1_0, "gem1"),
+	RESET_CELL(RESET_SERIAL0_0, RESET_SERIAL0_0, "serial0"),
+	RESET_CELL(RESET_SERIAL1_0, RESET_SERIAL1_0, "serial1"),
+	RESET_CELL(RESET_UFS0_0, RESET_UFS0_0, "ufs0"),
+	RESET_CELL(RESET_I2C0_0, RESET_I2C0_0, "i2c0"),
+	RESET_CELL(RESET_I2C1_0, RESET_I2C1_0, "i2c1"),
+	RESET_CELL(RESET_I2C2_0, RESET_I2C2_0, "i2c2"),
+	RESET_CELL(RESET_I2C3_0, RESET_I2C3_0, "i2c3"),
+	RESET_CELL(RESET_I2C4_0, RESET_I2C4_0, "i2c4"),
+	RESET_CELL(RESET_I2C5_0, RESET_I2C5_0, "i2c5"),
+	RESET_CELL(RESET_I2C6_0, RESET_I2C6_0, "i2c6"),
+	RESET_CELL(RESET_I2C7_0, RESET_I2C7_0, "i2c7"),
+	RESET_CELL(RESET_I2C8_0, RESET_I2C8_0, "i2c8"),
+	RESET_CELL(RESET_OSPI0_0, RESET_OSPI0_0, "ospi"),
+	RESET_CELL(RESET_USB0_0, RESET_USB0_0, "usb0_0"),
+	RESET_CELL(RESET_USB0_1, RESET_USB0_1, "usb0_1"),
+	RESET_CELL(RESET_USB0_2, RESET_USB0_2, "usb0_2"),
+	RESET_CELL(RESET_USB1_0, RESET_USB1_0, "usb1_0"),
+	RESET_CELL(RESET_USB1_1, RESET_USB1_1, "usb1_1"),
+	RESET_CELL(RESET_USB1_2, RESET_USB1_2, "usb1_2"),
+	RESET_CELL(RESET_MMC0_0, RESET_MMC0_0, "mmc0"),
+	RESET_CELL(RESET_MMC1_0, RESET_MMC1_0, "mmc1"),
+	RESET_CELL(RESET_SPI0_0, RESET_SPI0_0, "spi0"),
+	RESET_CELL(RESET_SPI1_0, RESET_SPI1_0, "spi1"),
+	RESET_CELL(RESET_QSPI0_0, RESET_QSPI0_0, "qspi"),
+	RESET_CELL(RESET_I3C0_0, RESET_I3C0_0, "i3c0"),
+	RESET_CELL(RESET_I3C1_0, RESET_I3C1_0, "i3c1"),
+	RESET_CELL(RESET_I3C2_0, RESET_I3C2_0, "i3c2"),
+	RESET_CELL(RESET_I3C3_0, RESET_I3C3_0, "i3c3"),
+	RESET_CELL(RESET_I3C4_0, RESET_I3C4_0, "i3c4"),
+	RESET_CELL(RESET_I3C5_0, RESET_I3C5_0, "i3c5"),
+	RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"),
+	RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"),
+	RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"),
+};
+
+struct scmi_resources {
+	struct scmi_clk *clock;
+	size_t clock_count;
+	struct scmi_reset *reset;
+	size_t reset_count;
+
+};
+
+static const struct scmi_resources resources[] = {
+	[0] = {
+		.clock = scmi0_clock,
+		.clock_count = ARRAY_SIZE(scmi0_clock),
+		.reset = scmi0_reset,
+		.reset_count = ARRAY_SIZE(scmi0_reset),
+	},
+};
+
+static const struct scmi_resources *find_resource(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(resources));
+
+	return &resources[agent_id];
+}
+
+static struct scmi_clk *clk_find(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n = 0U;
+	struct scmi_clk *ret = NULL;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->clock_count; n++) {
+			if (n == scmi_id) {
+				ret = &resource->clock[n];
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+size_t plat_scmi_clock_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		VERBOSE("SCMI: CLK: %d clocks\n", (unsigned int)resource->clock_count);
+
+		ret = resource->clock_count;
+	}
+	return ret;
+}
+
+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 char *ret;
+
+	if (clock == NULL) {
+		ret = NULL;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_name: %s\n", scmi_id, clock->name);
+
+		ret = clock->name;
+	}
+	return ret;
+};
+
+/* Called by Linux */
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
+				    unsigned long *array, size_t *nb_elts,
+				    uint32_t start_idx)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+
+	if (clock == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (start_idx > 0) {
+		return SCMI_OUT_OF_RANGE;
+	}
+
+	if (array == NULL) {
+		*nb_elts = 1U;
+	} else if (*nb_elts == 1U) {
+		*array = clock->rate;
+		VERBOSE("SCMI: CLK: id: %d, clk_name: %s, get_rate %lu\n",
+		     scmi_id, clock->name, *array);
+	} else {
+		return SCMI_GENERIC_ERROR;
+	}
+
+	return SCMI_SUCCESS;
+}
+
+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);
+	unsigned long ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_rate: %lu\n", scmi_id, clock->rate);
+		ret = clock->rate;
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
+				 unsigned long rate)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	unsigned long ret = UL(SCMI_SUCCESS);
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, set_rate: %lu\n", scmi_id, rate);
+		clock->rate = rate;
+	}
+	return ret;
+}
+
+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);
+	int32_t ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_state: %d\n", scmi_id, clock->enabled);
+
+		if (clock->enabled) {
+			ret = HIGH;
+		} else {
+			ret = LOW;
+		}
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
+				  bool enable_not_disable)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	int32_t ret;
+
+	if (clock == NULL) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		if (enable_not_disable) {
+			if (!clock->enabled) {
+				VERBOSE("SCMI: clock: %u enable\n", scmi_id);
+				clock->enabled = true;
+			}
+		} else {
+			if (clock->enabled) {
+				VERBOSE("SCMI: clock: %u disable\n", scmi_id);
+				clock->enabled = false;
+			}
+		}
+
+		VERBOSE("SCMI: CLK: id: %d, set_state: %d\n", scmi_id, clock->enabled);
+
+		ret = SCMI_SUCCESS;
+	}
+
+	return ret;
+}
+
+
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_reset *find_reset(unsigned int agent_id,
+					 unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->reset_count; n++) {
+			if (n == scmi_id) {
+				return &resource->reset[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return NULL;
+	}
+
+	return reset->name;
+}
+
+size_t plat_scmi_rstd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+
+	if (resource == NULL) {
+		return 0U;
+	}
+
+	return resource->reset_count;
+}
+
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
+				uint32_t state)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	/* Supports only reset with context loss */
+	if (state != 0U) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI reset on ID %lu/%s\n",
+	       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+	return SCMI_SUCCESS;
+}
+
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
+				 bool assert_not_deassert)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (assert_not_deassert) {
+		NOTICE("SCMI reset %lu/%s set\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+	} else {
+		NOTICE("SCMI reset %lu/%s release\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+	}
+
+	return SCMI_SUCCESS;
+}
+
+/* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	VERBOSE("%d: SCMI asking for channel\n", agent_id);
+
+	/* Just in case that code is reused */
+	return &scmi_channel[agent_id];
+}
+
+/* Base protocol implementations */
+const char *plat_scmi_vendor_name(void)
+{
+	return SCMI_VENDOR;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return SCMI_PRODUCT;
+}
+
+/* Currently supporting Clocks and Reset Domains */
+static const uint8_t plat_protocol_list[] = {
+	SCMI_PROTOCOL_ID_BASE,
+	SCMI_PROTOCOL_ID_CLOCK,
+	SCMI_PROTOCOL_ID_RESET_DOMAIN,
+	/*
+	 *SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	 *SCMI_PROTOCOL_ID_SENSOR,
+	 */
+	0U /* Null termination */
+};
+
+size_t plat_scmi_protocol_count(void)
+{
+	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
+
+	VERBOSE("SCMI: Protocol count: %d\n", (int32_t)count);
+
+	return count;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
+{
+	return plat_protocol_list;
+}
+
+void init_scmi_server(void)
+{
+	size_t i;
+	int32_t ret;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+
+	INFO("SCMI: Server initialized\n");
+
+	if (platform_id == QEMU) {
+		/* default setting is for QEMU */
+	} else if (platform_id == SPP) {
+		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)
+				continue;
+			/*
+			 * SPP supports multiple versions.
+			 * The cpu_clock value is set to corresponding SPP
+			 * version in early platform setup, resuse the same
+			 * value here.
+			 */
+			ret = plat_scmi_clock_set_rate(0, i, cpu_clock);
+			if (ret < 0) {
+				NOTICE("Failed to set clock rate for SPP scmi_id=%ld\n", i);
+			}
+		}
+	} else {
+		 /* Making MISRA C 2012 15.7 compliant */
+	}
+}
diff --git a/plat/amd/versal2/sip_svc_setup.c b/plat/amd/versal2/sip_svc_setup.c
new file mode 100644
index 0000000..6850030
--- /dev/null
+++ b/plat/amd/versal2/sip_svc_setup.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
+
+#include <errno.h>
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+#include <scmi.h>
+#include <tools_share/uuid.h>
+
+#include "ipi_mailbox_svc.h"
+#include "plat_private.h"
+#include "pm_svc_main.h"
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_UID		(0x8200ff01U)
+#define SIP_SVC_VERSION	(0x8200ff03U)
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR		(0U)
+#define SIP_SVC_VERSION_MINOR		(1U)
+
+/* These macros are used to identify PM calls from the SMC function ID */
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
+#define PM_FID_VALUE	0u
+#define IPI_FID_VALUE	0x1000u
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
+
+/* SiP Service UUID */
+DEFINE_SVC_UUID2(_sip_uuid,
+		0x0499eb70, 0x5ed0, 0x11ee, 0xb3, 0x0a,
+		0x87, 0xd1, 0x1d, 0x4f, 0x8a, 0x9b);
+
+/**
+ * sip_svc_setup() - Setup SiP Service
+ *
+ * Return: 0 on success, negative error code on failure.
+ *
+ */
+static int32_t sip_svc_setup(void)
+{
+	return sip_svc_setup_init();
+}
+
+/*
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ *
+ * Handler for all SiP SMC calls. Handles standard SIP requests
+ * and calls PM SMC handler if the call is for a PM-API function.
+ */
+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) != 0) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
+		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let IPI SMC handler deal with IPI-related requests if platform */
+	if (is_ipi_fid(smc_fid)) {
+		return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	switch (smc_fid) {
+	case SIP_SVC_UID:
+		SMC_UUID_RET(handle, _sip_uuid);
+
+	case SIP_SVC_VERSION:
+		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
+
+	case SIP_SCMI:
+		if (platform_id != EMU) {
+			scmi_smt_fastcall_smc_entry(0);
+			SMC_RET1(handle, 0);
+		}
+		WARN("SCMI is not working on EMU\n");
+		SMC_RET1(handle, SMC_UNK);
+	default:
+		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* Register PM Service Calls as runtime service */
+DECLARE_RT_SVC(
+		sip_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		sip_svc_setup,
+		sip_svc_smc_handler);
diff --git a/plat/amd/versal2/soc_ipi.c b/plat/amd/versal2/soc_ipi.c
new file mode 100644
index 0000000..85d1bcd
--- /dev/null
+++ b/plat/amd/versal2/soc_ipi.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * SoC IPI agent registers access management
+ */
+
+#include <lib/utils_def.h>
+#include <plat_ipi.h>
+
+/* versal2 ipi configuration table */
+static const struct ipi_config ipi_table[IPI_ID_MAX] = {
+	/* A78 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* PMC IPI */
+	[IPI_ID_PMC] = {
+		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = IPI_SECURE_MASK,
+	},
+
+	/* RPU0 IPI */
+	[IPI_ID_RPU0] = {
+		.ipi_bit_mask = IPI1_TRIG_BIT,
+		.ipi_reg_base = IPI1_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* RPU1 IPI */
+	[IPI_ID_RPU1] = {
+		.ipi_bit_mask = IPI2_TRIG_BIT,
+		.ipi_reg_base = IPI2_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI3 IPI */
+	[IPI_ID_3] = {
+		.ipi_bit_mask = IPI3_TRIG_BIT,
+		.ipi_reg_base = IPI3_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI4 IPI */
+	[IPI_ID_4] = {
+		.ipi_bit_mask = IPI4_TRIG_BIT,
+		.ipi_reg_base = IPI4_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI5 IPI */
+	[IPI_ID_5] = {
+		.ipi_bit_mask = IPI5_TRIG_BIT,
+		.ipi_reg_base = IPI5_REG_BASE,
+		.secure_only = 0,
+	},
+};
+
+/**
+ * soc_ipi_config_table_init() - Initialize versal2 IPI configuration data.
+ */
+void soc_ipi_config_table_init(void)
+{
+	ipi_config_table_init(ipi_table, ARRAY_SIZE(ipi_table));
+}
diff --git a/plat/amd/versal2/tsp/tsp-versal2.mk b/plat/amd/versal2/tsp/tsp-versal2.mk
new file mode 100644
index 0000000..422ed17
--- /dev/null
+++ b/plat/amd/versal2/tsp/tsp-versal2.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal Gen 2 platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
index 64b35d6..aadecab 100644
--- a/plat/amlogic/axg/platform.mk
+++ b/plat/amlogic/axg/platform.mk
@@ -85,10 +85,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/amlogic/g12a/platform.mk b/plat/amlogic/g12a/platform.mk
index 799e106..15658d3 100644
--- a/plat/amlogic/g12a/platform.mk
+++ b/plat/amlogic/g12a/platform.mk
@@ -81,10 +81,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/amlogic/gxl/platform.mk b/plat/amlogic/gxl/platform.mk
index 0a88482..31063a9 100644
--- a/plat/amlogic/gxl/platform.mk
+++ b/plat/amlogic/gxl/platform.mk
@@ -81,10 +81,10 @@
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index ec0b19e..82401db 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -41,8 +41,12 @@
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_MTE2		:= 2
+ENABLE_FEAT_TCR2		:= 2
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_TRF_FOR_NS		:= 2
+ENABLE_SME_FOR_NS		:= 2
+ENABLE_SME2_FOR_NS		:= 2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -77,8 +81,8 @@
 				lib/cpus/aarch64/neoverse_n1.S			\
 				lib/cpus/aarch64/neoverse_n2.S			\
 				lib/cpus/aarch64/neoverse_v1.S			\
-				lib/cpus/aarch64/cortex_chaberton.S		\
-				lib/cpus/aarch64/cortex_blackhawk.S
+				lib/cpus/aarch64/cortex_a725.S		\
+				lib/cpus/aarch64/cortex_x925.S
 
 # AArch64/AArch32 cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S	\
@@ -128,13 +132,15 @@
 $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31))
 
 ifeq ($($(ARCH)-ld-id),gnu-gcc)
-        PLAT_LDFLAGS	+=	-Wl,--strip-debug
+        AXF_LDFLAGS	+=	-Wl,--build-id=none -mno-fix-cortex-a53-843419
 else
-        PLAT_LDFLAGS	+=	--strip-debug
+        AXF_LDFLAGS	+=	--build-id=none
 endif
 
+AXF_LDFLAGS += -nostdlib -no-pie
+
 bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld
-	$(ECHO) "  LD      $@"
-	$(Q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} $(TF_LDFLAGS) $(PLAT_LDFLAGS) -s -n -o ${BUILD_PLAT}/bl31.axf
+	$(s)echo "  LD      $@"
+	$(q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} ${AXF_LDFLAGS} -s -n -o ${BUILD_PLAT}/bl31.axf
 
 all: bl31.axf
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 655a4d2..4a2572f 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -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
  */
@@ -219,6 +219,15 @@
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 							NON_TRUSTED_NV_CTR_ID);
+#if defined(ARM_COT_cca)
+	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
+		/*
+		 * Use Trusted NV counter for platforms that don't support
+		 * the CCA NV Counter.
+		 */
+		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+							TRUSTED_NV_CTR_ID);
+#endif
 	} else {
 		return 1;
 	}
diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
index 457d181..de6a15a 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, 2024 ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,7 +77,8 @@
 		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
 			VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
 		.ep_info.pc = BL33_BASE,
-
+		.ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS),
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 			VERSION_2, image_info_t, 0),
 		.image_info.image_base = BL33_BASE,
diff --git a/plat/arm/board/corstone1000/common/corstone1000_helpers.S b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
index cbe27c3..a4ca9fe 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_helpers.S
+++ b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,8 +21,34 @@
 	 * --------------------------------------------------------------------
 	 */
 func plat_secondary_cold_boot_setup
+#if defined(CORSTONE1000_FVP_MULTICORE)
+
+	/* Calculate the address of our hold entry */
+	bl	plat_my_core_pos
+	lsl	x0, x0, #CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT
+	mov_imm	x2, CORSTONE1000_SECONDARY_CORE_HOLD_BASE
+
+	/* Set the wait state for the secondary core */
+	mov_imm	x3, CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	str	x3, [x2, x0]
+	dmb	ish
+
+	/* Poll until the primary core signals to go  */
+poll_mailbox:
+	ldr	x1, [x2, x0]
+	cmp	x1, #CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	beq	1f
+	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+	ldr	x1, [x0]
+	br	x1
+1:
+	wfe
+	b	poll_mailbox
+#else
 cb_panic:
 	b	cb_panic
+#endif
+
 endfunc plat_secondary_cold_boot_setup
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/arm/board/corstone1000/common/corstone1000_plat.c b/plat/arm/board/corstone1000/common/corstone1000_plat.c
index ed3801c..e388c82 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_plat.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,7 +23,6 @@
 
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	ARM_MAP_NS_SHARED_RAM,
 	ARM_MAP_NS_DRAM1,
 	CORSTONE1000_MAP_DEVICE,
 	CORSTONE1000_EXTERNAL_FLASH,
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 4b0a791..bd3faec 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #include <lib/psci/psci.h>
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/gicv2.h>
 /*******************************************************************************
  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
  * platform layer will take care of registering the handlers with PSCI.
@@ -18,6 +20,15 @@
 	uint32_t volatile * const watchdog_ctrl_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_CTRL_REG;
 	uint32_t volatile * const watchdog_val_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_VAL_REG;
 
+	/*
+	 * Disable GIC CPU interface to prevent pending interrupt
+	 * from waking up the AP from WFI.
+	 */
+	gicv2_cpuif_disable();
+
+	/* Flush and invalidate data cache */
+	dcsw_op_all(DCCISW);
+
 	*(watchdog_val_reg) = SECURE_WATCHDOG_COUNTDOWN_VAL;
 	*watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE;
 	while (1) {
@@ -25,9 +36,52 @@
 	}
 }
 
+#if defined(CORSTONE1000_FVP_MULTICORE)
+int corstone1000_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) {
+		return PSCI_E_SUCCESS;
+	}
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+int corstone1000_pwr_domain_on(u_register_t mpidr)
+{
+	int core_index = plat_core_pos_by_mpidr(mpidr);
+	uint64_t *secondary_core_hold_base = (uint64_t *)CORSTONE1000_SECONDARY_CORE_HOLD_BASE;
+
+	/* Validate the core index */
+	if (core_index < 0 || core_index > PLATFORM_CORE_COUNT) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+	secondary_core_hold_base[core_index] = CORSTONE1000_SECONDARY_CORE_STATE_GO;
+	dsbish();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	(void)target_state;
+	plat_arm_gic_init();
+}
+#endif
+
 plat_psci_ops_t plat_arm_psci_pm_ops = {
+#if defined(CORSTONE1000_FVP_MULTICORE)
+	.pwr_domain_on = corstone1000_pwr_domain_on,
+	.pwr_domain_on_finish = corstone1000_pwr_domain_on_finish,
+	.validate_ns_entrypoint = corstone1000_validate_ns_entrypoint,
 	.system_reset = corstone1000_system_reset,
-	.validate_ns_entrypoint = NULL
+#else
+	.validate_ns_entrypoint = NULL,
+	.system_reset = corstone1000_system_reset,
+#endif
 };
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
index 6953b89..caf3d46 100644
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
@@ -55,42 +55,42 @@
 
 /* Memory related constants */
 
-/* SRAM (CVM) memory layout
+/* Memory mappings of where the BLs in the FIP are copied to
  *
- * <ARM_TRUSTED_SRAM_BASE>
+ * <ARM_TRUSTED_SRAM_BASE> = 0x02000000
  *	partition size: sizeof(meminfo_t) = 16 bytes
  *	content: memory info area used by the next BL
  *
- * <ARM_FW_CONFIG_BASE>
+ * <ARM_FW_CONFIG_BASE> = 0x02000010
  *	partition size: 4080 bytes
  *
- * <ARM_BL2_MEM_DESC_BASE>
+ * <ARM_BL2_MEM_DESC_BASE> = 0x02001000
  *	partition size: 4 KB
  *	content: Area where BL2 copies the images descriptors
  *
- * <ARM_BL_RAM_BASE> = <BL32_BASE>
- *	partition size: 688 KB
+ * <ARM_BL_RAM_BASE> = <BL32_BASE> = 0x02002000
+ *	partition size: 3752 KB
  *	content: BL32 (optee-os)
  *
- * <CORSTONE1000_TOS_FW_CONFIG_BASE> = 0x20ae000
+ * <CORSTONE1000_TOS_FW_CONFIG_BASE> = 0x023AC000
  *	partition size: 8 KB
  *	content: BL32 config (TOS_FW_CONFIG)
  *
- * <BL31_BASE>
+ * <BL31_BASE> = 0x023AE000
  *	partition size: 140 KB
  *	content: BL31
  *
- * <BL2_SIGNATURE_BASE>
+ * <BL2_SIGNATURE_BASE> = 0x023D1000
  *	partition size: 4 KB
  *	content: MCUBOOT data needed to verify TF-A BL2
  *
- * <BL2_BASE>
+ * <BL2_BASE> = 0x023D2000
  *	partition size: 176 KB
  *	content: BL2
  *
- * <ARM_NS_SHARED_RAM_BASE> = <ARM_TRUSTED_SRAM_BASE> + 1 MB
- *	partition size: 512 KB
- *	content: BL33 (u-boot)
+ * <BL33_BASE> = 0x80000000
+ *	partition size: 12 MB
+ *	content: BL33 (U-Boot)
  */
 
 /* DDR memory */
@@ -115,11 +115,8 @@
 /* The remaining Trusted SRAM is used to load the BL images */
 #define TOTAL_SRAM_SIZE		(SZ_4M)  /* 4 MB */
 
-/* Last 512KB of CVM is allocated for shared RAM as an example openAMP */
-#define ARM_NS_SHARED_RAM_SIZE	(512 * SZ_1K)
 
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	(TOTAL_SRAM_SIZE - \
-					 ARM_NS_SHARED_RAM_SIZE - \
 					 ARM_SHARED_RAM_SIZE)
 
 #define PLAT_ARM_MAX_BL2_SIZE	(180 * SZ_1K)  /* 180 KB */
@@ -158,11 +155,6 @@
 
 /* NS memory */
 
-/* The last 512KB of the SRAM is allocated as shared memory */
-#define ARM_NS_SHARED_RAM_BASE	(ARM_TRUSTED_SRAM_BASE + TOTAL_SRAM_SIZE - \
-				 (PLAT_ARM_MAX_BL31_SIZE + \
-				  PLAT_ARM_MAX_BL32_SIZE))
-
 #define BL33_BASE		ARM_DRAM1_BASE
 #define PLAT_ARM_MAX_BL33_SIZE	(12 * SZ_1M)  /* 12 MB*/
 #define BL33_LIMIT		(ARM_DRAM1_BASE + PLAT_ARM_MAX_BL33_SIZE)
@@ -262,9 +254,22 @@
 #define ARM_LOCAL_STATE_OFF	U(2)
 
 #define PLAT_ARM_TRUSTED_MAILBOX_BASE	ARM_TRUSTED_SRAM_BASE
+
+#if defined(CORSTONE1000_FVP_MULTICORE)
+/* The secondary core entrypoint address points to bl31_warm_entrypoint
+ * and the address size is 8 bytes */
+#define CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE    UL(0x8)
+
+#define CORSTONE1000_SECONDARY_CORE_HOLD_BASE	(PLAT_ARM_TRUSTED_MAILBOX_BASE + \
+						CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE)
+#define CORSTONE1000_SECONDARY_CORE_STATE_WAIT	ULL(0)
+#define CORSTONE1000_SECONDARY_CORE_STATE_GO	ULL(1)
+#define CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT	ULL(3)
+#endif
+
 #define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
 
-#define PLAT_ARM_NS_IMAGE_BASE		(ARM_NS_SHARED_RAM_BASE)
+#define PLAT_ARM_NS_IMAGE_BASE		(BL33_BASE)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
@@ -293,11 +298,6 @@
 				ARM_SHARED_RAM_SIZE, \
 				MT_MEMORY | MT_RW | MT_SECURE)
 
-#define ARM_MAP_NS_SHARED_RAM	MAP_REGION_FLAT( \
-				ARM_NS_SHARED_RAM_BASE, \
-				ARM_NS_SHARED_RAM_SIZE, \
-				MT_MEMORY | MT_RW | MT_NS)
-
 #define ARM_MAP_NS_DRAM1	MAP_REGION_FLAT( \
 				ARM_NS_DRAM1_BASE, \
 				ARM_NS_DRAM1_SIZE, \
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index fd08803..9d44a14 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -36,6 +36,13 @@
 $(eval $(call add_define,CORSTONE1000_WITH_BL32))
 endif
 
+ENABLE_MULTICORE       :=      0
+ifneq ($(filter ${TARGET_PLATFORM}, fvp),)
+ifeq (${ENABLE_MULTICORE},1)
+$(eval $(call add_define,CORSTONE1000_FVP_MULTICORE))
+endif
+endif
+
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
 
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 8efc238..46fb44a 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -6,9 +6,10 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/gicv3.h>
-#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
@@ -29,6 +30,21 @@
 	 */
 func plat_secondary_cold_boot_setup
 #ifndef EL3_PAYLOAD_BASE
+
+	/* --------------------------------------------
+	 * Check if core supports powering down, if it
+	 * supports power down then set core power down
+	 * bit before requesting for the cores to be
+	 * powered off from base power controller.
+	 * ---------------------------------------------
+	 */
+	bl	check_cpupwrctrl_el1_is_available
+	cbz	x0, base_power_off
+
+	mrs	x1, CPUPWRCTLR_EL1
+	orr	x1, x1, #CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CPUPWRCTLR_EL1, x1
+
 	/* ---------------------------------------------
 	 * Power down this cpu.
 	 * TODO: Do we need to worry about powering the
@@ -37,6 +53,7 @@
 	 * loader zeroes out the zi section.
 	 * ---------------------------------------------
 	 */
+base_power_off:
 	mrs	x0, mpidr_el1
 	mov_imm	x1, PWRC_BASE
 	str	w0, [x1, #PPOFFR_OFF]
diff --git a/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
new file mode 100644
index 0000000..9c8328b
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if COT_DESC_IN_DTB
+	#if defined(ARM_COT_cca)
+		#include "cca_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_dualroot)
+		#include "dualroot_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_tbbr)
+		#include "tbbr_cot_descriptors.dtsi"
+	#endif
+#endif
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts
new file mode 100644
index 0000000..36a22a1
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	attribute {
+		spmc_id = <0x8000>;
+		maj_ver = <0x1>;
+		min_ver = <0x1>;
+		exec_state = <0x0>;
+		load_address = <0x0 0x6000000>;
+		entrypoint = <0x0 0x6000000>;
+		binary_size = <0x80000>;
+	};
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 30f1760..9fba4af 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -92,8 +92,9 @@
 
 	memory@1 {
 		device_type = "ns-memory";
-		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
-		      <0x0 0x88000000 0x0 0x10000000>;
+		reg = <0x0 0x80000000 0x0 0x7c000000>,
+		      <0x8 0x80000000 0x1 0x80000000>,
+		      <0x00008800 0x80000000 0x0 0x7f000000>;
 	};
 
 	memory@2 {
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
index d90544b..234ab58 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -35,7 +35,7 @@
 			debug_name = "op-tee";
 			load_address = <0x6280000>;
 			vcpu_count = <8>;
-			mem_size = <1048576>;
+			mem_size = <0xd80000>;
 		};
 	};
 
@@ -63,10 +63,11 @@
 		reg = <0x0 0x6000000 0x0 0x2000000>; /* Trusted DRAM */
 	};
 
-	memory@1 {
+	memory@80000000 {
 		device_type = "ns-memory";
-		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
-		      <0x0 0x88000000 0x0 0x10000000>;
+		reg = <0x0 0x80000000 0x0 0x7c000000>,
+		      <0x8 0x80000000 0x1 0x80000000>,
+		      <0x00008800 0x80000000 0x0 0x7f000000>;
 	};
 
 	memory@0 {
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 9eb2177..b1d3bc1 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -103,13 +103,7 @@
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
 
-#if COT_DESC_IN_DTB
-	#if defined(ARM_COT_cca)
-		#include "cca_cot_descriptors.dtsi"
-	#elif defined(ARM_COT_tbbr)
-		#include "tbbr_cot_descriptors.dtsi"
-	#endif
-#endif
+#include "fvp_cot_desc.dtsi"
 
 #if MEASURED_BOOT
 	#include "event_log.dtsi"
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index 27f4724..4611f80 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,23 +15,30 @@
 
 	/* Properties */
 	description = "op-tee";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>;
 	id = <1>;
 	execution-ctx-count = <8>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x6280000>;
+	mem-size = <0xd80000>; 	/* OP-TEE specific extension */
 	entrypoint-offset = <0x4000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <0x3>; /* Direct request/response supported. */
-	managed-exit;
+	ns-interrupts-action = <1>; /* NS_ACTION_ME */
 	run-time-model = <1>; /* SP pre-emptible. */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
 
+	/* Boot Info */
+	boot-info {
+		compatible = "arm,ffa-manifest-boot-info";
+		ffa_manifest;
+	};
+
 	device-regions {
 		compatible = "arm,ffa-manifest-device-regions";
 
@@ -39,6 +46,7 @@
 			base-address = <0x00000000 0x1c0a0000>;
 			pages-count = <1>;
 			attributes = <0x3>; /* read-write */
+			interrupts = <38 0x900>;
 		};
 	};
 };
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 5557d59..0c5a76c 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -210,7 +210,7 @@
 #ifdef MAP_FW_NS_HANDOFF
 	MAP_FW_NS_HANDOFF,
 #endif
-#ifdef MAP_EL3_FW_HANDOFF
+#if defined(MAP_EL3_FW_HANDOFF) && !RESET_TO_BL31
 	MAP_EL3_FW_HANDOFF,
 #endif
 	{ 0 }
@@ -219,6 +219,11 @@
 #if defined(IMAGE_BL31) && SPM_MM
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	V2M_MAP_IOFPGA_EL0, /* for the UART */
+	V2M_MAP_SECURE_SYSTEMREG_EL0, /* for initializing flash */
+#if PSA_FWU_SUPPORT
+	V2M_MAP_FLASH0_RW_EL0, /* for firmware update service in standalone mm */
+#endif
+	V2M_MAP_FLASH1_RW_EL0, /* for secure variable service in standalone mm */
 	MAP_REGION_FLAT(DEVICE0_BASE,
 			DEVICE0_SIZE,
 			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
new file mode 100644
index 0000000..f2771c2
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if __aarch64__
+
+#include <aem_generic.h>
+#include <arch_helpers.h>
+#include <cortex_a35.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a78_ae.h>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <lib/utils_def.h>
+#include <neoverse_e1.h>
+
+bool check_cpupwrctrl_el1_is_available(void)
+{
+	/* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+	const unsigned int midr_no_cpupwrctl[] = {
+		BASE_AEM_MIDR,
+		CORTEX_A35_MIDR,
+		CORTEX_A53_MIDR,
+		CORTEX_A57_MIDR,
+		CORTEX_A72_MIDR,
+		CORTEX_A73_MIDR,
+		CORTEX_A78_AE_MIDR,
+		NEOVERSE_E1_MIDR
+	};
+	unsigned int midr = (unsigned int)read_midr();
+
+	for (unsigned int i = 0U; i < ARRAY_SIZE(midr_no_cpupwrctl); i++) {
+		if (midr_no_cpupwrctl[i] == midr) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+#endif /* __arch64__ */
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index f5bd722..83b52fc 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,91 +10,200 @@
 
 #include <plat/common/platform.h>
 
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
 static const uint8_t sample_platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x7a, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+	0x61, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x43, 0x43, 0x41, 0x2d, 0x53, 0x53, 0x44, 0x2f,
+	0x31, 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20,
+	0xb5, 0x97, 0x3c, 0xb6, 0x8b, 0xaa, 0x9f, 0xc5,
+	0x55, 0x58, 0x78, 0x6b, 0x7e, 0xc6, 0x7f, 0x69,
+	0xe4, 0x0d, 0xf5, 0xba, 0x5a, 0xa9, 0x21, 0xcd,
+	0x0c, 0x27, 0xf4, 0x05, 0x87, 0xa0, 0x11, 0xea,
+	0x19, 0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c,
 	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e,
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
 	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+	0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
+	0x0a, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b,
+	0x1a, 0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf,
+	0xcf, 0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30,
+	0x03, 0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78,
+	0x3a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+	0x2f, 0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f,
+	0x6e, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d,
+	0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76,
+	0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4,
+	0x01, 0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c,
+	0x31, 0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b,
+	0x6e, 0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3,
+	0x20, 0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d,
+	0x9b, 0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86,
+	0xaa, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47,
+	0x2b, 0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3,
+	0xfe, 0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb,
+	0xfd, 0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd,
+	0xd3, 0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53,
+	0x45, 0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f,
+	0x0a, 0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44,
+	0xea, 0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63,
+	0x4b, 0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02,
+	0xa2, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68,
+	0x51, 0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4,
+	0x4b, 0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7,
+	0x9e, 0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5,
+	0x01, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43,
+	0xa9, 0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7,
+	0x2c, 0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0,
+	0xa3, 0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c,
+	0x58, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f,
+	0xcd, 0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47,
+	0x61, 0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf,
+	0xaa, 0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d,
+	0x6f, 0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43,
+	0x50, 0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20,
+	0xf1, 0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58,
+	0x14, 0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2,
+	0x0f, 0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7,
+	0x61, 0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56,
+	0x02, 0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0,
+	0xbb, 0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65,
+	0x34, 0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c,
+	0x36, 0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c,
+	0x1f, 0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41,
+	0x50, 0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5,
+	0x98, 0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae,
+	0xfa, 0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6,
+	0x01, 0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9,
+	0x66, 0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63,
+	0x52, 0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae,
+	0x16, 0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6,
+	0x71, 0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17,
+	0x90, 0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81,
+	0x64, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02,
+	0x97, 0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17,
+	0x2b, 0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18,
+	0x31, 0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca,
+	0xae, 0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69,
+	0x46, 0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
+	0x47, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63,
+	0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15,
+	0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d,
+	0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa,
+	0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a,
+	0x92, 0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65,
+	0x8c, 0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56,
+	0x68, 0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c,
+	0x89, 0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06,
+	0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36,
+	0xa4, 0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57,
+	0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05,
+	0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53,
+	0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2,
+	0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60,
+	0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f,
+	0x7a, 0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03,
+	0x18, 0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b,
+	0x3f, 0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec,
+	0x0a, 0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc,
+	0x7c, 0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73,
+	0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01,
+	0x6d, 0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d,
+	0x26, 0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3,
+	0x39, 0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85,
+	0x29, 0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc,
+	0xe0, 0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x21,
+	0x51, 0x20, 0x92, 0xd6, 0xd0, 0x2a, 0xe6, 0xbe,
+	0x2f, 0xe3, 0x93, 0x0e, 0xa5, 0x1f, 0xd6, 0x98,
+	0x96, 0x32, 0x24, 0x56, 0xe9, 0xdf, 0xc7, 0x32,
+	0x5e, 0x0b, 0x78, 0x68, 0xb6, 0x90, 0x73, 0x2a,
+	0x0c, 0x0f, 0x07, 0x77, 0xc1, 0x15, 0x40, 0x4b,
+	0xe1, 0xfc, 0x83, 0x9b, 0x7d, 0x30, 0x4f, 0x4f,
+	0xe6, 0xfa, 0x46, 0xae, 0x12, 0xa3, 0x08, 0x3a,
+	0xcf, 0x24, 0x06, 0x67, 0x91, 0x06, 0xbf, 0xae,
+	0x50, 0x31, 0x79, 0xdd, 0x50, 0x33, 0x49, 0x12,
+	0xbf, 0xc6, 0xda, 0x33, 0x6d, 0xd6, 0x18, 0x25,
+	0x43, 0x54, 0x4d, 0xb5, 0x88, 0xd6, 0xae, 0x67,
+	0x35, 0x7a, 0xfd, 0xb0, 0x5f, 0x95, 0xb7
 };
 
 /*
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c0bba30..cef7bdf 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -24,7 +24,7 @@
 
 FVP_DT_PREFIX			:= fvp-base-gicv3-psci
 
-# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
+# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
 # the FVP platform. This option defaults to 256.
 FVP_TRUSTED_SRAM_SIZE		:= 256
 
@@ -57,6 +57,7 @@
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
 ENABLE_FEAT_CSV2_3		:= 2
+ENABLE_FEAT_DEBUGV8P9		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
 ENABLE_FEAT_VHE			:= 2
@@ -65,6 +66,7 @@
 ENABLE_TRF_FOR_NS		:= 2
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_FGT2		:= 2
 ENABLE_FEAT_TCR2		:= 2
 ENABLE_FEAT_S2PIE		:= 2
 ENABLE_FEAT_S1PIE		:= 2
@@ -222,6 +224,7 @@
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl1_setup.c		\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_err.c			\
 				plat/arm/board/fvp/fvp_io_storage.c		\
 				plat/arm/board/fvp/fvp_topology.c		\
@@ -252,7 +255,8 @@
 endif
 
 ifeq (${ENABLE_RME},1)
-BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				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
@@ -264,6 +268,7 @@
 
 ifeq (${RESET_TO_BL2},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
@@ -290,6 +295,7 @@
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
@@ -317,10 +323,6 @@
 BL31_SOURCES		+=	drivers/delay_timer/generic_delay_timer.c
 endif
 
-ifeq (${TRANSFER_LIST}, 1)
-include lib/transfer_list/transfer_list.mk
-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
@@ -380,6 +382,17 @@
 $(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
+
+ifeq ($(RESET_TO_BL31), 1)
+HW_CONFIG			:=	${FVP_HW_CONFIG}
+FW_HANDOFF_SIZE		:=	20000
+
+$(eval $(call add_define,ARM_PRELOADED_DTB_OFFSET))
+endif
+endif
+
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
diff --git a/plat/arm/board/fvp_ve/fvp_ve_def.h b/plat/arm/board/fvp_ve/fvp_ve_def.h
index 98de5f6..cb4b74c 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_def.h
+++ b/plat/arm/board/fvp_ve/fvp_ve_def.h
@@ -70,15 +70,4 @@
 #define FVP_VE_IRQ_TZ_WDOG			56
 #define FVP_VE_IRQ_SEC_SYS_TIMER		57
 
-#define V2M_FLASH1_BASE			UL(0x0C000000)
-#define V2M_FLASH1_SIZE			UL(0x04000000)
-
-#define V2M_MAP_FLASH1_RW		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
-						V2M_FLASH1_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define V2M_MAP_FLASH1_RO		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
-						V2M_FLASH1_SIZE,	\
-						MT_RO_DATA | MT_SECURE)
-
 #endif /* FVP_VE_DEF_H */
diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
index 8930dbb..d001dbe 100644
--- a/plat/arm/board/juno/juno_tbbr_cot_bl2.c
+++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
@@ -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
  */
@@ -745,6 +745,21 @@
 };
 #endif /* ETHOSN_NPU_TZMP1 */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
 
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index a00bf26..8eca0c5 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -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
 #
@@ -134,7 +134,7 @@
 endif
 
 bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
-	@echo "Building combined BL1 and ROMLIB binary for Juno $@"
+	$(s)echo "Building combined BL1 and ROMLIB binary for Juno $@"
 	./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
 
 # Errata workarounds for Cortex-A53:
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
new file mode 100644
index 0000000..bd2e682
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_CSS_DEF3_H
+#define NRD_CSS_DEF3_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* Shared RAM */
+#define NRD_CSS_SHARED_SRAM_BASE		UL(0x00000000)
+
+/* General Peripherals */
+#define NRD_CSS_PERIPH_BASE			UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE			UL(0x20000000)
+
+/* System NCI */
+#define NRD_CSS_SYSTEM_NCI_BASE			UL(0x20000000)
+#define NRD_CSS_SYSTEM_NCI_SIZE			UL(0x04000000)
+
+/* Debug NIC */
+#define NRD_CSS_DEBUG_NIC_BASE			UL(0x28000000)
+#define NRD_CSS_DEBUG_NIC_SIZE			UL(0x01000000)
+
+/* NS UART */
+#define NRD_CSS_NS_UART_BASE			UL(0x2A400000)
+#define NRD_CSS_NS_UART_SIZE			UL(0x00010000)
+
+/* Secure UART */
+#define NRD_CSS_SECURE_UART_BASE		UL(0x2A410000)
+#define NRD_CSS_SECURE_UART_SIZE		UL(0x00010000)
+
+/* Realm UART */
+#define NRD_CSS_REALM_UART_BASE			UL(0x2A420000)
+#define NRD_CSS_REALM_UART_SIZE			UL(0x00010000)
+
+/* Generic Refclk */
+#define NRD_CSS_GENERIC_REFCLK_BASE		UL(0x2A430000)
+#define NRD_CSS_GENERIC_REFCLK_SIZE		UL(0x00010000)
+
+/* NS Watchdog */
+#define NRD_CSS_AP_NS_WDOG_BASE			UL(0x2A440000)
+#define NRD_CSS_AP_NS_WDOG_SIZE			UL(0x00020000)
+
+/* Root Watchdog */
+#define NRD_CSS_AP_ROOT_WDOG_BASE		UL(0x2A460000)
+#define NRD_CSS_AP_ROOT_WDOG_SIZE		UL(0x00020000)
+
+/* Secure Watchdog */
+#define NRD_CSS_AP_SECURE_WDOG_BASE		UL(0x2A480000)
+#define NRD_CSS_AP_SECURE_WDOG_SIZE		UL(0x00020000)
+
+/* SID */
+#define NRD_CSS_SID_BASE			UL(0x2A4A0000)
+#define NRD_CSS_SID_SIZE			UL(0x00010000)
+
+/* SRAM Secure Error Record Block - AP */
+#define NRD_CSS_SECURE_SRAM_ERB_AP_BASE		UL(0x2A4B0000)
+#define NRD_CSS_SECURE_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM NS Error Record Block - AP */
+#define NRD_CSS_NS_SRAM_ERB_AP_BASE		UL(0x2A4C0000)
+#define NRD_CSS_NS_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - AP */
+#define NRD_CSS_ROOT_SRAM_ERB_AP_BASE		UL(0x2A4D0000)
+#define NRD_CSS_ROOT_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - AP */
+#define NRD_CSS_REALM_SRAM_ERB_AP_BASE		UL(0x2A4E0000)
+#define NRD_CSS_REALM_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - SCP */
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_BASE	UL(0x2A4F0000)
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - SCP */
+#define NRD_CSS_NS_SRAM_ERB_SCP_BASE		UL(0x2A500000)
+#define NRD_CSS_NS_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - SCP */
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_BASE		UL(0x2A510000)
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - SCP */
+#define NRD_CSS_REALM_SRAM_ERB_SCP_BASE		UL(0x2A520000)
+#define NRD_CSS_REALM_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - MCP */
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_BASE	UL(0x2A530000)
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - MCP */
+#define NRD_CSS_NS_SRAM_ERB_MCP_BASE		UL(0x2A540000)
+#define NRD_CSS_NS_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - MCP */
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_BASE		UL(0x2A550000)
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - MCP */
+#define NRD_CSS_REALM_SRAM_ERB_MCP_BASE		UL(0x2A560000)
+#define NRD_CSS_REALM_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - RSE */
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_BASE	UL(0x2A570000)
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - RSE */
+#define NRD_CSS_NS_SRAM_ERB_RSE_BASE		UL(0x2A580000)
+#define NRD_CSS_NS_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - RSE */
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_BASE		UL(0x2A590000)
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - RSE */
+#define NRD_CSS_REALM_SRAM_ERB_RSE_BASE		UL(0x2A5A0000)
+#define NRD_CSS_REALM_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5B0000)
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE	UL(0x2A5C0000)
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5D0000)
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A5E0000)
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5F0000)
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A600000)
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* CNTCTL Refclk Readframe */
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE	UL(0x2A800000)
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_SIZE	UL(0x00020000)
+
+/* CNTCTL base */
+#define NRD_CSS_SYS_TIMCTL_BASE			UL(0x2A810000)
+
+/* Secure Timer */
+#define NRD_CSS_SECURE_TIMER_CTL_BASE		UL(0x2A820000)
+#define NRD_CSS_SECURE_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* NS Timer */
+#define NRD_CSS_NS_TIMER_CTL_BASE		UL(0x2A830000)
+#define NRD_CSS_NS_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* AP - SCP NS MHU */
+#define NRD_CSS_AP_SCP_NS_MHU_BASE		UL(0x2A900000)
+#define NRD_CSS_AP_SCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Secure MHU */
+#define NRD_CSS_AP_SCP_SECURE_MHU_BASE		UL(0x2A920000)
+#define NRD_CSS_AP_SCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Root MHU */
+#define NRD_CSS_AP_SCP_ROOT_MHU_BASE		UL(0x2A940000)
+#define NRD_CSS_AP_SCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP NS MHU */
+#define NRD_CSS_AP_MCP_NS_MHU_BASE		UL(0x2AA00000)
+#define NRD_CSS_AP_MCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Secure MHU */
+#define NRD_CSS_AP_MCP_SECURE_MHU_BASE		UL(0x2AA20000)
+#define NRD_CSS_AP_MCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Root MHU */
+#define NRD_CSS_AP_MCP_ROOT_MHU_BASE		UL(0x2AA40000)
+#define NRD_CSS_AP_MCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_AP_RSE_NS_MHU_BASE		UL(0x2AB00000)
+#define NRD_CSS_AP_RSE_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Secure MHU */
+#define NRD_CSS_AP_RSE_SECURE_MHU_BASE		UL(0x2AB20000)
+#define NRD_CSS_AP_RSE_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Root MHU */
+#define NRD_CSS_AP_RSE_ROOT_MHU_BASE		UL(0x2AB40000)
+#define NRD_CSS_AP_RSE_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Realm MHU */
+#define NRD_CSS_AP_RSE_REALM_MHU_BASE		UL(0x2AB60000)
+#define NRD_CSS_AP_RSE_REALM_MHU_SIZE		UL(0x00020000)
+
+/* SCP - MCP - RSE Cross chip MHU */
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE	UL(0x2AC00000)
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE	UL(0x00120000)
+
+/* Synchronization Master Tupdate */
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE	UL(0x2B100000)
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE	UL(0x00030000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_STM_SYSTEM_ITS_BASE		UL(0x2CF00000)
+#define NRD_CSS_STM_SYSTEM_ITS_SIZE		UL(0x02100000)
+
+/* SCP - MCP - RSE Shared SRAM */
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE	UL(0x2F000000)
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE	UL(0x00400000)
+
+/* GIC base */
+#define NRD_CSS_GIC_BASE			UL(0x30000000)
+#define NRD_CSS_GIC_SIZE			UL(0x08000000)
+
+/* CMN */
+#define NRD_CSS_CMN_BASE			ULL(0x100000000)
+#define NRD_CSS_CMN_SIZE			UL(0x40000000)
+
+/* LCP Peripherals */
+#define NRD_CSS_LCP_PERIPHERAL_BASE		ULL(0x200000000)
+#define NRD_CSS_LCP_PERIPHERAL_SIZE		UL(0x40000000)
+
+/* DDR IO */
+#define NRD_CSS_DDR_IO_BASE			ULL(0x240000000)
+#define NRD_CSS_DDR_IO_SIZE			UL(0x40000000)
+
+/* SMMU & NCI IO */
+#define NRD_CSS_SMMU_NCI_IO_BASE		ULL(0x280000000)
+#define NRD_CSS_SMMU_NCI_IO_SIZE		UL(0x60000000)
+
+/* GPC SMMU */
+#define NRD_CSS_GPC_SMMUV3_BASE			UL(0x300000000)
+#define NRD_CSS_GPC_SMMUV3_SIZE			UL(0x8000000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_BASE			UL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE			ULL(0x8080000000)
+
+/*******************************************************************************
+ * MHUv3 related definitions
+ ******************************************************************************/
+
+#define MHU_V3_MBX_FRAME_OFFSET			UL(0x10000)
+
+/* MHUv3 Postbox and Mailbox register frame base */
+#define AP_RSE_ROOT_MHU_V3_PBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE
+#define AP_RSE_ROOT_MHU_V3_MBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#define AP_RSE_SECURE_MHU_V3_PBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE
+#define AP_RSE_SECURE_MHU_V3_MBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#endif /* NRD_CSS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
new file mode 100644
index 0000000..1b92ec2
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS-firmware specific definitions for the third
+ * generation of platforms.
+ */
+
+#ifndef NRD_CSS_FW_DEF3_H
+#define NRD_CSS_FW_DEF3_H
+
+#include <nrd_css_def3.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#define NRD_CSS_BL1_RO_BASE		NRD_CSS_SHARED_SRAM_BASE
+#define NRD_CSS_BL1_RO_SIZE		UL(0x00019000)
+
+# define NRD_CSS_BL2_SIZE		UL(0x30000)
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. NRD_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+#define NRD_CSS_DRAM1_CARVEOUT_SIZE	UL(0x0C000000)	/* 117MB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_AP_SECURE_WDOG_TIMEOUT	UL(100)
+
+/*******************************************************************************
+ * RMM Console Config
+ ******************************************************************************/
+
+#define NRD_CSS_RMM_CONSOLE_BASE		NRD_CSS_REALM_UART_BASE
+#define NRD_CSS_RMM_CONSOLE_BAUD		ARM_CONSOLE_BAUDRATE
+#define NRD_CSS_RMM_CONSOLE_CLK_IN_HZ		UL(14745600)
+#define NRD_CSS_RMM_CONSOLE_NAME		"pl011"
+#define NRD_CSS_RMM_CONSOLE_COUNT		UL(1)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_GPC_SMMU_SMMUV3_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_BL1_RW_MMAP						\
+		MAP_REGION_FLAT(					\
+			BL1_RW_BASE,					\
+			BL1_RW_LIMIT - BL1_RW_BASE,			\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_NS_DRAM1_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#define NRD_CSS_GPT_L1_DRAM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_EL3_RMM_SHARED_MEM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_EL3_RMM_SHARED_BASE,			\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#define NRD_CSS_RMM_REGION_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE,					\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#endif /* NRD_CSS_FW_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
new file mode 100644
index 0000000..f9a62ae
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_PAS_DEF3_H
+#define NRD_PAS_DEF3_H
+
+#ifndef __ASSEMBLER__
+#include <stddef.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
+
+#include <nrd_css_def3.h>
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/*
+ * =====================================================================
+ * Base Addr        |Size    |L? GPT |PAS    |Content                  |
+ * =====================================================================
+ * 0x00000000       |256MB   |L0 GPT |ANY    |SHARED RAM               |
+ * 0x0FFFFFFF       |        |       |       |AP EXPANSION             |
+ * ---------------------------------------------------------------------
+ * 0x20000000       |64MB    |L1 GPT |ROOT   |SYSTEM NCI               |
+ * 0x23FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x28000000       |16MB    |L1 GPT |SECURE |DEBUG NIC                |
+ * 0x28FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A400000       |64KB    |L1 GPT |NS     |NS UART                  |
+ * 0x2A40FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A410000       |64KB    |L1 GPT |SECURE |SECURE UART              |
+ * 0x2A41FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A420000       |64KB    |L1 GPT |REALM  |REALM UART               |
+ * 0x2A42FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A430000       |64KB    |L1 GPT |SECURE |GENERIC REFCLK           |
+ * 0x2A43FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A440000       |128KB   |L1 GPT |NS     |AP NS WDOG               |
+ * 0x2A45FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A460000       |128KB   |L1 GPT |ROOT   |AP ROOT WDOG             |
+ * 0x2A47FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A480000       |128KB   |L1 GPT |SECURE |AP SECURE WDOG           |
+ * 0x2A49FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4A0000       |64KB    |L1 GPT |NS     |SID                      |
+ * 0x2A4AFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4B0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4BFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4C0000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A4CFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4D0000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A4DFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4E0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A4EFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4F0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4FFFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A500000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A50FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A510000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A51FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A520000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A52FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A530000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A53FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A540000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A54FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A550000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A55FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A560000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A56FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A570000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A57FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A580000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A58FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A590000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A59FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5A0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A5AFFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5B0000       |64KB    |L1 GPT |SECURE |RSE SECURE SRAM ERROR    |
+ * 0x2A5BFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5C0000       |64KB    |L1 GPT |NS     |RSE NS SRAM ERROR        |
+ * 0x2A5CFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5D0000       |64KB    |L1 GPT |SECURE |SCP SECURE SRAM ERROR    |
+ * 0x2A5DFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5E0000       |64KB    |L1 GPT |NS     |SCP NS SRAM ERROR        |
+ * 0x2A5EFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5F0000       |64KB    |L1 GPT |SECURE |MCP SECURE SRAM ERROR    |
+ * 0x2A5FFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A600000       |64KB    |L1 GPT |NS     |MCP NS SRAM ERROR        |
+ * 0x2A60FFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A800000       |128KB   |L1 GPT |NS     |CNTCTL REFCLK            |
+ * 0x2A81FFFF       |        |       |       |READ FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A820000       |64KB    |L1 GPT |SECURE |SECURE TIMER CTL         |
+ * 0x2A82FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A830000       |64KB    |L1 GPT |NS     |NS TIMER CTL             |
+ * 0x2A83FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A900000       |128KB   |L1 GPT |NS     |AP-SCP NS                |
+ * 0x2A91FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A920000       |128KB   |L1 GPT |SECURE |AP-SCP SECURE            |
+ * 0x2A93FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A940000       |128KB   |L1 GPT |ROOT   |AP-SCP ROOT              |
+ * 0x2A95FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AA1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA20000       |128KB   |L1 GPT |SECURE |AP-MCP SECURE            |
+ * 0x2AA3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA40000       |128KB   |L1 GPT |ROOT   |AP-MCP ROOT              |
+ * 0x2AA5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AB1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB20000       |128KB   |L1 GPT |SECURE |AP-RSE SECURE            |
+ * 0x2AB3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB40000       |128KB   |L1 GPT |ROOT   |AP-RSE ROOT              |
+ * 0x2AB5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB60000       |128KB   |L1 GPT |REALM  |AP-RSE REALM             |
+ * 0x2AB7FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AC00000       |1152KB  |L1 GPT |ROOT   |SCP MCP RSE              |
+ * 0x2ACEFFFF       |        |       |       |CROSS CHIP MHU           |
+ * ---------------------------------------------------------------------
+ * 0x2B100000       |192KB   |L1 GPT |SECURE |SYNCNT                   |
+ * 0x2B12FFFF       |        |       |       |MSTUPDTVAL_ADDR          |
+ * ---------------------------------------------------------------------
+ * 0x2CF00000       |~33MB   |L1 GPT |NS     |STM SYSTEM ITS           |
+ * 0x2EFFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2F000000       |4MB     |L1 GPT |ANY    |SHARED SRAM              |
+ * 0x2F3FFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x30000000       |128MB   |L1 GPT |ANY    |GIC CLAYTON              |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2GB -   |L1 GPT |NS     |NS DRAM                  |
+ * 0xFFFE2BFF       |117MB   |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |26MB    |L1 GPT |REALM  |RMM                      |
+ * 0x37FFFFFF       |        |       |       |TF-A SHARED              |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2MB     |L1 GPT |ROOT   |L1GPT                    |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 3            |
+ * 0x1000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 2            |
+ * 0x2000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 1            |
+ * 0x3000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100000000      |1GB     |L1 GPT |ANY    |CMN                      |
+ * 0x13FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200000000      |1GB     |L1 GPT |ANY    |LCP PERIPHERALS          |
+ * 0x23FFFFFFF      |        |       |       |DDR                      |
+ * ---------------------------------------------------------------------
+ * 0x240000000      |1GB     |L1 GPT |ANY    |DDR IO                   |
+ * 0x27FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x280000000      |1.5GB   |L1 GPT |ANY    |SMMU & NCI IO            |
+ * 0x2DFFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300000000      |128MB   |L1 GPT |ROOT   |GPC SMMU                 |
+ * 0x308000000      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x8080000000     |6GB     |L1 GPT |ANY    |DRAM 2 CHIP 0            |
+ * 0x81FFFFFFFF     |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x108080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 1            |
+ * 0x1081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x208080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 2            |
+ * 0x2081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x308080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 3            |
+ * 0x3081FFFFFFFF   |        |       |       |                         |
+ * =====================================================================
+ */
+
+/*******************************************************************************
+ * Multichip config
+ ******************************************************************************/
+
+#define NRD_MC_BASE(base, n)		(NRD_REMOTE_CHIP_MEM_OFFSET(n) + base)
+
+/*******************************************************************************
+ * PAS mappings
+ ******************************************************************************/
+
+#define NRD_PAS_SHARED_SRAM						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SHARED_SRAM_BASE,			\
+			NRD_CSS_SHARED_SRAM_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SYSTEM_NCI						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYSTEM_NCI_BASE,			\
+			NRD_CSS_SYSTEM_NCI_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DEBUG_NIC						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DEBUG_NIC_BASE,				\
+			NRD_CSS_DEBUG_NIC_SIZE,				\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_UART							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_UART_BASE,				\
+			NRD_CSS_NS_UART_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_REALM_UART						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_UART_BASE,			\
+			NRD_CSS_REALM_UART_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_AP_NS_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_NS_WDOG_BASE,			\
+			NRD_CSS_AP_NS_WDOG_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_ROOT_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_ROOT_WDOG_BASE,			\
+			NRD_CSS_AP_ROOT_WDOG_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_SECURE_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SECURE_WDOG_BASE,			\
+			NRD_CSS_AP_SECURE_WDOG_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SECURE_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_AP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_AP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_AP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_REALM_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_SCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_MCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_RSE						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_RSE_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_RSE_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_MCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define	NRD_PAS_MCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_SCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_SCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_MCP_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_NS_MHU_BASE,			\
+			NRD_CSS_AP_MCP_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_MCP_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_MCP_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_MCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_MCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_NS_MHU_BASE,			\
+			NRD_CSS_AP_RSE_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_RSE_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_RSE_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_RSE_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_RSE_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_REALM_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_REALM_MHU_BASE,			\
+			NRD_CSS_AP_RSE_REALM_MHU_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU				\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE,	\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE,	\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE,		\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_STM_SYSTEM_ITS						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_STM_SYSTEM_ITS_BASE,			\
+			NRD_CSS_STM_SYSTEM_ITS_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_MCP_RSE_SHARED_SRAM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE,		\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE,		\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GIC							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GIC_BASE,				\
+			NRD_CSS_GIC_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_NS_DRAM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 1),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 2),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 3),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_RMM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE +				\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_L1GPT							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_CMN							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_CMN_BASE,				\
+			NRD_CSS_CMN_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_LCP_PERIPHERAL						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_LCP_PERIPHERAL_BASE,			\
+			NRD_CSS_LCP_PERIPHERAL_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_DDR_IO							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DDR_IO_BASE,				\
+			NRD_CSS_DDR_IO_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SMMU_NCI_IO						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SMMU_NCI_IO_BASE,			\
+			NRD_CSS_SMMU_NCI_IO_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GPC_SMMUV3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DRAM2_CHIP0						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 0),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 1),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 2),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 3),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#endif /* NRD_PAS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
new file mode 100644
index 0000000..0dce512
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
@@ -0,0 +1,756 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the platform port definitions for the
+ * third generation of platforms.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF3_H
+#define NRD_PLAT_ARM_DEF3_H
+
+#include <common/tbbr/tbbr_img_def.h>
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/common/common_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT		(NRD_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					NRD_MAX_CPUS_PER_CLUSTER *	\
+					NRD_MAX_PE_PER_CPU)
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage. In addition to that, on
+ * multi-chip platforms, address regions on each of the remote chips are
+ * also mapped. In BL31, for instance, three address regions on the remote
+ * chips are accessed - secure ram, css device and soc device regions.
+ */
+#if defined(IMAGE_BL31)
+#  define PLAT_ARM_MMAP_ENTRIES		(9 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(9 + ((NRD_CHIP_COUNT - 1) * 3))
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(16 + (NRD_CHIP_COUNT - 1))
+# define MAX_XLAT_TABLES		(11  + ((NRD_CHIP_COUNT - 1) * 2))
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(7)
+# define MAX_XLAT_TABLES		U(7)
+#endif
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * BL31 plat param
+ ******************************************************************************/
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
+
+/*******************************************************************************
+ * Stack sizes
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		UL(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		UL(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		UL(0x440)
+#endif
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define ARM_CONSOLE_BAUDRATE		(115200)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * System counter and timer config
+ ******************************************************************************/
+
+#define ARM_SYS_CNTCTL_BASE		NRD_CSS_GENERIC_REFCLK_BASE
+#define ARM_SYS_CNTREAD_BASE		NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE
+#define ARM_SYS_TIMCTL_BASE		NRD_CSS_SYS_TIMCTL_BASE
+#define ARM_SYS_CNT_BASE_S		NRD_CSS_SECURE_TIMER_CTL_BASE
+#define ARM_SYS_CNT_BASE_NS		NRD_CSS_NS_TIMER_CTL_BASE
+
+/*******************************************************************************
+ * SRAM and DRAM config for FW
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_SECURE_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_SECURE_ROM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_SECURE_SRAM_SIZE
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	(0)
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NS_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NS_SRAM_SIZE
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+/*
+ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
+ * power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define ARM_PWR_LVL0			MPIDR_AFFLVL0
+#define ARM_PWR_LVL1			MPIDR_AFFLVL1
+#define ARM_PWR_LVL2			MPIDR_AFFLVL2
+#define ARM_PWR_LVL3			MPIDR_AFFLVL3
+
+/* Local power state for power domains in Run state. */
+#define ARM_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define ARM_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains
+ */
+#define ARM_LOCAL_STATE_OFF		U(2)
+/*
+ * 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		ARM_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		ARM_LOCAL_STATE_OFF
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * MHU config
+ ******************************************************************************/
+
+#define PLAT_CSS_MHU_BASE		NRD_CSS_AP_SCP_SECURE_MHU_BASE
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+/*******************************************************************************
+ * Cache config
+ ******************************************************************************/
+
+#define ARM_CACHE_WRITEBACK_SHIFT	U(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		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+/* CPU Fault Handling Interrupt(FHI) PPI interrupt ID */
+#define PLAT_CORE_FAULT_IRQ		U(17)
+
+/* ARM platforms use 3 upper bits of secure interrupt priority */
+#define PLAT_PRI_BITS			U(3)
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_RAS_PRI			U(0x10)
+#endif
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI			U(0x10)
+#endif
+
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+#define ARM_G0_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,		\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define ARM_G1S_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_LEVEL),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+#define ARM_G0_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,		\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#define PLAT_ARM_GICD_BASE		NRD_CSS_GIC_BASE
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00100000)
+#else
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x001C0000)
+#endif
+
+/*******************************************************************************
+ * SDEI config
+ ******************************************************************************/
+
+#define PLAT_SDEI_CRITICAL_PRI		U(0x60)
+#define PLAT_SDEI_NORMAL_PRI		U(0x70)
+
+/* SGI used for SDEI signalling */
+#define ARM_SDEI_SGI			ARM_IRQ_SEC_SGI_0
+
+#if SDEI_IN_FCONF
+/* ARM SDEI dynamic private event max count */
+#define ARM_SDEI_DP_EVENT_MAX_CNT	U(3)
+
+/* ARM SDEI dynamic shared event max count */
+#define ARM_SDEI_DS_EVENT_MAX_CNT	U(3)
+#else
+/* ARM SDEI dynamic private event numbers */
+#define ARM_SDEI_DP_EVENT_0		UL(1000)
+#define ARM_SDEI_DP_EVENT_1		UL(1001)
+#define ARM_SDEI_DP_EVENT_2		UL(1002)
+
+/* ARM SDEI dynamic shared event numbers */
+#define ARM_SDEI_DS_EVENT_0		UL(2000)
+#define ARM_SDEI_DS_EVENT_1		UL(2001)
+#define ARM_SDEI_DS_EVENT_2		UL(2002)
+
+#define ARM_SDEI_PRIVATE_EVENTS						\
+	SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_0,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_1,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+
+#define ARM_SDEI_SHARED_EVENTS						\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+#endif /* SDEI_IN_FCONF */
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+
+/*******************************************************************************
+ * SMMUv3 Config
+ ******************************************************************************/
+
+/* SMMUv3 root offset register */
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET	UL(0xA0000)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR	NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00FE00E0)
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define V2M_SYS_LED			U(0x8)
+
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
+
+#define V2M_SYSREGS_BASE		NRD_ROS_SYSTEM_PERIPH_BASE +	\
+						UL(0x00010000)
+#define V2M_FLASH0_BASE			NRD_ROS_SMC0_BASE
+#define V2M_FLASH0_SIZE			NRD_ROS_SMC0_SIZE
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE +	\
+					V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*******************************************************************************
+ * ROS peripheral config
+ ******************************************************************************/
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00E70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE	+ 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * SRAM layout
+ ******************************************************************************/
+
+/*
+ *              Trusted SRAM
+ * 0x00100000 +--------------+
+ *            |    L0 GPT    |
+ * 0x000E0000 +--------------+  loaded by BL2  +----------------+
+ *            |   BL1 (rw)   |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |  BL31 NOBITS   |
+ *            |     BL2      |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |----------------|
+ *            |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
+ *            |              |                 +----------------+
+ *            +--------------+
+ *            |    CONFIG    |
+ * 0x0001A000 +--------------+
+ *            |    Shared    |
+ * 0x00019000 +--------------+
+ *            |   BL1 (ro)   |
+ * 0x00000000 +--------------+
+ */
+
+/*******************************************************************************
+ * BL1 RO specifics
+ ******************************************************************************/
+
+/*
+ * SRAM region to store BL1 code and RO. This has been carved out at the bottom
+ * of SRAM
+ */
+
+#define BL1_RO_BASE			NRD_CSS_BL1_RO_BASE
+#define BL1_RO_LIMIT			(NRD_CSS_BL1_RO_BASE		\
+					 + NRD_CSS_BL1_RO_SIZE)
+
+/*******************************************************************************
+ * L0 GPT specifics
+ ******************************************************************************/
+
+/*
+ * L0 GPT has to be aligned to its size. In order to avoid holes due to
+ * alignment, place L0 GPT at the top of SRAM.
+ */
+#define ARM_L0_GPT_SIZE			UL(0x00020000) /* 128KB */
+#define ARM_L0_GPT_BASE			NRD_CSS_SHARED_SRAM_SIZE -	\
+					ARM_L0_GPT_SIZE
+
+#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
+
+/*******************************************************************************
+ * Arm shared RAM specifics
+ ******************************************************************************/
+
+#define ARM_SHARED_RAM_BASE		(NRD_CSS_BL1_RO_BASE +		\
+					 NRD_CSS_BL1_RO_SIZE)
+#define ARM_SHARED_RAM_SIZE		UL(0x00001000)	/* 4 KB */
+
+/*******************************************************************************
+ * Arm BL RAM specifics
+ ******************************************************************************/
+
+/*Rest of SRAM till L0 GPT base */
+#define ARM_BL_RAM_BASE			(ARM_SHARED_RAM_BASE +		\
+					 ARM_SHARED_RAM_SIZE)
+#define ARM_BL_RAM_SIZE			(ARM_L0_GPT_BASE -		\
+					 ARM_BL_RAM_BASE)
+
+/*******************************************************************************
+ * FW_CONFIG specifics
+ ******************************************************************************/
+
+/*
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
+ * and limit. Leave enough space of BL2 meminfo.
+ */
+#define ARM_FW_CONFIG_BASE		(ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT		((ARM_BL_RAM_BASE + PAGE_SIZE) \
+					+ (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE		(ARM_FW_CONFIG_LIMIT)
+#define ARM_BL2_MEM_DESC_LIMIT		(ARM_BL2_MEM_DESC_BASE		\
+					+ (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+
+/*******************************************************************************
+ * BL1 RW specifics
+ ******************************************************************************/
+
+#define BL1_RW_BASE			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE -		\
+					 PLAT_ARM_MAX_BL1_RW_SIZE)
+#define BL1_RW_LIMIT			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+
+/* Put BL2 just below BL1. */
+#define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL1_RW_BASE
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+
+/* Keep BL31 below BL2 in the Trusted SRAM.*/
+#define BL31_BASE			((ARM_BL_RAM_BASE +		\
+					  ARM_BL_RAM_SIZE) -		\
+					  PLAT_ARM_MAX_BL31_SIZE)
+#define BL31_PROGBITS_LIMIT		BL2_BASE
+#define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+
+/*
+ * The max number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+#define ARM_BL_REGIONS			7
+
+#define MAX_MMAP_REGIONS		(PLAT_ARM_MMAP_ENTRIES +	\
+					 ARM_BL_REGIONS)
+
+/*******************************************************************************
+ * DRAM layout
+ ******************************************************************************/
+
+/*
+ * The top 100MB of DRAM1 is configured as follows:
+ *   - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
+ *   - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
+ *   - REALM DRAM: Reserved for Realm world if RME is enabled
+ *
+ *                    DRAM layout
+ *               +------------------+
+ *               |   REALM (RMM)    |
+ *               |   (32MB - 4KB)   |
+ *               +------------------+
+ *               |                  |
+ *               |   TF-A <-> RMM   |
+ *               |   SHARED (4KB)   |
+ *               +------------------+
+ *               |       L1 GPT     |
+ *               |                  |
+ *     DRAM1 End +------------------+
+ */
+
+/* Number of DRAM banks */
+#if (NRD_PLATFORM_VARIANT == 2)
+#define ARM_DRAM_NUM_BANKS		U(8)
+#else
+#define ARM_DRAM_NUM_BANKS		U(2)
+#endif
+
+/*******************************************************************************
+ * DRAM bank1 specific defines.
+ ******************************************************************************/
+
+/* Bank-1 DRAM */
+#define ARM_DRAM1_BASE			UL(0x80000000)
+#define ARM_DRAM1_SIZE			UL(0x80000000)
+#define ARM_DRAM1_END			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * DRAM bank2 specific defines.
+ ******************************************************************************/
+
+/* Bank-2 DRAM */
+#define ARM_DRAM2_BASE			PLAT_ARM_DRAM2_BASE
+#define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
+#define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
+					 ARM_DRAM2_SIZE - 1U)
+
+/*******************************************************************************
+ * L1GPT specific defines.
+ ******************************************************************************/
+
+/* 2MB per L1 entry, PPS - 48 bits, PGS - 4KB, L0GPTSZ - 16GB */
+#define ARM_L1_GPT_SIZE			(UL(40 * 1024 * 1024) +		\
+					((NRD_CHIP_COUNT - 1) *		\
+					(4 * 1024 * 1024)))
+
+#define ARM_L1_GPT_BASE			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 ARM_L1_GPT_SIZE)
+#define ARM_L1_GPT_END			(ARM_L1_GPT_BASE +		\
+					 ARM_L1_GPT_SIZE - 1U)
+
+/*******************************************************************************
+ * "RMM TF-A shared region" specific defines.
+ ******************************************************************************/
+
+/* PLAT_ARM_EL3_RMM_SHARED_SIZE */
+#define ARM_EL3_RMM_SHARED_SIZE		(PAGE_SIZE)    /* 4KB */
+
+#define ARM_EL3_RMM_SHARED_BASE		(ARM_L1_GPT_BASE -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+
+#define ARM_EL3_RMM_SHARED_END		(ARM_EL3_RMM_SHARED_BASE +	\
+					 ARM_EL3_RMM_SHARED_SIZE - 1U)
+
+/*******************************************************************************
+ * RMM specific defines.
+ ******************************************************************************/
+
+/* ARM_REALM_SIZE */
+#define ARM_REALM_SIZE			(UL(0x02600000) -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+#define ARM_REALM_BASE			(ARM_EL3_RMM_SHARED_BASE -	\
+					 ARM_REALM_SIZE)
+
+#define ARM_REALM_END			(ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
+
+#define RMM_BASE			(ARM_REALM_BASE)
+#define RMM_LIMIT			(RMM_BASE + ARM_REALM_SIZE)
+#define RMM_SHARED_BASE			(ARM_EL3_RMM_SHARED_BASE)
+#define RMM_SHARED_SIZE			(ARM_EL3_RMM_SHARED_SIZE)
+
+/*******************************************************************************
+ * NRD_CSS_CARVEOUT_RESERVED region specific defines.
+ ******************************************************************************/
+
+#define NRD_CSS_CARVEOUT_RESERVED_BASE	(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+#define NRD_CSS_CARVEOUT_RESERVED_SIZE	(NRD_CSS_DRAM1_CARVEOUT_SIZE -	\
+					(ARM_EL3_RMM_SHARED_SIZE +	\
+					 ARM_REALM_SIZE +		\
+					 ARM_L1_GPT_SIZE))
+
+#define NRD_CSS_CARVEOUT_RESERVED_END	(NRD_CSS_CARVEOUT_RESERVED_BASE +\
+					 NRD_CSS_CARVEOUT_RESERVED_SIZE - 1U)
+
+/*******************************************************************************
+ * NS RAM specific defines specific defines.
+ ******************************************************************************/
+
+#define ARM_NS_DRAM1_BASE		ARM_DRAM1_BASE
+#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+
+#define ARM_NS_DRAM1_END		(ARM_NS_DRAM1_BASE +		\
+					 ARM_NS_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define V2M_MAP_FLASH0_RW						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define V2M_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_RO_DATA | EL3_PAS)
+
+#define ARM_MAP_L0_GPT_REGION						\
+		MAP_REGION_FLAT(					\
+			ARM_L0_GPT_BASE,				\
+			ARM_L0_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | MT_ROOT)
+
+#define ARM_MAP_BL_CONFIG_REGION					\
+		MAP_REGION_FLAT(					\
+			ARM_BL_RAM_BASE,				\
+			(ARM_FW_CONFIGS_LIMIT - ARM_BL_RAM_BASE),	\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#if SEPARATE_CODE_AND_RODATA
+#define ARM_MAP_BL_RO							\
+		MAP_REGION_FLAT(					\
+			BL_CODE_BASE,					\
+			(BL_CODE_END - BL_CODE_BASE),			\
+			MT_CODE | EL3_PAS),				\
+		MAP_REGION_FLAT(					\
+			BL_RO_DATA_BASE,				\
+			(BL_RO_DATA_END - BL_RO_DATA_BASE),		\
+			MT_RO_DATA | EL3_PAS)
+#else
+#define ARM_MAP_BL_RO							\
+		MAP_REGION_FLAT(					\
+			BL_CODE_BASE,					\
+			(BL_CODE_END - BL_CODE_BASE),			\
+			MT_CODE | EL3_PAS)
+#endif
+
+#if USE_COHERENT_MEM
+#define ARM_MAP_BL_COHERENT_RAM						\
+		MAP_REGION_FLAT(					\
+			BL_COHERENT_RAM_BASE,				\
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,	\
+			MT_DEVICE | MT_RW | EL3_PAS)
+#endif
+
+#define ARM_MAP_DRAM2							\
+		MAP_REGION_FLAT(					\
+			ARM_DRAM2_BASE,					\
+			ARM_DRAM2_SIZE,					\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#endif /* NRD_PLAT_ARM_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
new file mode 100644
index 0000000..c987621
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the RoS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_ROS_DEF3_H
+#define NRD_ROS_DEF3_H
+
+/*******************************************************************************
+ * RoS memory map related defines
+ ******************************************************************************/
+
+/* System peripherals */
+#define NRD_ROS_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define NRD_ROS_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+/* Platform peripherals */
+#define NRD_ROS_PLATFORM_PERIPH_BASE		UL(0x0E000000)
+#define NRD_ROS_PLATFORM_PERIPH_SIZE		UL(0x02000000)
+
+/* SMC0 */
+#define NRD_ROS_SMC0_BASE			UL(0x08000000)
+#define NRD_ROS_SMC0_SIZE			UL(0x04000000)
+
+#endif /* NRD_ROS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
new file mode 100644
index 0000000..c0fde85
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * third generation of platforms. RoS (Rest Of System) is used to refer to the
+ * part of the reference design platform that excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF3_H
+#define NRD_ROS_FW_DEF3_H
+
+#include <nrd_ros_def3.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PLATFORM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SYSTEM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEM_PERIPH_BASE,			\
+			NRD_ROS_SYSTEM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_V2M_MEM_PROTECT_MMAP					\
+		MAP_REGION_FLAT(					\
+			PLAT_ARM_MEM_PROT_ADDR,				\
+			V2M_FLASH_BLOCK_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_ROS_FLASH0_RO_MMAP						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+#endif /* NRD_ROS_FW_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_variant.h b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
index 94f80c3..86d82e2 100644
--- a/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
@@ -28,6 +28,14 @@
 #define RD_V2_SID_VER_PART_NUM			0x07F2
 #define RD_V2_CONFIG_ID				0x1
 
+/* SID Version values for RD-V3 */
+#define RD_V3_SID_VER_PART_NUM		0x07EE
+#define RD_V3_CONFIG_ID			0x0
+
+/* SID Version values for RD-V3 variants */
+#define RD_V3_CFG1_SID_VER_PART_NUM	0x07F9
+#define RD_V3_CFG2_SID_VER_PART_NUM	0x07EE
+
 /* Structure containing Neoverse RD platform variant information */
 typedef struct nrd_platform_info {
 	unsigned int platform_id;	/* Part Number of the platform */
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 a22c799..18aa2fb 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -73,6 +73,52 @@
 	#endif
 };
 
+static scmi_channel_plat_info_t plat3_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#if (NRD_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+};
+
 scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 	if (nrd_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
@@ -85,6 +131,13 @@
 			panic();
 		}
 		return &plat_rd_scmi_info[channel_id];
+	} else if (nrd_plat_info.platform_id == RD_V3_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V3_CFG1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V3_CFG2_SID_VER_PART_NUM) {
+		if (channel_id >= ARRAY_SIZE(plat3_rd_scmi_info)) {
+			panic();
+		}
+		return &plat3_rd_scmi_info[channel_id];
 	} else if (nrd_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) {
 		return &sgi575_scmi_plat_info;
 	} else {
diff --git a/plat/arm/board/neoverse_rd/common/nrd_plat3.c b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
new file mode 100644
index 0000000..7b98052
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/utils_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL3 */
+
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_NS_DRAM1_MMAP,
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
+	NRD_CSS_BL1_RW_MMAP,
+#endif
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_RMM_REGION_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL2 */
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_EL3_RMM_SHARED_MEM_MMAP,
+	NRD_CSS_GPC_SMMU_SMMUV3_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL31 */
+
+ARM_CASSERT_MMAP
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(NRD_CSS_AP_SECURE_WDOG_BASE,
+			NRD_CSS_AP_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(NRD_CSS_AP_SECURE_WDOG_BASE);
+}
+
+static sds_region_desc_t nrd_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
+
+	return nrd_sds_regions;
+}
diff --git a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
index 371bde6..cf1eb6f 100644
--- a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
@@ -62,37 +62,50 @@
 	cpu_info->SecurityState = security_state;
 
 	/* populate CPU EL1 context information. */
-	cpu_info->ErrCtxEl1Reg[0]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_ELR_EL1);
-	cpu_info->ErrCtxEl1Reg[1]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_ESR_EL1);
-	cpu_info->ErrCtxEl1Reg[2]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_FAR_EL1);
+	cpu_info->ErrCtxEl1Reg[0]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  elr_el1);
+	cpu_info->ErrCtxEl1Reg[1]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  esr_el1);
+	cpu_info->ErrCtxEl1Reg[2]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  far_el1);
 	cpu_info->ErrCtxEl1Reg[3]  = read_isr_el1();
-	cpu_info->ErrCtxEl1Reg[4]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_MAIR_EL1);
+	cpu_info->ErrCtxEl1Reg[4]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  mair_el1);
 	cpu_info->ErrCtxEl1Reg[5]  = read_midr_el1();
 	cpu_info->ErrCtxEl1Reg[6]  = read_mpidr_el1();
-	cpu_info->ErrCtxEl1Reg[7]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SCTLR_EL1);
+
+#if (ERRATA_SPECULATIVE_AT)
+	cpu_info->ErrCtxEl1Reg[7]  = read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+						  CTX_ERRATA_SPEC_AT_SCTLR_EL1);
+#else
+	cpu_info->ErrCtxEl1Reg[7]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  sctlr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+
 	cpu_info->ErrCtxEl1Reg[8]  = read_ctx_reg(get_gpregs_ctx(ctx),
 						  CTX_GPREG_SP_EL0);
-	cpu_info->ErrCtxEl1Reg[9]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SP_EL1);
-	cpu_info->ErrCtxEl1Reg[10] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SPSR_EL1);
-	cpu_info->ErrCtxEl1Reg[11] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TCR_EL1);
-	cpu_info->ErrCtxEl1Reg[12] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDR_EL0);
-	cpu_info->ErrCtxEl1Reg[13] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDR_EL1);
-	cpu_info->ErrCtxEl1Reg[14] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDRRO_EL0);
-	cpu_info->ErrCtxEl1Reg[15] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TTBR0_EL1);
-	cpu_info->ErrCtxEl1Reg[16] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TTBR1_EL1);
+	cpu_info->ErrCtxEl1Reg[9]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  sp_el1);
+	cpu_info->ErrCtxEl1Reg[10] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  spsr_el1);
+#if (ERRATA_SPECULATIVE_AT)
+	cpu_info->ErrCtxEl1Reg[11]  = read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+						   CTX_ERRATA_SPEC_AT_TCR_EL1);
+#else
+	cpu_info->ErrCtxEl1Reg[11] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tcr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+
+	cpu_info->ErrCtxEl1Reg[12] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidr_el0);
+	cpu_info->ErrCtxEl1Reg[13] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidr_el1);
+	cpu_info->ErrCtxEl1Reg[14] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidrro_el0);
+	cpu_info->ErrCtxEl1Reg[15] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  ttbr0_el1);
+	cpu_info->ErrCtxEl1Reg[16] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  ttbr1_el1);
 
 #if CTX_INCLUDE_EL2_REGS
 	cpu_info->ErrCtxEl2Reg[0]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
new file mode 100644
index 0000000..62ba0fa
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		tb_fw-config {
+			load-address = <0x0 0x01f300>;
+			max-size = <0x200>;
+			id = <TB_FW_CONFIG_ID>;
+		};
+
+		nt_fw-config {
+			load-address = <0x0 0xF3000000>;
+			max-size = <0x0100000>;
+			id = <NT_FW_CONFIG_ID>;
+		};
+	};
+};
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
new file mode 100644
index 0000000..941d4a0
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+	/* compatible string */
+	compatible = "arm,rd-v3";
+
+	/*
+	 * Place holder for system-id node with default values. The
+	 * value of platform-id and config-id will be set to the
+	 * correct values during the BL2 stage of boot.
+	 */
+	system-id {
+		platform-id = <0x0>;
+		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
+	};
+};
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
new file mode 100644
index 0000000..a4c7c72
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	tb_fw-config {
+		compatible = "arm,tb_fw";
+
+		/* Disable authentication for development */
+		disable_auth = <0x0>;
+
+		/*
+		 * The following two entries are placeholders for Mbed TLS
+		 * heap information. The default values don't matter since
+		 * they will be overwritten by BL1.
+		 * In case of having shared Mbed TLS heap between BL1 and BL2,
+		 * BL1 will populate these two properties with the respective
+		 * info about the shared heap. This info will be available for
+		 * BL2 in order to locate and re-use the heap.
+		 */
+		mbedtls_heap_addr = <0x0 0x0>;
+		mbedtls_heap_size = <0x0>;
+	};
+};
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
new file mode 100644
index 0000000..b55dbe8
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/arm/css/common/css_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_pas_def3.h>
+#include <nrd_plat_arm_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+/* PE-Cluster count */
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_CLUSTER_COUNT		U(8)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define PLAT_ARM_CLUSTER_COUNT		U(4)
+#else
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#endif
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+/* Shared RAM*/
+#define NRD_CSS_SHARED_SRAM_SIZE	UL(0x000100000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_SIZE		ULL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000)
+
+/* Address bits */
+#define NRD_ADDR_BITS_PER_CHIP		U(36)  /* 64GB */
+
+/*
+ * In the current implementation, the RoT Service request that requires the
+ * biggest message buffer is the RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * maximum required buffer size is calculated based on the platform-specific
+ * needs of this request.
+ */
+#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE	UL(0x1000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
new file mode 100644
index 0000000..fa64963
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDV3_MHUV3_H
+#define RDV3_MHUV3_H
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender);
+
+#endif /* RDV3_MHUV3_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
new file mode 100644
index 0000000..cb8e786
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDV3_RSE_COMMS_H
+#define RDV3_RSE_COMMS_H
+
+int plat_rse_comms_init(void);
+
+#endif /* RDV3_RSE_COMMS_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
new file mode 100644
index 0000000..7d770f5
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
@@ -0,0 +1,139 @@
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RD_V3_VARIANTS := 0 1 2
+ifneq ($(NRD_PLATFORM_VARIANT),						\
+	$(filter $(NRD_PLATFORM_VARIANT),$(RD_V3_VARIANTS)))
+	$(error "NRD_PLATFORM_VARIANT for RD-V3 should be 0, 1, or 2,"
+	"currently set to ${NRD_PLATFORM_VARIANT}.")
+endif
+
+$(eval $(call CREATE_SEQ,SEQ,4))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
+	$(error  "Chip count for RD-V3-MC should be either $(SEQ) \
+	currently it is set to ${NRD_CHIP_COUNT}.")
+endif
+
+# Build options
+# Major and Minor versions
+override ARM_ARCH_MAJOR			:= 8
+override ARM_ARCH_MINOR			:= 7
+
+# Image flags
+override NEED_BL1			:= yes
+override NEED_BL2			:= yes
+override NEED_BL32			:= no
+override NEED_RMM			:= no
+
+# Misc options
+override CTX_INCLUDE_AARCH32_REGS	:= 0
+
+# RD-V3 platform uses GIC-700 which is based on GICv4.1
+GIC_ENABLE_V4_EXTN			:= 1
+
+# Enable GIC multichip extension only for multichip platforms
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+GICV3_IMPL_GIC600_MULTICHIP	:= 1
+endif
+
+# RD-V3 uses MHUv3
+PLAT_MHU_VERSION := 3
+
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
+include drivers/arm/rse/rse_comms.mk
+include drivers/auth/mbedtls/mbedtls_common.mk
+ifeq (${MEASURED_BOOT},1)
+include drivers/measured_boot/rse/rse_measured_boot.mk
+endif
+
+RDV3_BASE	=	plat/arm/board/neoverse_rd/platform/rdv3
+
+PLAT_INCLUDES	+=	-I${NRD_COMMON_BASE}/include/nrd3/		\
+			-I${RDV3_BASE}/include/			\
+			-Iinclude/lib/psa
+
+NRD_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
+
+# Source files for RD-V3 variants
+PLAT_BL_COMMON_SOURCES							\
+		+=	${NRD_COMMON_BASE}/nrd_plat3.c			\
+			${RDV3_BASE}/rdv3_common.c
+
+PLAT_MEASURED_BOOT_SOURCES						\
+		:=	${MEASURED_BOOT_SOURCES} 			\
+			${RSE_COMMS_SOURCES}				\
+			${RDV3_BASE}/rdv3_common_measured_boot.c \
+			lib/psa/measured_boot.c
+
+BL1_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${RDV3_BASE}/rdv3_err.c		\
+			${RDV3_BASE}/rdv3_mhuv3.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL1_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDV3_BASE}/rdv3_bl1_measured_boot.c
+endif
+
+BL2_SOURCES	+=	${RDV3_BASE}/rdv3_bl2_setup.c		\
+			${RDV3_BASE}/rdv3_err.c		\
+			${RDV3_BASE}/rdv3_mhuv3.c		\
+			${RDV3_BASE}/rdv3_security.c		\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL2_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL2_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDV3_BASE}/rdv3_bl2_measured_boot.c
+endif
+
+BL31_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${MBEDTLS_SOURCES}				\
+			${RSE_COMMS_SOURCES}				\
+			${RDV3_BASE}/rdv3_bl31_setup.c	\
+			${RDV3_BASE}/rdv3_mhuv3.c		\
+			${RDV3_BASE}/rdv3_topology.c		\
+			${RDV3_BASE}/rdv3_plat_attest_token.c	\
+			${RDV3_BASE}/rdv3_realm_attest_key.c	\
+			drivers/arm/smmu/smmu_v3.c			\
+			drivers/cfi/v2m/v2m_flash.c			\
+			lib/psa/cca_attestation.c			\
+			lib/psa/delegated_attestation.c			\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_dyn_cfg.c			\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
+endif
+
+# XLAT options for RD-V3 variants
+BL31_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+BL2_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES	+=	${RDV3_BASE}/fdts/${PLAT}_fw_config.dts	\
+			${RDV3_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+			${RDV3_BASE}/fdts/${PLAT}_nt_fw_config.dts
+
+FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+# Features for RD-V3 variants
+override ENABLE_FEAT_MPAM	:= 2
+override ENABLE_FEAT_AMU	:= 2
+override ENABLE_SVE_FOR_SWD	:= 1
+override ENABLE_SVE_FOR_NS	:= 2
+override ENABLE_FEAT_MTE2	:= 2
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
new file mode 100644
index 0000000..4db9a11
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdv3_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.slot = U(8),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = TB_FW_CONFIG_ID,
+		.slot = U(9),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = BL2_IMAGE_ID,
+		.slot = U(10),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
new file mode 100644
index 0000000..1b94427
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdv3_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.slot = U(11),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = HW_CONFIG_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.slot = U(13),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+#if ENABLE_RME
+	{
+		.id = RMM_IMAGE_ID,
+		.slot = U(14),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_RMM_IMAGE_STRING,
+		.lock_measurement = false
+	},
+#endif /* ENABLE_RME */
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
new file mode 100644
index 0000000..8dac8d3
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+
+/*
+ * 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[] = {
+	NRD_PAS_SHARED_SRAM,
+	NRD_PAS_SYSTEM_NCI,
+	NRD_PAS_DEBUG_NIC,
+	NRD_PAS_NS_UART,
+	NRD_PAS_REALM_UART,
+	NRD_PAS_AP_NS_WDOG,
+	NRD_PAS_AP_ROOT_WDOG,
+	NRD_PAS_AP_SECURE_WDOG,
+	NRD_PAS_SECURE_SRAM_ERB_AP,
+	NRD_PAS_NS_SRAM_ERB_AP,
+	NRD_PAS_ROOT_SRAM_ERB_AP,
+	NRD_PAS_REALM_SRAM_ERB_AP,
+	NRD_PAS_SECURE_SRAM_ERB_SCP,
+	NRD_PAS_NS_SRAM_ERB_SCP,
+	NRD_PAS_ROOT_SRAM_ERB_SCP,
+	NRD_PAS_REALM_SRAM_ERB_SCP,
+	NRD_PAS_SECURE_SRAM_ERB_MCP,
+	NRD_PAS_NS_SRAM_ERB_MCP,
+	NRD_PAS_ROOT_SRAM_ERB_MCP,
+	NRD_PAS_REALM_SRAM_ERB_MCP,
+	NRD_PAS_SECURE_SRAM_ERB_RSE,
+	NRD_PAS_NS_SRAM_ERB_RSE,
+	NRD_PAS_ROOT_SRAM_ERB_RSE,
+	NRD_PAS_REALM_SRAM_ERB_RSE,
+	NRD_PAS_RSE_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_RSE_NS_SRAM_ERB_RSM,
+	NRD_PAS_SCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_SCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_MCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_MCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_AP_SCP_ROOT_MHU,
+	NRD_PAS_AP_MCP_NS_MHU,
+	NRD_PAS_AP_MCP_SECURE_MHU,
+	NRD_PAS_AP_MCP_ROOT_MHU,
+	NRD_PAS_AP_RSE_NS_MHU,
+	NRD_PAS_AP_RSE_SECURE_MHU,
+	NRD_PAS_AP_RSE_ROOT_MHU,
+	NRD_PAS_AP_RSE_REALM_MHU,
+	NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU,
+	NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR,
+	NRD_PAS_STM_SYSTEM_ITS,
+	NRD_PAS_SCP_MCP_RSE_SHARED_SRAM,
+	NRD_PAS_GIC,
+	NRD_PAS_NS_DRAM,
+	NRD_PAS_RMM,
+	NRD_PAS_L1GPT,
+	NRD_PAS_CMN,
+	NRD_PAS_LCP_PERIPHERAL,
+	NRD_PAS_DDR_IO,
+	NRD_PAS_SMMU_NCI_IO,
+	NRD_PAS_DRAM2_CHIP0,
+#if NRD_CHIP_COUNT > 1
+	NRD_PAS_DRAM1_CHIP1,
+	NRD_PAS_DRAM2_CHIP1,
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_PAS_DRAM1_CHIP2,
+	NRD_PAS_DRAM2_CHIP2,
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_PAS_DRAM1_CHIP3,
+	NRD_PAS_DRAM2_CHIP3
+#endif
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_256TB,
+	.pgs = GPCCR_PGS_4K
+};
+
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
new file mode 100644
index 0000000..21675f6
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/arm/smmu_v3.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+#include <nrd_variant.h>
+#include <rdv3_rse_comms.h>
+
+#if (NRD_PLATFORM_VARIANT == 2)
+static const mmap_region_t rdv3mc_dynamic_mmap[] = {
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
+#endif
+};
+
+static struct gic600_multichip_data rdv3mc_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = NRD_CHIP_COUNT,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+#if NRD_CHIP_COUNT > 1
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 2
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 3
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#endif
+	},
+	.spi_ids = {
+		{PLAT_ARM_GICD_BASE, 32, 511},
+#if NRD_CHIP_COUNT > 1
+		{PLAT_ARM_GICD_BASE, 512, 991},
+#endif
+#if NRD_CHIP_COUNT > 2
+		{PLAT_ARM_GICD_BASE, 4096, 4575},
+#endif
+#if NRD_CHIP_COUNT > 3
+		{PLAT_ARM_GICD_BASE, 4576, 5055},
+#endif
+	}
+};
+
+static uintptr_t rdv3mc_multichip_gicr_frames[] = {
+	/* Chip 0's GICR Base */
+	PLAT_ARM_GICR_BASE,
+#if NRD_CHIP_COUNT > 1
+	/* Chip 1's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	/* Chip 2's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	/* Chip 3's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
+#endif
+	UL(0)	/* Zero Termination */
+};
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+
+void bl31_platform_setup(void)
+{
+	/*
+	 * Perform SMMUv3 GPT configuration for the GPC SMMU present in system
+	 * control block on RD-V3 platforms. This SMMUv3 initialization is
+	 * not fatal.
+	 *
+	 * Don't perform smmuv3_security_init() for this instance of SMMUv3 as
+	 * the global aborts need not be configured to allow the components in
+	 * system control block send transations downstream to SMMUv3.
+	 */
+	if (smmuv3_init(NRD_CSS_GPC_SMMUV3_BASE) != 0) {
+		WARN("Failed initializing System SMMU.\n");
+	}
+
+#if (NRD_PLATFORM_VARIANT == 2)
+	int ret;
+	unsigned int i;
+
+	if (plat_arm_nrd_get_multi_chip_mode() == 0) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+		       NRD_CHIP_COUNT);
+		panic();
+	} else {
+		INFO("Enabling multi-chip support for RD-V3 variant\n");
+
+		for (i = 0; i < ARRAY_SIZE(rdv3mc_dynamic_mmap); i++) {
+			ret = mmap_add_dynamic_region(
+					rdv3mc_dynamic_mmap[i].base_pa,
+					rdv3mc_dynamic_mmap[i].base_va,
+					rdv3mc_dynamic_mmap[i].size,
+					rdv3mc_dynamic_mmap[i].attr);
+			if (ret != 0) {
+				ERROR("Failed to add entry i: %d (ret=%d)\n",
+				       i, ret);
+				panic();
+			}
+		}
+
+		plat_arm_override_gicr_frames(
+			rdv3mc_multichip_gicr_frames);
+		gic600_multichip_init(&rdv3mc_multichip_data);
+	}
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+	nrd_bl31_common_platform_setup();
+
+	if (plat_rse_comms_init() != 0) {
+		WARN("Failed initializing AP-RSE comms.\n");
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
new file mode 100644
index 0000000..10fe666
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <nrd_plat.h>
+#include <rdv3_mhuv3.h>
+#include <rdv3_rse_comms.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) &
+	       SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+		SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * Get a pointer to the RMM-EL3 shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+	*shared = (uintptr_t)RMM_SHARED_BASE;
+
+	return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
+{
+	uint64_t checksum, num_banks, num_consoles;
+	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
+
+	assert(manifest != NULL);
+
+	/* DRAM Bank-1 and Bank-2 */
+	num_banks = 2;
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
+	/* Set number of consoles */
+	num_consoles = NRD_CSS_RMM_CONSOLE_COUNT;
+
+	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->padding = 0U; /* RES0 */
+	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
+
+	/*
+	 * Boot Manifest structure illustration, with two dram banks and
+	 * a single console.
+	 *
+	 * +----------------------------------------+
+	 * | offset |     field      |    comment   |
+	 * +--------+----------------+--------------+
+	 * |   0    |    version     |  0x00000003  |
+	 * +--------+----------------+--------------+
+	 * |   4    |    padding     |  0x00000000  |
+	 * +--------+----------------+--------------+
+	 * |   8    |   plat_data    |     NULL     |
+	 * +--------+----------------+--------------+
+	 * |   16   |   num_banks    |              |
+	 * +--------+----------------+              |
+	 * |   24   |     banks      |   plat_dram  |
+	 * +--------+----------------+              |
+	 * |   32   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   40   |  num_consoles  |              |
+	 * +--------+----------------+              |
+	 * |   48   |    consoles    | plat_console |
+	 * +--------+----------------+              |
+	 * |   56   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   64   |     base 0     |              |
+	 * +--------+----------------+    bank[0]   |
+	 * |   72   |     size 0     |              |
+	 * +--------+----------------+--------------+
+	 * |   80   |     base 1     |              |
+	 * +--------+----------------+    bank[1]   |
+	 * |   88   |     size 1     |              |
+	 * +--------+----------------+--------------+
+	 * |   96   |     base       |              |
+	 * +--------+----------------+              |
+	 * |   104  |   map_pages    |              |
+	 * +--------+----------------+              |
+	 * |   112  |     name       |              |
+	 * +--------+----------------+  consoles[0] |
+	 * |   120  |   clk_in_hz    |              |
+	 * +--------+----------------+              |
+	 * |   128  |   baud_rate    |              |
+	 * +--------+----------------+              |
+	 * |   136  |     flags      |              |
+	 * +--------+----------------+--------------+
+	 */
+
+	bank_ptr = (struct ns_dram_bank *)
+			(((uintptr_t)manifest) + sizeof(*manifest));
+	console_ptr = (struct console_info *)
+			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
+
+	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) *
+		manifest->plat_console.num_consoles) +
+		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks))
+		<= ARM_EL3_RMM_SHARED_SIZE);
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	bank_ptr[0].base = ARM_NS_DRAM1_BASE;
+	bank_ptr[0].size = ARM_NS_DRAM1_SIZE;
+
+	bank_ptr[1].base = ARM_DRAM2_BASE;
+	bank_ptr[1].size = ARM_DRAM2_SIZE;
+
+	/* Update checksum */
+	checksum += bank_ptr[0].base + bank_ptr[0].size + bank_ptr[1].base +
+		bank_ptr[1].size;
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
+
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, '\0',
+		sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = NRD_CSS_RMM_CONSOLE_BASE;
+	console_ptr[0].clk_in_hz = NRD_CSS_RMM_CONSOLE_CLK_IN_HZ;
+	console_ptr[0].baud_rate = NRD_CSS_RMM_CONSOLE_BAUD;
+
+	strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
+		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 must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
+	return 0;
+}
+
+int plat_rse_comms_init(void)
+{
+	uintptr_t snd_base, rcv_base;
+
+	/* Get sender and receiver frames for AP-RSE communication */
+	mhu_v3_get_secure_device_base(&snd_base, true);
+	mhu_v3_get_secure_device_base(&rcv_base, false);
+
+	VERBOSE("Initializing the rse_comms now\n");
+	/* Initialize the communication channel between AP and RSE */
+	return rse_comms_init(snd_base, rcv_base);
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
new file mode 100644
index 0000000..f5160ce
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+
+extern struct rse_mboot_metadata rdv3_rse_mboot_metadata[];
+
+struct rse_mboot_metadata *plat_rse_mboot_get_metadata(void)
+{
+	return rdv3_rse_mboot_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record data in RSE */
+	err = rse_mboot_measure_and_record(rdv3_rse_mboot_metadata,
+					   image_data->image_base,
+					   image_data->image_size,
+					   image_id);
+	if (err != 0) {
+		ERROR("Measure and record failed for image id %u, err (%i)\n",
+		      image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return rse_mboot_set_signer_id(rdv3_rse_mboot_metadata, pk_oid,
+				       pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
new file mode 100644
index 0000000..270febf
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdv3 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
new file mode 100644
index 0000000..738f753
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <nrd_css_def3.h>
+#include <nrd_plat.h>
+#include <rdv3_mhuv3.h>
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender)
+{
+	if (sender) {
+		*base = AP_RSE_ROOT_MHU_V3_PBX;
+	} else {
+		*base = AP_RSE_ROOT_MHU_V3_MBX;
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
new file mode 100644
index 0000000..188a09f
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+				   uintptr_t hash, size_t hash_size)
+{
+	psa_status_t ret;
+
+	ret = cca_attestation_get_plat_token(buf, len, hash, hash_size);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation token\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
new file mode 100644
index 0000000..224c20b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+				       unsigned int type)
+{
+	psa_status_t ret;
+
+	ret = cca_attestation_get_realm_key(buf, len, type);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation key\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
new file mode 100644
index 0000000..a12d3e2
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Placeholder function to resolve build dependency */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
new file mode 100644
index 0000000..6eb5002
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_v3_pd_tree_desc[] = {
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (PLAT_ARM_CLUSTER_COUNT > 4 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 2))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (PLAT_ARM_CLUSTER_COUNT > 12 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 3))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd_v3_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+#if (NRD_PLATFORM_VARIANT == 2)
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+#if (NRD_CHIP_COUNT > 1)
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (NRD_CHIP_COUNT > 2)
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (NRD_CHIP_COUNT > 3)
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+};
+#else
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if (NRD_PLATFORM_VARIANT == 0)
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)),
+#endif
+};
+#endif
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
new file mode 100644
index 0000000..6aec208
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
index dc6c7d8..a6b63a1 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
@@ -112,4 +112,9 @@
 		device_type = "device-memory";
 		reg = <0x0 0x25000000 0x0 0x10000>; /* For cactus tertiary dummy device. */
 	};
+
+	s_uart {
+		device_type = "device-memory";
+		reg = <0x0 PLAT_ARM_BOOT_UART_BASE 0x0 0x01000>;
+	};
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index dcae95f..45d17ba 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -7,6 +7,7 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
+#include <cortex_a520.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <plat/arm/board/common/board_css_def.h>
@@ -298,9 +299,14 @@
 #endif /* TARGET_PLATFORM == 3 */
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-/* TC2: AP<->RSE MHUs */
+/* AP<->RSS MHUs */
+#if TARGET_PLATFORM <= 2
 #define PLAT_RSE_AP_SND_MHU_BASE	UL(0x2A840000)
 #define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x2A850000)
+#elif TARGET_PLATFORM == 3
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49100000)
+#endif
 
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
@@ -328,6 +334,7 @@
  */
 #define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x20000
 
+#if TARGET_PLATFORM <= 2
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x25000000)
 #define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
@@ -355,6 +362,7 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS},	\
 	{PLAT_ARM_DRAM2_BASE, PLAT_ARM_DRAM2_END,	\
 		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+#endif
 
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
@@ -408,4 +416,52 @@
 #define PLAT_ARM_BOOT_UART_CLK_IN_HZ	TC_UARTCLK
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ	TC_UARTCLK
 
+#if TARGET_PLATFORM == 3
+#define NCI_BASE_ADDR			UL(0x4F000000)
+#ifdef TARGET_FLAVOUR_FPGA
+#define MCN_ADDRESS_SPACE_SIZE		0x00120000
+#else
+#define MCN_ADDRESS_SPACE_SIZE		0x00130000
+#endif	/* TARGET_FLAVOUR_FPGA */
+#define MCN_OFFSET_IN_NCI		0x00C90000
+#define MCN_BASE_ADDR			(NCI_BASE_ADDR + MCN_OFFSET_IN_NCI)
+#define MCN_PMU_OFFSET			0x000C4000
+#define MCN_MICROARCH_OFFSET		0x000E4000
+#define MCN_MICROARCH_BASE_ADDR		(MCN_BASE_ADDR + MCN_MICROARCH_OFFSET)
+#define MCN_SCR_OFFSET			0x4
+#define MCN_SCR_PMU_BIT			10
+#define MCN_INSTANCES			4
+#define MCN_PMU_ADDR(n)			(MCN_BASE_ADDR + \
+					 (n * MCN_ADDRESS_SPACE_SIZE) + \
+					 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_S_OFFSET		0x000D4000
+#define MCN_MPAM_S_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_S_OFFSET)
+#define MPAM_SLCCFG_CTL_OFFSET		0x00003018
+#define SLC_RDALLOCMODE_SHIFT		8
+#define SLC_RDALLOCMODE_MASK		(3 << SLC_RDALLOCMODE_SHIFT)
+#define SLC_WRALLOCMODE_SHIFT		12
+#define SLC_WRALLOCMODE_MASK		(3 << SLC_WRALLOCMODE_SHIFT)
+
+#define SLC_DONT_ALLOC			0
+#define SLC_ALWAYS_ALLOC		1
+#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_SLC_PRESENT_BIT	3
+
+/*
+ * TC3 CPUs have the same definitions for:
+ *   CORTEX_{A520|A725|X925}_CPUECTLR_EL1
+ *   CORTEX_{A520|A725|X925}_CPUECTLR_EL1_EXTLLC_BIT
+ * Define the common macros for easier using.
+ */
+#define CPUECTLR_EL1			CORTEX_A520_CPUECTLR_EL1
+#define CPUECTLR_EL1_EXTLLC_BIT		CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT
+#endif /* TARGET_PLATFORM == 3 */
+
+#define CPUACTLR_CLUSTERPMUEN		(ULL(1) << 12)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
index 5f54856..29130ea 100644
--- a/plat/arm/board/tc/include/tc_helpers.S
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,9 @@
 #include <platform_def.h>
 #include <cpu_macros.S>
 
+#define TC_HANDLER(rev)         plat_reset_handler_tc##rev
+#define PLAT_RESET_HANDLER(rev) TC_HANDLER(rev)
+
 	.globl	plat_arm_calc_core_pos
 	.globl	plat_reset_handler
 
@@ -49,13 +52,42 @@
 	ret
 endfunc plat_arm_calc_core_pos
 
+func mark_extllc_presence
+#ifdef MCN_CONFIG_ADDR
+	mov_imm x0, (MCN_CONFIG_ADDR)
+	ldr	w1, [x0]
+	ubfx	x1, x1, #MCN_CONFIG_SLC_PRESENT_BIT, #1
+	sysreg_bitfield_insert_from_gpr CPUECTLR_EL1, x1, \
+					CPUECTLR_EL1_EXTLLC_BIT, 1
+#endif
+	ret
+endfunc mark_extllc_presence
+
+func enable_dsu_pmu_el1_access
+	sysreg_bit_set actlr_el2, CPUACTLR_CLUSTERPMUEN
+	sysreg_bit_set actlr_el3, CPUACTLR_CLUSTERPMUEN
+	ret
+endfunc enable_dsu_pmu_el1_access
+
+func TC_HANDLER(2)
+	ret
+endfunc TC_HANDLER(2)
+
+func TC_HANDLER(3)
+	mov	x9, lr
+	bl	mark_extllc_presence
+	bl	enable_dsu_pmu_el1_access
+	mov	lr, x9
+	ret
+endfunc TC_HANDLER(3)
+
 	/* -----------------------------------------------------
 	 * void plat_reset_handler(void);
-	 *
-	 * Determine the CPU MIDR and disable power down bit for
-	 * that CPU.
 	 * -----------------------------------------------------
 	 */
 func plat_reset_handler
+	mov	x8, lr
+	bl	PLAT_RESET_HANDLER(TARGET_PLATFORM)
+	mov	lr, x8
 	ret
 endfunc plat_reset_handler
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 37ca4c6..fb70500 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -10,8 +10,6 @@
 TC_DPU_USE_SCMI_CLK		:=	1
 # SCMI power domain control enable
 TC_SCMI_PD_CTRL_EN		:=	1
-# IOMMU: Enable the use of system or individual MMUs
-TC_IOMMU_EN			:=	1
 
 # System setup
 CSS_USE_SCMI_SDS_DRIVER		:=	1
@@ -35,15 +33,27 @@
 ENABLE_AMU_AUXILIARY_COUNTERS	:=	1
 ENABLE_MPMM			:=	1
 ENABLE_MPMM_FCONF		:=	1
+ENABLE_FEAT_MTE2	        :=	2
 
 CTX_INCLUDE_AARCH32_REGS	:=	0
 
 ifeq (${SPD},spmd)
 	SPMD_SPM_AT_SEL2	:=	1
-	ENABLE_FEAT_MTE2	:=	1
 	CTX_INCLUDE_PAUTH_REGS	:=	1
 endif
 
+# TC RESOLUTION - LIST OF VALID OPTIONS (this impacts only FVP)
+TC_RESOLUTION_OPTIONS		:= 	640x480p60 \
+					1920x1080p60
+# Set default to the 640x480p60 resolution mode
+TC_RESOLUTION ?= $(firstword $(TC_RESOLUTION_OPTIONS))
+
+# Check resolution option for FVP
+ifneq ($(filter ${TARGET_FLAVOUR}, fvp),)
+ifeq ($(filter ${TC_RESOLUTION}, ${TC_RESOLUTION_OPTIONS}),)
+        $(error TC_RESOLUTION is ${TC_RESOLUTION}, it must be: ${TC_RESOLUTION_OPTIONS})
+endif
+endif
 
 ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
         $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
@@ -61,9 +71,9 @@
 $(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_IOMMU_EN \
 ))
 
 CSS_LOAD_SCP_IMAGES	:=	1
@@ -71,6 +81,13 @@
 # Save DSU PMU registers on cluster off and restore them on cluster on
 PRESERVE_DSU_PMU_REGS		:= 1
 
+# Specify MHU type based on platform
+ifneq ($(filter ${TARGET_PLATFORM}, 2),)
+	PLAT_MHU_VERSION	:= 2
+else
+	PLAT_MHU_VERSION	:= 3
+endif
+
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
@@ -100,11 +117,12 @@
 # CPU libraries for TARGET_PLATFORM=3
 ifeq (${TARGET_PLATFORM}, 3)
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
-			lib/cpus/aarch64/cortex_chaberton.S \
-			lib/cpus/aarch64/cortex_blackhawk.S
+			lib/cpus/aarch64/cortex_a725.S \
+			lib/cpus/aarch64/cortex_x925.S
 endif
 
-INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c
+INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c \
+				plat/arm/common/arm_ni.c
 
 PLAT_BL_COMMON_SOURCES	+=	${TC_BASE}/tc_plat.c	\
 				${TC_BASE}/include/tc_helpers.S
@@ -112,6 +130,7 @@
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${TC_BASE}/tc_trusted_boot.c	\
+				${TC_BASE}/tc_bl1_setup.c \
 				${TC_BASE}/tc_err.c	\
 				drivers/arm/sbsa/sbsa.c
 
@@ -121,9 +140,12 @@
 				${TC_BASE}/tc_bl2_setup.c		\
 				lib/utils/mem_region.c			\
 				drivers/arm/tzc/tzc400.c		\
-				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
+ifeq ($(shell test $(TARGET_PLATFORM) -le 2; echo $$?),0)
+BL2_SOURCES		+=	plat/arm/common/arm_tzc400.c
+endif
+
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${ENT_GIC_SOURCES}			\
@@ -241,5 +263,4 @@
 
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
 include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/tc/tc_bl1_dpe.c b/plat/arm/board/tc/tc_bl1_dpe.c
index 432a163..de5702a 100644
--- a/plat/arm/board/tc/tc_bl1_dpe.c
+++ b/plat/arm/board/tc/tc_bl1_dpe.c
@@ -18,7 +18,7 @@
 #include <platform_def.h>
 #include <tools_share/zero_oid.h>
 
-#include "tc_dpe_cert.h"
+#include "tc_dpe.h"
 
 struct dpe_metadata tc_dpe_metadata[] = {
 	{
@@ -29,6 +29,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = ZERO_OID },
 	{
 		.id = TB_FW_CONFIG_ID,
@@ -38,6 +39,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = ZERO_OID },
 	{
 		.id = BL2_IMAGE_ID,
@@ -45,7 +47,8 @@
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = MBOOT_BL2_IMAGE_STRING,
 		.allow_new_context_to_derive = true,
-		.retain_parent_context = false,
+		.retain_parent_context = true, /* To handle restart */
+		.target_locality = LOCALITY_AP_S,
 		.create_certificate = false,
 		.pk_oid = ZERO_OID },
 	{
@@ -58,10 +61,15 @@
 
 /* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
 static int new_ctx_handle;
+/* Save a valid parent context handle to be able to send commands to DPE service
+ * in case of an AP cold restart.
+ */
+static int new_parent_ctx_handle;
 
-void plat_dpe_share_context_handle(int *ctx_handle)
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
 {
 	new_ctx_handle = *ctx_handle;
+	new_parent_ctx_handle = *parent_ctx_handle;
 }
 
 void plat_dpe_get_context_handle(int *ctx_handle)
@@ -135,4 +143,16 @@
 		 */
 		plat_panic_handler();
 	}
+
+	VERBOSE("Save parent context handle: 0x%x\n", new_parent_ctx_handle);
+	rc = sds_struct_write(SDS_RSE_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      &new_parent_ctx_handle,
+			      sizeof(new_parent_ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (rc != SDS_OK) {
+		ERROR("Unable to save DPE parent context handle to SDS area\n");
+		plat_panic_handler();
+	}
 }
diff --git a/plat/arm/board/tc/tc_bl1_setup.c b/plat/arm/board/tc/tc_bl1_setup.c
new file mode 100644
index 0000000..aedc94f
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+
+void soc_css_init_nic400(void)
+{
+}
+
+void soc_css_init_pcie(void)
+{
+}
diff --git a/plat/arm/board/tc/tc_bl2_dpe.c b/plat/arm/board/tc/tc_bl2_dpe.c
index 50cdbf8..c56612b 100644
--- a/plat/arm/board/tc/tc_bl2_dpe.c
+++ b/plat/arm/board/tc/tc_bl2_dpe.c
@@ -15,7 +15,7 @@
 #include <platform_def.h>
 #include <tools_share/tbbr_oid.h>
 
-#include "tc_dpe_cert.h"
+#include "tc_dpe.h"
 
 /*
  * The content and the values of this array depends on:
@@ -39,6 +39,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = BL31_IMAGE_KEY_OID },
 	{
 		.id = BL32_IMAGE_ID,
@@ -48,6 +49,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = BL32_IMAGE_KEY_OID },
 	{
 		.id = BL33_IMAGE_ID,
@@ -57,6 +59,7 @@
 		.allow_new_context_to_derive = true,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_AP_NS,
 		.pk_oid = BL33_IMAGE_KEY_OID },
 
 	{
@@ -67,6 +70,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = HW_CONFIG_KEY_OID },
 	{
 		.id = NT_FW_CONFIG_ID,
@@ -76,6 +80,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NT_FW_CONFIG_KEY_OID },
 	{
 		.id = SCP_BL2_IMAGE_ID,
@@ -85,6 +90,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = SCP_BL2_IMAGE_KEY_OID },
 	{
 		.id = SOC_FW_CONFIG_ID,
@@ -94,6 +100,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = SOC_FW_CONFIG_KEY_OID },
 	{
 		.id = TOS_FW_CONFIG_ID,
@@ -103,6 +110,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = TOS_FW_CONFIG_KEY_OID },
 #if defined(SPD_spmd)
 	{
@@ -113,6 +121,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = true, /* With Trusty only one SP is loaded */
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG2_ID,
@@ -122,6 +131,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG3_ID,
@@ -131,6 +141,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG4_ID,
@@ -140,6 +151,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG5_ID,
@@ -149,6 +161,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG6_ID,
@@ -158,6 +171,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG7_ID,
@@ -167,6 +181,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 	{
 		.id = SP_PKG8_ID,
@@ -176,6 +191,7 @@
 		.allow_new_context_to_derive = false,
 		.retain_parent_context = true,
 		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
 		.pk_oid = NULL },
 
 #endif
@@ -186,9 +202,12 @@
 /* Context handle is meant to be used by BL33. Sharing it via NT_FW_CONFIG */
 static int new_ctx_handle;
 
-void plat_dpe_share_context_handle(int *ctx_handle)
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
 {
 	new_ctx_handle = *ctx_handle;
+
+	/* Irrelevant in BL2 because cold restart resumes CPU in BL1 */
+	(void)parent_ctx_handle;
 }
 
 void plat_dpe_get_context_handle(int *ctx_handle)
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index add871c..3957c90 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -40,6 +40,13 @@
 		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
+		.id = SCP_BL2_IMAGE_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID,
+		.lock_measurement = true },
+	{
 		.id = RSE_MBOOT_INVALID_ID }
 };
 
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 5742d07..53404df 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -50,25 +50,74 @@
 }
 #endif /* PLATFORM_TEST_TFM_TESTSUITE */
 
-static scmi_channel_plat_info_t tc_scmi_plat_info[] = {
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	}
+#if TARGET_PLATFORM <= 2
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhuv2_ring_doorbell,
 };
+#elif TARGET_PLATFORM == 3
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhu_ring_doorbell,
+};
+
+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);
+		mmio_setbits_32(mcn_scr, 1 << MCN_SCR_PMU_BIT);
+	}
+}
+
+static void set_mcn_slc_alloc_mode(void)
+{
+	/*
+	 * SLC WRALLOCMODE and RDALLOCMODE are configured by default to
+	 * 0b01 (always alloc), configure both to 0b10 (use bus signal
+	 * 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;
+
+		mmio_clrsetbits_32(slccfg_ctl_ns,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+		mmio_clrsetbits_32(slccfg_ctl_s,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+	}
+}
+#endif
 
 void bl31_platform_setup(void)
 {
 	tc_bl31_common_platform_setup();
+#if TARGET_PLATFORM == 3
+	enable_ns_mcn_pmu();
+	set_mcn_slc_alloc_mode();
+	plat_arm_ni_setup(NCI_BASE_ADDR);
+#endif
 }
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id __unused)
 {
 
-	return &tc_scmi_plat_info[channel_id];
+	return &tc_scmi_plat_info;
 
 }
 
diff --git a/plat/arm/board/tc/tc_dpe_cert.h b/plat/arm/board/tc/tc_dpe.h
similarity index 79%
rename from plat/arm/board/tc/tc_dpe_cert.h
rename to plat/arm/board/tc/tc_dpe.h
index d0632e8..3e1af5a 100644
--- a/plat/arm/board/tc/tc_dpe_cert.h
+++ b/plat/arm/board/tc/tc_dpe.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef TC_DPE_CERT_H
-#define TC_DPE_CERT_H
+#ifndef TC_DPE_H
+#define TC_DPE_H
 
 /*
  * The certificate structure on the TC platform:
@@ -36,4 +36,18 @@
 /* Common definition */
 #define DPE_CERT_ID_SAME_AS_PARENT	0xFFFFFFFF
 
-#endif /* TC_DPE_CERT_H */
+/*
+ * Target Locality:
+ *    The goal is to specify that a certain component is expected to run and
+ *    thereby send DPE commands from a given security domain. RSE is capable of
+ *    of distinguishing the client's locality based on the MHU channel used for
+ *    communication.
+ *    Defines here must match with RSE side:
+ */
+#define LOCALITY_NONE		-1
+/* #define LOCALITY_RSE_S	0 */  /* Not applicable on AP side */
+/* #define LOCALITY_RSE_NS	1 */  /* Not applicable on AP side */
+#define LOCALITY_AP_S		 2
+#define LOCALITY_AP_NS		 3
+
+#endif /* TC_DPE_H */
diff --git a/plat/arm/board/tc/tc_security.c b/plat/arm/board/tc/tc_security.c
index 6a34501..7c7a1a1 100644
--- a/plat/arm/board/tc/tc_security.c
+++ b/plat/arm/board/tc/tc_security.c
@@ -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
  */
@@ -7,17 +7,21 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
+#if (TARGET_PLATFORM <= 2)
 static const arm_tzc_regions_info_t tzc_regions[] = {
 	TC_TZC_REGIONS_DEF,
 	{}
 };
+#endif
 
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
 {
+#if (TARGET_PLATFORM <= 2)
 	unsigned int i;
 
 	for (i = 0U; i < TZC400_COUNT; i++) {
 		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
 	}
+#endif
 }
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 58a14ab..b5a7db1 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -162,16 +162,6 @@
 #if defined(PLAT_ARM_MEM_PROT_ADDR)
 	arm_nor_psci_do_static_mem_protect();
 #endif
-
-#if TRANSFER_LIST
-	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
-				   PLAT_ARM_FW_HANDOFF_SIZE);
-
-	if (ns_tl == NULL) {
-		ERROR("Non-secure transfer list initialisation failed!");
-		panic();
-	}
-#endif
 }
 
 void bl2_platform_setup(void)
@@ -326,7 +316,8 @@
 
 #if TRANSFER_LIST
 	if (image_id == HW_CONFIG_ID) {
-		arm_transfer_list_copy_hw_config(secure_tl, ns_tl);
+		/* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */
+		transfer_list_update_checksum(secure_tl);
 	}
 #endif /* TRANSFER_LIST */
 
@@ -335,8 +326,10 @@
 
 void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node)
 {
-	assert(transfer_list_set_handoff_args(
-		       secure_tl, &next_param_node->ep_info) != NULL);
+	entry_point_info_t *ep __unused;
+	ep = transfer_list_set_handoff_args(secure_tl,
+					    &next_param_node->ep_info);
+	assert(ep != NULL);
 
-	arm_transfer_list_populate_ep_info(next_param_node, secure_tl, ns_tl);
+	arm_transfer_list_populate_ep_info(next_param_node, secure_tl);
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index b7941ec..e91746b 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -25,6 +25,8 @@
 #include <platform_def.h>
 
 static struct transfer_list_header *secure_tl __unused;
+static struct transfer_list_header *ns_tl __unused;
+
 /*
  * Placeholder variables for copying the arguments that have been passed to
  * BL31 from BL2.
@@ -95,7 +97,12 @@
 
 	assert(sec_state_is_valid(type));
 	if (type == NON_SECURE) {
+#if TRANSFER_LIST && !RESET_TO_BL31
+		next_image_info = transfer_list_set_handoff_args(
+			ns_tl, &bl33_image_ep_info);
+#else
 		next_image_info = &bl33_image_ep_info;
+#endif
 	}
 #if ENABLE_RME
 	else if (type == REALM) {
@@ -128,6 +135,24 @@
 void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
 					  u_register_t arg2, u_register_t arg3)
 {
+#if RESET_TO_BL31
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+	bl33_image_ep_info.args.arg0 =
+		FW_NS_HANDOFF_BASE + ARM_PRELOADED_DTB_OFFSET;
+	bl33_image_ep_info.args.arg1 =
+		TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+	bl33_image_ep_info.args.arg3 = FW_NS_HANDOFF_BASE;
+#else
 	struct transfer_list_entry *te = NULL;
 	struct entry_point_info *ep;
 
@@ -160,6 +185,7 @@
 			}
 		}
 	}
+#endif /* RESET_TO_BL31 */
 }
 #else
 void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
@@ -338,6 +364,28 @@
  ******************************************************************************/
 void arm_bl31_platform_setup(void)
 {
+	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);
+
+	if (ns_tl == NULL) {
+		ERROR("Non-secure transfer list initialisation failed!");
+		panic();
+	}
+
+#if !RESET_TO_BL2
+	te = transfer_list_find(secure_tl, TL_TAG_FDT);
+	assert(te != NULL);
+
+	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
+#endif /* !(RESET_TO_BL2 && RESET_TO_BL31) */
+#endif /* TRANSFER_LIST */
+
 	/* Initialize the GIC driver, cpu and distributor interfaces */
 	plat_arm_gic_driver_init();
 	plat_arm_gic_init();
@@ -380,9 +428,26 @@
  ******************************************************************************/
 void arm_bl31_plat_runtime_setup(void)
 {
+	struct transfer_list_entry *te __unused;
 	/* Initialize the runtime console */
 	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) */
+
 #if RECLAIM_INIT_CODE
 	arm_free_init_memory();
 #endif
@@ -497,15 +562,5 @@
 
 void __init bl31_plat_arch_setup(void)
 {
-	struct transfer_list_entry *te __unused;
-
 	arm_bl31_plat_arch_setup();
-
-#if TRANSFER_LIST && !RESET_TO_BL2
-	te = transfer_list_find(secure_tl, TL_TAG_FDT);
-	assert(te != NULL);
-
-	/* Populate HW_CONFIG device tree with the mapped address */
-	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
-#endif
 }
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 7ab39eb..2c1888d 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -26,7 +26,7 @@
   else ifeq (${ARM_TSP_RAM_LOCATION}, dram)
     ARM_TSP_RAM_LOCATION_ID = ARM_DRAM_ID
   else
-    $(error "Unsupported ARM_TSP_RAM_LOCATION value")
+    $(error Unsupported ARM_TSP_RAM_LOCATION value)
   endif
 
   # Process flags
@@ -83,7 +83,7 @@
 # memory. This means we must not run BL31 from TZC-protected DRAM.
 ifeq (${ARM_BL31_IN_DRAM},1)
   ifeq (${ENABLE_RME},1)
-    $(error "BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0")
+    $(error BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0)
   endif
 endif
 
@@ -105,16 +105,15 @@
 ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
   ifneq (${ARCH},aarch64)
     ifneq (${RESET_TO_SP_MIN},1)
-      $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.")
+      $(error ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.)
     endif
   endif
   ifndef PRELOADED_BL33_BASE
-    $(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+    $(error PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.)
   endif
   ifeq (${RESET_TO_BL31},1)
     ifndef ARM_PRELOADED_DTB_BASE
-      $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is
-       used with RESET_TO_BL31.")
+      $(error ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used with RESET_TO_BL31.)
     endif
     $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
   endif
@@ -385,7 +384,12 @@
             endif
         endif
     else ifeq (${COT},dualroot)
-        AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
+        BL1_SOURCES	+=	drivers/auth/dualroot/cot.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        else
+            BL2_SOURCES	+=	drivers/auth/dualroot/cot.c
+        endif
     else ifeq (${COT},cca)
         BL1_SOURCES	+=	drivers/auth/cca/cot.c
         ifneq (${COT_DESC_IN_DTB},0)
@@ -451,6 +455,20 @@
 
 ifeq (${RECLAIM_INIT_CODE}, 1)
     ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-        $(error "To reclaim init code xlat tables v2 must be used")
+        $(error To reclaim init code xlat tables v2 must be used)
     endif
 endif
+
+TRANSFER_LIST_BIN := ${BUILD_PLAT}/tl.bin
+
+.PHONY: tl
+tl: ${HW_CONFIG}
+	@echo "  TLC     ${TRANSFER_LIST_BIN}"
+	$(Q)${PYTHON} -m tools.tlc.tlc create --fdt ${HW_CONFIG} -s ${FW_HANDOFF_SIZE} ${TRANSFER_LIST_BIN}
+	$(Q)$(eval ARM_PRELOADED_DTB_OFFSET := `tlc info --fdt-offset ${TRANSFER_LIST_BIN}`)
+
+ifeq (${TRANSFER_LIST}, 1)
+  ifeq (${RESET_TO_BL31}, 1)
+    bl31: tl
+  endif
+endif
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index 19ee1b0..5a3d27a 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -124,6 +124,7 @@
 	const struct plat_io_policy *policy;
 
 	policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
+	assert(policy->check != NULL);
 	result = policy->check(policy->image_spec);
 	if (result == 0) {
 		*image_spec = policy->image_spec;
diff --git a/plat/arm/common/arm_ni.c b/plat/arm/common/arm_ni.c
new file mode 100644
index 0000000..b3ad8b3
--- /dev/null
+++ b/plat/arm/common/arm_ni.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#define NI_CHILD_NODE_COUNT			4
+#define NI_CHILD_POINTERS_START			8
+
+#define NI_PMU_SECURE_CTRL			0x100
+#define NI_PMU_SECURE_EVENT_OBSERVATION		0x108
+#define NI_PMU_DEBUG_ENABLE			0x110
+#define NI_COMP_NUM_SUBFEATURES			0x100
+#define NI_COMP_SUBFEATURE_TYPE_START		0x108
+#define NI_COMP_SUBFEATURE_SECURE_CTRL_START	0x308
+
+#define SECURE_OVERRIDE_DEFAULT			BIT(0)
+#define SECURE_EVENT_ENABLE			BIT(2)
+#define NA_EVENT_ENABLE				BIT(3)
+#define PMU_ENABLE				BIT(0)
+
+#define NI_NODE_MASK				0x0000ffff
+#define NI_NODE_TYPE(node_info)			(node_info & NI_NODE_MASK)
+#define NI_CHILD_POINTER(i)			(NI_CHILD_POINTERS_START + (i * 4))
+#define NI_COMP_SUBFEATURE_TYPE(i)		(NI_COMP_SUBFEATURE_TYPE_START + (i * 8))
+#define NI_COMP_SUBFEATURE_SECURE_CTRL(i)	(NI_COMP_SUBFEATURE_SECURE_CTRL_START + (i * 8))
+
+#define NI_PERIPHERAL_ID0			0xfe0
+#define NI_PIDR0_PART_MASK			0xff
+#define NI_PERIPHERAL_ID1			0xfe4
+#define NI_PIDR1_PART_MASK			0xf
+#define NI_PIDR1_PART_SHIFT			8
+
+enum ni_part {
+	NI_700 = 0x43b,
+	NI_710AE = 0x43d,
+	NI_TOWER = 0x43f,
+};
+
+enum ni_node_type {
+	NI_INVALID_NODE = 0,
+	NI_VOLTAGE_DOMAIN  = 1,
+	NI_POWER_DOMAIN = 2,
+	NI_CLOCK_DOMAIN = 3,
+	NI_ASNI = 4,
+	NI_AMNI = 5,
+	NI_PMU = 6,
+	NI_HSNI = 7,
+	NI_HMNI = 8,
+	NI_PMNI = 9,
+	NI_CMNI = 14,
+	NI_CFGNI = 15
+};
+
+enum ni_subfeature_type {
+	NI_SUBFEATURE_APU = 0,
+	NI_SUBFEATURE_ADDR_MAP = 1,
+	NI_SUBFEATURE_FCU = 2,
+	NI_SUBFEATURE_IDM = 3
+};
+
+static void ni_enable_pmu(uintptr_t pmu_addr)
+{
+	mmio_setbits_32(pmu_addr + NI_PMU_DEBUG_ENABLE, PMU_ENABLE);
+}
+
+static void ni_enable_fcu_ns_access(uintptr_t comp_addr)
+{
+	uint32_t subfeature_type;
+	uint32_t subfeature_count;
+	uint32_t subfeature_secure_ctrl;
+
+	subfeature_count = mmio_read_32(comp_addr + NI_COMP_NUM_SUBFEATURES);
+	for (uint32_t i = 0U; i < subfeature_count; i++) {
+		subfeature_type =
+			NI_NODE_TYPE(mmio_read_32(comp_addr + NI_COMP_SUBFEATURE_TYPE(i)));
+		if (subfeature_type == NI_SUBFEATURE_FCU) {
+			subfeature_secure_ctrl = comp_addr + NI_COMP_SUBFEATURE_SECURE_CTRL(i);
+			mmio_setbits_32(subfeature_secure_ctrl, SECURE_OVERRIDE_DEFAULT);
+		}
+	}
+}
+
+static void ni_enable_pmu_ns_access(uintptr_t comp_addr)
+{
+	mmio_setbits_32(comp_addr + NI_PMU_SECURE_CTRL, SECURE_OVERRIDE_DEFAULT);
+	mmio_setbits_32(comp_addr + NI_PMU_SECURE_EVENT_OBSERVATION,
+			SECURE_EVENT_ENABLE | NA_EVENT_ENABLE);
+}
+
+static void ni_setup_component(uintptr_t comp_addr)
+{
+	uint32_t node_info;
+
+	node_info = mmio_read_32(comp_addr);
+
+	switch (NI_NODE_TYPE(node_info)) {
+	case NI_ASNI:
+	case NI_AMNI:
+	case NI_HSNI:
+	case NI_HMNI:
+	case NI_PMNI:
+		ni_enable_fcu_ns_access(comp_addr);
+		break;
+	case NI_PMU:
+		ni_enable_pmu_ns_access(comp_addr);
+		ni_enable_pmu(comp_addr);
+		break;
+	default:
+		return;
+	}
+}
+
+int plat_arm_ni_setup(uintptr_t global_cfg)
+{
+	uintptr_t vd_addr;
+	uintptr_t pd_addr;
+	uintptr_t cd_addr;
+	uintptr_t comp_addr;
+	uint32_t vd_count;
+	uint32_t pd_count;
+	uint32_t cd_count;
+	uint32_t comp_count;
+	uint32_t part;
+	uint32_t reg;
+
+	reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID0);
+	part = reg & NI_PIDR0_PART_MASK;
+	reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID1);
+	part |= ((reg & NI_PIDR1_PART_MASK) << NI_PIDR1_PART_SHIFT);
+
+	if (part != NI_TOWER) {
+		ERROR("0x%x is not supported\n", part);
+		return -EINVAL;
+	}
+
+	vd_count = mmio_read_32(global_cfg + NI_CHILD_NODE_COUNT);
+
+	for (uint32_t i = 0U; i < vd_count; i++) {
+		vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i));
+		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);
+
+			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);
+
+				for (uint32_t l = 0U; l < comp_count; l++) {
+					comp_addr = global_cfg +
+						mmio_read_32(cd_addr + NI_CHILD_POINTER(l));
+					ni_setup_component(comp_addr);
+				}
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
index d144bbb..59fb039 100644
--- a/plat/arm/common/arm_transfer_list.c
+++ b/plat/arm/common/arm_transfer_list.c
@@ -30,8 +30,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 *ns_tl)
+					struct transfer_list_header *secure_tl)
 {
 	uint32_t next_exe_img_id;
 	entry_point_info_t *ep;
@@ -53,10 +52,7 @@
 
 		ep = transfer_list_entry_data(te);
 
-		if (next_exe_img_id == BL33_IMAGE_ID) {
-			ep = transfer_list_set_handoff_args(ns_tl, ep);
-			assert(ep != NULL);
-		} else if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) {
+		if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) {
 			/*
 			 * Populate the BL32 image base, size and max limit in
 			 * the entry point information, since there is no
@@ -78,19 +74,3 @@
 
 	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
 }
-
-void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
-				      struct transfer_list_header *ns_tl)
-{
-	struct transfer_list_entry *te =
-		transfer_list_find(secure_tl, TL_TAG_FDT);
-	assert(te != NULL);
-
-	/* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */
-	transfer_list_update_checksum(secure_tl);
-
-	/* Copy the hardware configuration to the non-secure TL. */
-	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
-			       transfer_list_entry_data(te));
-	assert(te != NULL);
-}
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index f15c137..4cd514b 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,10 +68,6 @@
 	arm_console_boot_init();
 
 #if RESET_TO_SP_MIN
-	/* There are no parameters from BL2 if SP_MIN is a reset vector */
-	assert(from_bl2 == NULL);
-	assert(plat_params_from_bl2 == NULL);
-
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info,
 				PARAM_EP,
diff --git a/plat/aspeed/ast2700/include/platform_def.h b/plat/aspeed/ast2700/include/platform_def.h
index 8be26c3..e668115 100644
--- a/plat/aspeed/ast2700/include/platform_def.h
+++ b/plat/aspeed/ast2700/include/platform_def.h
@@ -21,9 +21,6 @@
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
 					 PLATFORM_CORE_COUNT_PER_CLUSTER)
 
-/* arch timer */
-#define PLAT_SYSCNT_CLKIN_HZ		U(1600000000)
-
 /* power domain */
 #define PLAT_MAX_PWR_LVL		U(1)
 #define PLAT_NUM_PWR_DOMAINS		U(5)
@@ -55,4 +52,12 @@
 #define CONSOLE_UART_CLKIN_HZ		U(1846153)
 #define CONSOLE_UART_BAUDRATE		U(115200)
 
+/* CLK information */
+#define CLKIN_25M			UL(25000000)
+
+#define PLAT_CLK_GATE_NUM		U(29)
+#define PLAT_CLK_HPLL			(PLAT_CLK_GATE_NUM + 5)
+#define PLAT_CLK_DPLL			(PLAT_CLK_GATE_NUM + 6)
+#define PLAT_CLK_MPLL			(PLAT_CLK_GATE_NUM + 7)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/aspeed/ast2700/include/platform_reg.h b/plat/aspeed/ast2700/include/platform_reg.h
index 7f26865..3c164a4 100644
--- a/plat/aspeed/ast2700/include/platform_reg.h
+++ b/plat/aspeed/ast2700/include/platform_reg.h
@@ -19,6 +19,10 @@
 
 /* CPU-die SCU */
 #define SCU_CPU_BASE	U(0x12c02000)
+#define SCU_CPU_HW_STRAP1	(SCU_CPU_BASE + 0x010)
+#define SCU_CPU_HPLL	(SCU_CPU_BASE + 0x300)
+#define SCU_CPU_DPLL	(SCU_CPU_BASE + 0x308)
+#define SCU_CPU_MPLL	(SCU_CPU_BASE + 0x310)
 #define SCU_CPU_SMP_EP0	(SCU_CPU_BASE + 0x780)
 #define SCU_CPU_SMP_EP1	(SCU_CPU_BASE + 0x788)
 #define SCU_CPU_SMP_EP2	(SCU_CPU_BASE + 0x790)
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index 92a48ff..087b479 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <arch.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
@@ -112,3 +113,90 @@
 
 	return ep_info;
 }
+
+/*
+ * Clock divider/multiplier configuration struct.
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ *
+ */
+union plat_pll_reg {
+	uint32_t w;
+	struct {
+		uint16_t m : 13;		/* bit[12:0]	*/
+		uint8_t n : 6;			/* bit[18:13]	*/
+		uint8_t p : 4;			/* bit[22:19]	*/
+		uint8_t off : 1;		/* bit[23]	*/
+		uint8_t bypass : 1;		/* bit[24]	*/
+		uint8_t reset : 1;		/* bit[25]	*/
+		uint8_t reserved : 6;		/* bit[31:26]	*/
+	} b;
+};
+
+static uint32_t plat_get_pll_rate(int pll_idx)
+{
+	union plat_pll_reg pll_reg;
+	uint32_t mul = 1, div = 1;
+	uint32_t rate = 0;
+
+	switch (pll_idx) {
+	case PLAT_CLK_HPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_HPLL);
+		break;
+	case PLAT_CLK_DPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_DPLL);
+		break;
+	case PLAT_CLK_MPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_MPLL);
+		break;
+	default:
+		ERROR("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+		return -EINVAL;
+	}
+
+	if (pll_idx == PLAT_CLK_HPLL && ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) != 0U)) {
+		switch ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) >> 2) {
+		case 1U:
+			rate = 1900000000;
+			break;
+		case 2U:
+			rate = 1800000000;
+			break;
+		case 3U:
+			rate = 1700000000;
+			break;
+		default:
+			rate = 2000000000;
+			break;
+		}
+	} else {
+		if (pll_reg.b.bypass == 0U) {
+			if (pll_idx == PLAT_CLK_MPLL) {
+				/* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+				div = (pll_reg.b.p + 1);
+			} else {
+				/* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+				div = (pll_reg.b.p + 1);
+			}
+		}
+
+		rate = ((CLKIN_25M * mul) / div);
+	}
+
+	return rate;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	if (mmio_read_32(SCU_CPU_HW_STRAP1) & BIT(4)) {
+		return plat_get_pll_rate(PLAT_CLK_HPLL);
+	} else {
+		return plat_get_pll_rate(PLAT_CLK_MPLL);
+	}
+}
diff --git a/plat/aspeed/ast2700/plat_helpers.S b/plat/aspeed/ast2700/plat_helpers.S
index c6d987e..e4a283c 100644
--- a/plat/aspeed/ast2700/plat_helpers.S
+++ b/plat/aspeed/ast2700/plat_helpers.S
@@ -59,12 +59,6 @@
 	br	x0
 endfunc plat_secondary_cold_boot_setup
 
-/* unsigned int plat_get_syscnt_freq2(void); */
-func plat_get_syscnt_freq2
-	mov_imm	w0, PLAT_SYSCNT_CLKIN_HZ
-	ret
-endfunc plat_get_syscnt_freq2
-
 /* int plat_crash_console_init(void); */
 func plat_crash_console_init
 	mov_imm	x0, CONSOLE_UART_BASE
diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c
index 2c1a8fa..8979171 100644
--- a/plat/common/aarch32/plat_common.c
+++ b/plat/common/aarch32/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
@@ -14,7 +22,6 @@
  */
 #pragma weak bl32_plat_enable_mmu
 
-
 void bl32_plat_enable_mmu(uint32_t flags)
 {
 	enable_mmu_svc_mon(flags);
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 54f2a03..7a228b9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -17,6 +17,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 89b77ba..a603f2b 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,6 @@
 #pragma weak bl2_plat_preload_setup
 #pragma weak bl2_plat_handle_pre_image_load
 #pragma weak bl2_plat_handle_post_image_load
-#pragma weak plat_try_next_boot_source
 #pragma weak plat_get_enc_key_info
 #pragma weak plat_is_smccc_feature_available
 #pragma weak plat_get_soc_version
@@ -69,11 +68,6 @@
 	return 0;
 }
 
-int plat_try_next_boot_source(void)
-{
-	return 0;
-}
-
 /*
  * Weak implementation to provide dummy decryption key only for test purposes,
  * platforms must override this API for any real world firmware encryption
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 807a915..63eca37 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.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
 #
@@ -153,12 +153,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index fd11a4d..c2c3122 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.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
 #
@@ -146,12 +146,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
diff --git a/plat/imx/common/imx_common.c b/plat/imx/common/imx_common.c
new file mode 100644
index 0000000..01f354a
--- /dev/null
+++ b/plat/imx/common/imx_common.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+
+#include <plat_common.h>
+
+/*
+ * This function checks if @arg0 can safely be accessed as a pointer
+ * and if it does, it fills in @bl32_info and @bl33_info with data
+ * found in @arg0.
+ *
+ * Returns 0 when @arg0 can be used as entry point info and a negative
+ * error code otherwise.
+ */
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info)
+{
+	bl_params_t *v2 = (void *)(uintptr_t)arg0;
+
+	if (arg0 & 0x3) {
+		return -EINVAL;
+	}
+
+	if (arg0 < ocram_base || arg0 >= ocram_base + ocram_size) {
+		return -EINVAL;
+	}
+
+	if (v2->h.version != PARAM_VERSION_2) {
+		return -EINVAL;
+	}
+
+	if (v2->h.type != PARAM_BL_PARAMS) {
+		return -EINVAL;
+	}
+
+	bl31_params_parse_helper(arg0, bl32_info, bl33_info);
+
+	return 0;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index c625704..75b709a 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -80,7 +80,8 @@
 		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
 		break;
 #endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp) || \
+	defined(PLAT_imx8mq)
 	case IMX_SIP_HAB:
 		SMC_RET1(handle, imx_hab_handler(smc_fid, x1, x2, x3, x4));
 		break;
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index e154530..404a829 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -62,8 +62,16 @@
 			 u_register_t x2, u_register_t x3);
 int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3);
+#if IMX_DRAM_RETENTION
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
 	u_register_t x1, u_register_t x2, u_register_t x3);
+#else
+static inline int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+		u_register_t x1, u_register_t x2, u_register_t x3)
+{
+	SMC_RET1(handle, SMC_UNK);
+}
+#endif
 #endif
 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
diff --git a/plat/imx/common/include/plat_common.h b/plat/imx/common/include/plat_common.h
new file mode 100644
index 0000000..6f41222
--- /dev/null
+++ b/plat/imx/common/include/plat_common.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_COMMON_H
+#define PLAT_COMMON_H
+
+#include <stdint.h>
+#include <common/bl_common.h>
+
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info);
+
+#endif /* PLAT_COMMON_H */
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 156c55d..2bda3a5 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -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
 #
@@ -71,21 +71,20 @@
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx7_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index bff8fb4..f6e46eb 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -30,6 +30,7 @@
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -154,7 +155,7 @@
 {
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -207,6 +208,13 @@
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 349233a..2fa6199 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -118,6 +118,8 @@
 #define IMX_ROM_SIZE			U(0x40000)
 #define IMX_NS_OCRAM_BASE		U(0x900000)
 #define IMX_NS_OCRAM_SIZE		U(0x20000)
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 #define IMX_CAAM_RAM_BASE		U(0x100000)
 #define IMX_CAAM_RAM_SIZE		U(0x10000)
 #define IMX_DRAM_BASE			U(0x40000000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 6136820..f0cdb3e 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -30,7 +30,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -46,13 +47,13 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ifeq (${NEED_BL2},yes)
@@ -126,21 +127,20 @@
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx8mm_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
@@ -153,6 +153,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index f9e430b..befa769 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -126,7 +127,7 @@
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	unsigned int val;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -192,6 +193,13 @@
 #endif
 #endif
 
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+				      &bl32_image_ep_info, &bl33_image_ep_info);
+	}
+
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
 #endif
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 8e7be98..569432d 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -140,6 +140,8 @@
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
 #define SAVED_DRAM_TIMING_BASE		OCRAM_S_BASE
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 6036b6a..6a9d22e 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -25,7 +25,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -41,12 +42,12 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -59,6 +60,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 8e35219..ffad3d1 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -156,6 +157,7 @@
 	static console_t console;
 	unsigned int val;
 	unsigned int i;
+	int ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -213,6 +215,13 @@
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 4a03830..84a7e00 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -172,6 +172,9 @@
 
 #define MAX_CSU_NUM			U(64)
 
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
+
 #define OCRAM_S_BASE			U(0x00180000)
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 40764b1..5df598c 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -26,7 +26,8 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -42,12 +43,12 @@
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -123,21 +124,20 @@
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx8mp_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
@@ -150,6 +150,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 6556c7f..73179dd 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -43,7 +43,6 @@
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ENABLE_PIE		:=	1
@@ -56,6 +55,14 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	0
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
 ifneq (${PRELOADED_BL33_BASE},)
 $(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
 endif
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
index 719c390..1cf0666 100644
--- a/plat/imx/imx8m/include/dram.h
+++ b/plat/imx/imx8m/include/dram.h
@@ -70,13 +70,19 @@
 
 extern struct dram_info dram_info;
 
-void dram_info_init(unsigned long dram_timing_base);
 void dram_umctl2_init(struct dram_timing_info *timing);
 void dram_phy_init(struct dram_timing_info *timing);
 
 /* dram retention */
+#if IMX_DRAM_RETENTION
+void dram_info_init(unsigned long dram_timing_base);
 void dram_enter_retention(void);
 void dram_exit_retention(void);
+#else
+static inline void dram_info_init(unsigned long dram_timing_base) {}
+static inline void dram_enter_retention(void) {}
+static inline void dram_exit_retention(void) {}
+#endif
 
 void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
 
diff --git a/plat/imx/imx93/imx93_bl31_setup.c b/plat/imx/imx93/imx93_bl31_setup.c
index a7d0f65..d997e9a 100644
--- a/plat/imx/imx93/imx93_bl31_setup.c
+++ b/plat/imx/imx93/imx93_bl31_setup.c
@@ -20,6 +20,7 @@
 #include <plat/common/platform.h>
 
 #include <imx8_lpuart.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 #include <platform_def.h>
 
@@ -90,6 +91,9 @@
 	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
+
+	imx_bl31_params_parse(arg0, OCRAM_BASE, OCRAM_SIZE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
 }
 
 void bl31_plat_arch_setup(void)
diff --git a/plat/imx/imx93/include/platform_def.h b/plat/imx/imx93/include/platform_def.h
index 7efbf1c..f0d53cd 100644
--- a/plat/imx/imx93/include/platform_def.h
+++ b/plat/imx/imx93/include/platform_def.h
@@ -31,6 +31,9 @@
 #define BL31_BASE			U(0x204E0000)
 #define BL31_LIMIT			U(0x20520000)
 
+#define OCRAM_BASE			U(0x20480000)
+#define OCRAM_SIZE			U(0xA0000)
+
 /* non-secure uboot base */
 /* TODO */
 #define PLAT_NS_IMAGE_OFFSET		U(0x80200000)
diff --git a/plat/imx/imx93/platform.mk b/plat/imx/imx93/platform.mk
index ed7e81f..f506d8b 100644
--- a/plat/imx/imx93/platform.mk
+++ b/plat/imx/imx93/platform.mk
@@ -19,9 +19,11 @@
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/common/aarch64/crash_console_helpers.S   \
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
 				plat/imx/imx93/aarch64/plat_helpers.S		\
 				plat/imx/imx93/plat_topology.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/lpuart_console.S		\
 				plat/imx/imx93/trdc.c			\
 				plat/imx/imx93/pwr_ctrl.c			\
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index 6d8825f..18aa48e 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -14,6 +14,7 @@
 
 #include "cadence_qspi.h"
 #include "socfpga_plat_def.h"
+#include "wdt/watchdog.h"
 
 #define LESS(a, b)   (((a) < (b)) ? (a) : (b))
 #define MORE(a, b)   (((a) > (b)) ? (a) : (b))
@@ -654,6 +655,9 @@
 
 			read_count += level * sizeof(uint8_t);
 			count++;
+#if ARM_LINUX_KERNEL_AS_BL33
+			watchdog_sw_rst();
+#endif
 		} while (level > 0);
 	}
 
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 3e44833..fcee101 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.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
  */
@@ -75,6 +76,7 @@
 #define MBOX_RSU_STATUS					0x5B
 #define MBOX_RSU_UPDATE					0x5C
 #define MBOX_HPS_STAGE_NOTIFY				0x5D
+#define MBOX_RSU_GET_DEVICE_INFO			0x74
 
 /* FCS Command */
 #define MBOX_FCS_GET_PROVISION				0x7B
@@ -249,6 +251,7 @@
 
 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_get_device_info(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_update(uint32_t *flash_offset);
 int mailbox_hps_stage_notify(uint32_t execution_stage);
 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index d45ab11..d2eceb9 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.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
  */
@@ -64,6 +65,7 @@
 #define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY				0xC2000013
 #define INTEL_SIP_SMC_RSU_DCMF_STATUS					0xC2000014
 #define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS				0xC2000015
+#define INTEL_SIP_SMC_RSU_GET_DEVICE_INFO				0xC2000016
 
 /* Hardware monitor */
 #define INTEL_SIP_SMC_HWMON_READTEMP					0xC2000020
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index e2a25ea..b8e5cde 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -578,6 +579,13 @@
 	return ret;
 }
 
+int mailbox_rsu_get_device_info(uint32_t *resp_buf, unsigned int resp_buf_len)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_GET_DEVICE_INFO, NULL, 0U,
+				CMD_CASUAL, resp_buf,
+				&resp_buf_len);
+}
+
 int mailbox_rsu_update(uint32_t *flash_offset)
 {
 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index 5204146..5c80798 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -777,14 +777,6 @@
 		VERBOSE("Deassert F2SDRAM ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_F2SSDRAM0);
-
-		/*
-		 * Clear fpga2sdram_manager_main_SidebandManager_FlagOutClr0
-		 * f2s_ready_latency_enable
-		 */
-		VERBOSE("Clear F2SDRAM f2s_ready_latency_enable ...\n");
-		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
-			FLAGOUTCLR0_F2SDRAM0_ENABLE);
 	}
 #else
 	if (brg_mask != 0U) {
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index f68dc29..2f88c86 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -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
  */
@@ -507,6 +509,16 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+static uint32_t intel_rsu_get_device_info(uint32_t *respbuf,
+					  unsigned int respbuf_sz)
+{
+	if (mailbox_rsu_get_device_info((uint32_t *)respbuf, respbuf_sz) < 0) {
+		return INTEL_SIP_SMC_RSU_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 uint32_t intel_rsu_update(uint64_t update_address)
 {
 	if (update_address > SIZE_MAX) {
@@ -878,6 +890,16 @@
 		status = intel_rsu_copy_dcmf_version(x1, x2);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_RSU_GET_DEVICE_INFO:
+		status = intel_rsu_get_device_info((uint32_t *)rsu_respbuf,
+					ARRAY_SIZE(rsu_respbuf));
+		if (status) {
+			SMC_RET1(handle, status);
+		} else {
+			SMC_RET5(handle, status, rsu_respbuf[0], rsu_respbuf[1],
+				 rsu_respbuf[2], rsu_respbuf[3]);
+		}
+
 	case INTEL_SIP_SMC_RSU_DCMF_STATUS:
 		SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK,
 			 ((uint64_t)rsu_dcmf_stat[3] << 48) |
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index b9c28de..e8f892d 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -150,90 +150,89 @@
 	$(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist"))
 	$(if $(wildcard $(CRYPTOPP_INCDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_INCDIR' was set to '$(CRYPTOPP_INCDIR)', but '$(CRYPTOPP_INCDIR)' does not exist"))
 ifdef CRYPTOPP_PATH
-	$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
+	$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
 endif
-	$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
+	$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
 
 $(WTMI_MULTI_IMG): FORCE
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
+	$(q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
 
 $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG)
-	$(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
+	$(q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
 
 $(TIMDDRTOOL): FORCE
 #	Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
 	$(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
+	$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
 
-$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building uart images"
-	$(Q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART)
-	$(Q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
-	$(Q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
+$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL) | $(BUILD_PLAT)/$(BUILD_UART)/ $$(@D)/
+	$(s)echo
+	$(s)echo "Building uart images"
+	$(q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
+	$(q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
 endif
-	$(Q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 $(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building flash image"
-	$(Q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
-	@$(ECHO_BLANK_LINE)
-	@echo "=======================================================";
-	@echo "  Secure boot. Encrypting wtmi and boot-image";
-	@echo "=======================================================";
-	@$(ECHO_BLANK_LINE)
-	$(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
+	$(s)echo
+	$(s)echo "=======================================================";
+	$(s)echo "  Secure boot. Encrypting wtmi and boot-image";
+	$(s)echo "=======================================================";
+	$(s)echo
+	$(q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
+	$(q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
 	-out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
-	$(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
+	$(q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
 	-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
-	$(Q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
-	$(Q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
+	$(q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
+	$(q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 clean realclean distclean: mrvl_clean
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
 ifdef CRYPTOPP_PATH
-	-$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
+	-$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
 endif
 
 else # WTP
diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c
index f105d59..030a614 100644
--- a/plat/marvell/armada/a3k/common/cm3_system_reset.c
+++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c
@@ -8,11 +8,22 @@
 #include <stdbool.h>
 
 #include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
+#include <a3700_pm.h>
+#include <platform_def.h>
 #include <mvebu_def.h>
 
+/* IO Decoder Error Interrupt Status Registers */
+#define MVEBU_DEC_WIN_REGS_BASE(p)		(MVEBU_REGS_BASE + 0xC000 + \
+						 (p) * 0x100)
+#define MVEBU_DEC_WIN_ERR_INT_STS_REG(p)	(MVEBU_DEC_WIN_REGS_BASE(p) + \
+						 0xF8)
+
 /* Cortex-M3 Secure Processor Mailbox Registers */
 #define MVEBU_RWTM_PARAM0_REG			(MVEBU_RWTM_REG_BASE)
 #define MVEBU_RWTM_CMD_REG			(MVEBU_RWTM_REG_BASE + 0x40)
@@ -23,6 +34,122 @@
 #define MVEBU_RWTM_REBOOT_CMD		0x0009
 #define MVEBU_RWTM_REBOOT_MAGIC		0xDEADBEEF
 
+static inline uint32_t a3700_gicd_read(uint32_t reg)
+{
+	return mmio_read_32(PLAT_MARVELL_GICD_BASE + reg);
+}
+
+static inline void a3700_gicd_write(uint32_t reg, uint32_t value)
+{
+	mmio_write_32(PLAT_MARVELL_GICD_BASE + reg, value);
+}
+
+static void a3700_gicd_ctlr_clear_bits(uint32_t bits)
+{
+	uint32_t val;
+
+	val = a3700_gicd_read(GICD_CTLR);
+	if ((val & bits) != 0U) {
+		a3700_gicd_write(GICD_CTLR, val & ~bits);
+		mdelay(1);
+
+		if ((a3700_gicd_read(GICD_CTLR) & GICD_CTLR_RWP_BIT) != 0U) {
+			ERROR("could not clear bits 0x%x in GIC distributor control\n",
+			      bits);
+		}
+	}
+}
+
+static void a3700_gic_dist_disable_irqs(void)
+{
+	int i;
+
+	for (i = 32; i < 224; i += 32) {
+		a3700_gicd_write(GICD_ICENABLER + (i >> 3), GENMASK_32(31, 0));
+	}
+}
+
+static inline uintptr_t a3700_rdist_base(unsigned int proc)
+{
+	return PLAT_MARVELL_GICR_BASE + (proc << GICR_V3_PCPUBASE_SHIFT);
+}
+
+static inline uint32_t a3700_gicr_read(unsigned int proc, uint32_t reg)
+{
+	return mmio_read_32(a3700_rdist_base(proc) + reg);
+}
+
+static inline void a3700_gicr_write(unsigned int proc, uint32_t reg,
+				    uint32_t value)
+{
+	mmio_write_32(a3700_rdist_base(proc) + reg, value);
+}
+
+static void a3700_gic_redist_disable_irqs(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_ICENABLER0, GENMASK_32(31, 0));
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_CTLR) & GICR_CTLR_RWP_BIT) != 0U) {
+		ERROR("could not disable core %u PPIs & SGIs\n", proc);
+	}
+}
+
+static void a3700_gic_redist_mark_asleep(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_WAKER,
+			 a3700_gicr_read(proc, GICR_WAKER) | WAKER_PS_BIT);
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_WAKER) & WAKER_CA_BIT) == 0U) {
+		ERROR("could not mark core %u redistributor asleep\n", proc);
+	}
+}
+
+static void a3700_io_addr_dec_ack_err_irq(void)
+{
+	unsigned int periph;
+
+	for (periph = 0; periph < 16; ++periph) {
+		/* periph 6 does not exist */
+		if (periph == 6)
+			continue;
+
+		mmio_write_32(MVEBU_DEC_WIN_ERR_INT_STS_REG(periph),
+			      GENMASK_32(1, 0));
+	}
+}
+
+static void a3700_gic_reset(void)
+{
+	a3700_gic_redist_disable_irqs(0);
+	a3700_gic_redist_disable_irqs(1);
+
+	a3700_gic_redist_mark_asleep(0);
+	a3700_gic_redist_mark_asleep(1);
+
+	a3700_io_addr_dec_ack_err_irq();
+
+	a3700_pm_ack_irq();
+
+	a3700_gic_dist_disable_irqs();
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1NS_BIT |
+				   CTLR_ENABLE_G1S_BIT);
+
+	/* Clearing ARE_S and ARE_NS bits is undefined in the specification, but
+	 * works if the previous operations are successful. We need to do it in
+	 * order to put GIC into the same state it was in just after reset. If
+	 * this is successful, the rWTM firmware in the secure coprocessor will
+	 * reset all other peripherals one by one, load new firmware and boot
+	 * it, all without triggering the true warm reset via the WARM_RESET
+	 * register (which may hang the board).
+	 */
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_S_BIT);
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_NS_BIT);
+}
+
 static inline bool rwtm_completed(void)
 {
 	return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
@@ -43,6 +170,11 @@
 {
 	int tries = 5;
 
+	/* Put GIC into the same state it was just after reset. This is needed
+	 * for the reset issue workaround to work.
+	 */
+	a3700_gic_reset();
+
 	for (; tries > 0; --tries) {
 		mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
 				MVEBU_RWTM_HOST_INT_SP_COMPLETE);
diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h
index 44dbb9f..1be82b2 100644
--- a/plat/marvell/armada/a3k/common/include/a3700_pm.h
+++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h
@@ -48,6 +48,8 @@
 
 struct pm_wake_up_src_config *mv_wake_up_src_config_get(void);
 
+void a3700_pm_ack_irq(void);
+
 void cm3_system_reset(void);
 
 #endif /* A3700_PM_H */
diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c
index e2d15ab..d573b79 100644
--- a/plat/marvell/armada/a3k/common/plat_pm.c
+++ b/plat/marvell/armada/a3k/common/plat_pm.c
@@ -197,7 +197,7 @@
 {
 }
 
-static void a3700_pm_ack_irq(void)
+void a3700_pm_ack_irq(void)
 {
 	uint32_t reg;
 
diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 4d8a87f..bdad8b5 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -176,17 +176,17 @@
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	@echo "  Doimage CLEAN"
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
+	$(s)echo "  Doimage CLEAN"
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}: FORCE
-	@$(DOIMAGE_LIBS_CHECK)
-	${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH}
+	$(q)$(DOIMAGE_LIBS_CHECK)
+	$(q)${MAKE} --no-print-directory -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL}
-	@${ECHO_BLANK_LINE}
-	@echo "Building flash image"
-	${Q}${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 752ab41..5ab6123 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -32,4 +32,4 @@
 	$(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	@+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
+	$(q)+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk
index f0e6edf..2561232 100644
--- a/plat/marvell/armada/common/marvell_common.mk
+++ b/plat/marvell/armada/common/marvell_common.mk
@@ -84,13 +84,13 @@
 
 $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME)
 	$(if $(shell find $(BUILD_PLAT)/bl1.bin -type f -size +128k),$(error "Image '$(BUILD_PLAT)/bl1.bin' is bigger than 128kB"))
-	@cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 .PHONY: mrvl_bootimage
 mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index ac2cbad..0cb2014 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -27,12 +27,10 @@
 # Determine option variable is defined or not then define it
 define add_defined_option
 ifdef $(1)
-ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
-DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
-else
 ifeq ($(strip $(value $(1))),y)
 DEFINES += -D$(1)$(if $(value $(1)),=1,)
-endif
+else ifneq ($(strip $(value $(1))),n)
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
 endif
 endif
 endef
@@ -73,15 +71,6 @@
         $(eval SOURCES    := $(2))
         $(eval OBJS_TEMP  := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MODULE_OBJS += $(OBJS_TEMP))
-        # We use sort only to get a list of unique object directory names.
-        # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS_TEMP} ${LINKERFILE})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
-
-$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-${3}_dirs: | ${OBJ_DIRS}
 
 $(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
 
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index ef7134c..329a45e 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -18,7 +18,7 @@
 #define FORBIDDEN			(5)
 #define SEC_R_NSEC_RW			(6)
 
-#define LOCK				(1)
+#define LOCK				(1UL)
 #define UNLOCK				(0)
 
 #if (EMI_MPU_DGROUP_NUM == 1)
@@ -69,6 +69,7 @@
 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
 						  uint64_t zone_info);
 int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+int emi_mpu_clear_protection(unsigned int region);
 void set_emi_mpu_regions(void);
 int set_apu_emi_mpu_region(void);
 #endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index 8810be3..1e732f0 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -39,13 +39,13 @@
 	}
 
 #if ENABLE_EMI_MPU_SW_LOCK
-	if (region_lock_state[region] == 1) {
+	if (region_lock_state[region] == LOCK) {
 		WARN("invalid region\n");
 		return -1;
 	}
 
 	if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
-		region_lock_state[region] = 1;
+		region_lock_state[region] = LOCK;
 	}
 
 	apc &= EMI_MPU_APC_SW_LOCK_MASK;
@@ -73,6 +73,50 @@
 	return 0;
 }
 
+int emi_mpu_clear_protection(unsigned int region)
+{
+	unsigned int dgroup;
+
+	if (region >= EMI_MPU_REGION_NUM) {
+		WARN("invalid region number\n");
+		return -1;
+	}
+
+#if ENABLE_EMI_MPU_SW_LOCK
+	if (region_lock_state[region] == LOCK) {
+		WARN("SW:region is locked\n");
+		return -1;
+	}
+#endif
+	if (mmio_read_32(EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:EMI-MPU region is locked\n");
+		return -1;
+	}
+
+#if defined(SUB_EMI_MPU_BASE)
+	if (mmio_read_32(SUB_EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:SUB EMI-MPU region is locked\n");
+		return -1;
+	}
+#endif
+
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(EMI_MPU_SA(region), 0x0);
+	mmio_write_32(EMI_MPU_EA(region), 0x0);
+
+#if defined(SUB_EMI_MPU_BASE)
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(SUB_EMI_MPU_SA(region), 0);
+	mmio_write_32(SUB_EMI_MPU_EA(region), 0);
+#endif
+	return 0;
+}
+
+
 static void dump_emi_mpu_regions(void)
 {
 	int region, i;
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index e8882f0..efb70b7 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -14,11 +14,35 @@
 {
 	struct emi_region_info_t region_info;
 
+	/* BL31 address */
+	region_info.start = TZRAM_BASE;
+	region_info.end = TZRAM_BASE + TZRAM_SIZE - 1;
+	region_info.region = BL31_EMI_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+
+#ifndef SPD_NONE
+	/* BL32 address */
+	region_info.start = BL32_REGION_BASE;
+	region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1;
+	region_info.region = BL32_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+#endif
+
 	/* SCP core0 DRAM */
-	region_info.start = 0x50000000ULL;
-	region_info.end = 0x528FFFFFULL;
-	region_info.region = 2;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE0_REGION_BASE;
+	region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1;
+	region_info.region = SCP_CORE0_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -26,10 +50,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* SCP core1 DRAM */
-	region_info.start = 0x70000000ULL;
-	region_info.end = 0x729FFFFFULL;
-	region_info.region = 3;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE1_REGION_BASE;
+	region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1;
+	region_info.region = SCP_CORE1_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -37,10 +61,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* DSP protect address */
-	region_info.start = 0x60000000ULL;
-	region_info.end = 0x610FFFFFULL;
-	region_info.region = 4;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DSP_PROTECT_REGION_BASE;
+	region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1;
+	region_info.region = DSP_PROTECT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
@@ -48,10 +72,10 @@
 	emi_mpu_set_protection(&region_info);
 
 	/* All default settings */
-	region_info.start = 0x40000000ULL;
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 31;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DRAM_START_ADDR;
+	region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1;
+	region_info.region = ALL_DEFAULT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
@@ -65,7 +89,7 @@
 
 	region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
 	region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
-	region_info.region = APUSYS_SEC_BUF_EMI_REGION;
+	region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID;
 
 	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
@@ -86,12 +110,18 @@
 	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
 }
 
+static inline uint32_t get_decoded_set_clear_info(uint32_t info)
+{
+	return (info & 0x0000FFFF);
+}
+
 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
 						  uint64_t zone_info)
 {
 	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
 	struct emi_region_info_t region_info;
 	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
+	uint32_t is_set = get_decoded_set_clear_info(zone_info);
 
 	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
 	     encoded_addr, zone_size, zone_info);
@@ -101,17 +131,21 @@
 		return MTK_SIP_E_INVALID_PARAM;
 	}
 
-	/* SVP DRAM */
-	region_info.start = phys_addr;
-	region_info.end = phys_addr + zone_size;
-	region_info.region = 4;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+	if (is_set > 0) {
+		/* SVP DRAM */
+		region_info.start = phys_addr;
+		region_info.end = phys_addr + zone_size - 1;
+		region_info.region = SVP_DRAM_REGION_ID;
+		SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
 
-	emi_mpu_set_protection(&region_info);
+		emi_mpu_set_protection(&region_info);
+	} else { /* clear region protection */
+		emi_mpu_clear_protection(SVP_DRAM_REGION_ID);
+	}
 
 	return 0;
-}
\ No newline at end of file
+}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
index cc7f7f1..18acb9c 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -7,7 +7,7 @@
 #ifndef EMI_MPU_PRIV_H
 #define EMI_MPU_PRIV_H
 
-#define ENABLE_EMI_MPU_SW_LOCK		(1)
+#define ENABLE_EMI_MPU_SW_LOCK		(0)
 
 #define EMI_MPU_CTRL			(EMI_MPU_BASE + 0x000)
 #define EMI_MPU_DBG			(EMI_MPU_BASE + 0x004)
@@ -38,13 +38,34 @@
 #define EMI_MPU_DOMAIN_NUM		(16)
 #define EMI_MPU_REGION_NUM		(32)
 #define EMI_MPU_ALIGN_BITS		(16)
-#define DRAM_OFFSET			(0x40000000 >> EMI_MPU_ALIGN_BITS)
+#define DRAM_START_ADDR                 (0x40000000ULL)
+#define DRAM_OFFSET			(DRAM_START_ADDR >> EMI_MPU_ALIGN_BITS)
+#define DRAM_MAX_SIZE			(0x200000000ULL)
+#define BL32_REGION_BASE		(0x43000000ULL)
+#define BL32_REGION_SIZE		(0x4600000ULL)
+#define SCP_CORE0_REGION_BASE		(0x50000000ULL)
+#define SCP_CORE0_REGION_SIZE		(0x800000ULL)
+#define SCP_CORE1_REGION_BASE		(0x70000000ULL)
+#define SCP_CORE1_REGION_SIZE		(0xa000000ULL)
+#define DSP_PROTECT_REGION_BASE		(0x60000000ULL)
+#define DSP_PROTECT_REGION_SIZE		(0x1100000ULL)
 
 #define EMI_MPU_DGROUP_NUM		(EMI_MPU_DOMAIN_NUM / 8)
 
 /* APU EMI MPU Setting */
-#define APUSYS_SEC_BUF_EMI_REGION	(21)
 #define APUSYS_SEC_BUF_PA		(0x55000000)
 #define APUSYS_SEC_BUF_SZ		(0x100000)
 
+enum region_ids {
+	BL31_EMI_REGION_ID = 0,
+	BL32_REGION_ID,
+	SCP_CORE0_REGION_ID,
+	SCP_CORE1_REGION_ID,
+	DSP_PROTECT_REGION_ID,
+	SVP_DRAM_REGION_ID,
+
+	APUSYS_SEC_BUF_EMI_REGION_ID = 21,
+
+	ALL_DEFAULT_REGION_ID = 31,
+};
 #endif
diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
index 85f9e37..2f9765c 100644
--- a/plat/mediatek/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -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
  */
@@ -27,6 +27,10 @@
 /* we save and restore the GICv3 context on system suspend */
 gicv3_dist_ctx_t dist_ctx;
 
+static const interrupt_prop_t mtk_interrupt_props[] = {
+	PLAT_MTK_G1S_IRQ_PROPS(INTR_GROUP1S)
+};
+
 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
 {
 	return plat_core_pos_by_mpidr(mpidr);
@@ -35,6 +39,8 @@
 gicv3_driver_data_t mt_gicv3_data = {
 	.gicd_base = MT_GIC_BASE,
 	.gicr_base = MT_GIC_RDIST_BASE,
+	.interrupt_props = mtk_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(mtk_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
 	.rdistif_base_addrs = rdistif_base_addrs,
 	.mpidr_to_core_pos = mt_mpidr_to_core_pos,
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index 850ce2f..98b88bd 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -83,6 +83,8 @@
 #define BASE_GICD_BASE		MT_GIC_BASE
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE		(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM		(11)
 #define CIRQ_IRQ_NUM		(326)
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 71a4e97..8e0f5f9 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,6 +96,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE		(MT_GIC_BASE)
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID		580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 /*******************************************************************************
  * CIRQ related constants
diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h
index ec377b5..1b25e00 100644
--- a/plat/mediatek/mt8192/include/platform_def.h
+++ b/plat/mediatek/mt8192/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,6 +82,8 @@
 #define BASE_GICD_BASE        MT_GIC_BASE
 #define MT_GIC_RDIST_BASE     (MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE         (IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM          14
 #define CIRQ_IRQ_NUM          439
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index 8696f2a..a70abec 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -95,6 +95,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE			MT_GIC_BASE
 #define MT_GIC_RDIST_BASE		(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID			580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 #define SYS_CIRQ_BASE			(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM			23
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 5309d98..4ff9888 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, 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
@@ -142,7 +142,7 @@
 	val = read_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_SP_EL0));
 	write_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_X2), (val));
 
-	val = read_ctx_reg((el1state_ctx), (uint32_t)(CTX_SP_EL1));
+	val = read_el1_ctx_common(el1state_ctx, sp_el1);
 	write_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_X3), (val));
 
 	return 0;
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 83d815a..8232883 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -356,10 +356,10 @@
 	 * will re-init this info from non-secure software when the
 	 * core come online.
 	 */
-	actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1));
+	actlr_elx = read_el1_ctx_common((get_el1_sysregs_ctx(ctx)), actlr_el1);
 	actlr_elx &= ~DENVER_CPU_PMSTATE_MASK;
 	actlr_elx |= DENVER_CPU_PMSTATE_C1;
-	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+	write_el1_ctx_common((get_el1_sysregs_ctx(ctx)), actlr_el1, actlr_elx);
 
 	/*
 	 * Check if we are exiting from deep sleep and restore SE
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
index 4e84d02..14ddefd 100644
--- a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -1,6 +1,6 @@
 #
 # Copyright 2018-2020 NXP
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -73,7 +73,7 @@
 ifeq (${FUSE_PROV_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}: ${FUSE_PROV_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -81,7 +81,7 @@
 ifeq (${FUSE_UP_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_UP_FILE_SB}: ${FUSE_UP_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -94,6 +94,6 @@
 endif
 	${FIPTOOL} create ${FUSE_FIP_ARGS} $@
 	${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 4aac9d6..000e419 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -131,14 +131,14 @@
 
     certificates: $(ROT_KEY)
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 
 endif #MBEDTLS_DIR
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index f265d95..705832c 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -4,10 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
 #include <plat_console.h>
+#include <s32cc-clk-drv.h>
 #include <plat_io_storage.h>
 
 #define SIUL2_PC09_MSCR		UL(0x4009C2E4)
@@ -50,6 +52,13 @@
 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3)
 {
+	int ret;
+
+	ret = s32cc_init_early_clks();
+	if (ret != 0) {
+		panic();
+	}
+
 	linflex_config_pinctrl();
 	console_s32g2_register();
 
diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c
index 27cae12..542fa7b 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_console.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_console.c
@@ -11,11 +11,12 @@
 
 void console_s32g2_register(void)
 {
-	static console_t s32g2_console;
+	static console_t s32g2_console = {
+		.next = NULL,
+		.flags = 0u,
+	};
 	int ret;
 
-	(void)memset(&s32g2_console, 0, sizeof(s32g2_console));
-
 	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 ee1507e..316ed2c 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -35,6 +35,7 @@
 
 # Selecting Drivers for SoC
 $(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM))
 
 include ${PLAT_DRIVERS_PATH}/drivers.mk
 
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index f14a9e8..c303ced 100644
--- a/plat/nxp/soc-lx2160a/ddr_fip.mk
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -38,8 +38,6 @@
     DDR_DMEM_RDIMM_2D	:=	${DDR_PHY_BIN_PATH}/ddr4_rdimm2d_pmu_train_dmem.bin
 endif
 
-$(shell mkdir -p '${BUILD_PLAT}')
-
 ifeq (${DDR_FIP_NAME},)
 ifeq (${TRUSTED_BOARD_BOOT},1)
 	DDR_FIP_NAME	:= ddr_fip_sec.bin
@@ -73,11 +71,11 @@
 
 ifneq (${GENERATE_COT},0)
 ddr_certificates: ${DDR_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${DDR_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "DDR certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${DDR_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "DDR certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif
 endif
 endif
@@ -88,10 +86,10 @@
 
 ${BUILD_PLAT}/${DDR_FIP_NAME}: ${DDR_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_DDR_FIP_CMD})
-	${Q}${FIPTOOL} create ${DDR_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${DDR_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fip_ddr: ${BUILD_PLAT}/${DDR_FIP_NAME}
diff --git a/plat/nxp/soc-lx2160a/ddr_sb.mk b/plat/nxp/soc-lx2160a/ddr_sb.mk
index c11651e..119fc08 100644
--- a/plat/nxp/soc-lx2160a/ddr_sb.mk
+++ b/plat/nxp/soc-lx2160a/ddr_sb.mk
@@ -36,7 +36,7 @@
 endif
 
 %.sb: %
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${DDR_INPUT_FILE}
 
diff --git a/plat/nxp/soc-lx2160a/ddr_tbbr.mk b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
index deb475b..836a431 100644
--- a/plat/nxp/soc-lx2160a/ddr_tbbr.mk
+++ b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
@@ -39,8 +39,6 @@
 # Pass the non-volatile counters to the cert_create tool
 $(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr,DDR_))
 
-$(shell mkdir -p '${BUILD_PLAT}')
-
 ifeq (${DDR_KEY},)
 DDR_KEY=${BUILD_PLAT}/ddr.pem
 endif
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index 60acb25..c96e4b9 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -173,7 +173,8 @@
 	 * 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) < 0) {
+			       PLAT_QEMU_L0_GPT_SIZE +
+			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
 		ERROR("gpt_init_l0_tables() failed!\n");
 		panic();
 	}
@@ -356,12 +357,20 @@
 	case BL31_IMAGE_ID:
 		/*
 		 * arg0 is a bl_params_t reserved for bl31_early_platform_setup2
-		 * we just need arg1 and arg3 for BL31 to update th TL from S
+		 * we just need arg1 and arg3 for BL31 to update the TL from S
 		 * to NS memory before it exits
 		 */
-		bl_mem_params->ep_info.args.arg1 =
-			TRANSFER_LIST_SIGNATURE |
-			REGISTER_CONVENTION_VERSION_MASK;
+#ifdef __aarch64__
+		if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_64) {
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+		} else
+#endif
+		{
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		}
+
 		bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
 		break;
 #endif
diff --git a/plat/qemu/common/qemu_plat_attest_token.c b/plat/qemu/common/qemu_plat_attest_token.c
index f7d7e90..141ff57 100644
--- a/plat/qemu/common/qemu_plat_attest_token.c
+++ b/plat/qemu/common/qemu_plat_attest_token.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,91 +10,200 @@
 
 #include <plat/common/platform.h>
 
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
 static const uint8_t sample_platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x7a, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+	0x61, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x43, 0x43, 0x41, 0x2d, 0x53, 0x53, 0x44, 0x2f,
+	0x31, 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20,
+	0xb5, 0x97, 0x3c, 0xb6, 0x8b, 0xaa, 0x9f, 0xc5,
+	0x55, 0x58, 0x78, 0x6b, 0x7e, 0xc6, 0x7f, 0x69,
+	0xe4, 0x0d, 0xf5, 0xba, 0x5a, 0xa9, 0x21, 0xcd,
+	0x0c, 0x27, 0xf4, 0x05, 0x87, 0xa0, 0x11, 0xea,
+	0x19, 0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c,
 	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e,
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
 	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+	0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
+	0x0a, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b,
+	0x1a, 0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf,
+	0xcf, 0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30,
+	0x03, 0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78,
+	0x3a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+	0x2f, 0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f,
+	0x6e, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d,
+	0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76,
+	0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4,
+	0x01, 0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c,
+	0x31, 0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b,
+	0x6e, 0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3,
+	0x20, 0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d,
+	0x9b, 0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86,
+	0xaa, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47,
+	0x2b, 0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3,
+	0xfe, 0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb,
+	0xfd, 0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd,
+	0xd3, 0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53,
+	0x45, 0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f,
+	0x0a, 0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44,
+	0xea, 0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63,
+	0x4b, 0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02,
+	0xa2, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68,
+	0x51, 0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4,
+	0x4b, 0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7,
+	0x9e, 0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5,
+	0x01, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43,
+	0xa9, 0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7,
+	0x2c, 0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0,
+	0xa3, 0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c,
+	0x58, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53,
+	0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec,
+	0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41,
+	0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22,
+	0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02,
+	0x58, 0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f,
+	0xcd, 0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47,
+	0x61, 0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf,
+	0xaa, 0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d,
+	0x6f, 0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43,
+	0x50, 0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20,
+	0xf1, 0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58,
+	0x14, 0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2,
+	0x0f, 0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7,
+	0x61, 0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56,
+	0x02, 0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0,
+	0xbb, 0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65,
+	0x34, 0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c,
+	0x36, 0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c,
+	0x1f, 0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41,
+	0x50, 0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5,
+	0x98, 0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae,
+	0xfa, 0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6,
+	0x01, 0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9,
+	0x66, 0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63,
+	0x52, 0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae,
+	0x16, 0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6,
+	0x71, 0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17,
+	0x90, 0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81,
+	0x64, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02,
+	0x97, 0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17,
+	0x2b, 0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18,
+	0x31, 0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca,
+	0xae, 0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69,
+	0x46, 0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
+	0x47, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63,
+	0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15,
+	0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d,
+	0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa,
+	0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a,
+	0x92, 0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65,
+	0x8c, 0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56,
+	0x68, 0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c,
+	0x89, 0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06,
+	0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36,
+	0xa4, 0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57,
+	0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05,
+	0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53,
+	0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2,
+	0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60,
+	0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f,
+	0x7a, 0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03,
+	0x18, 0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b,
+	0x3f, 0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec,
+	0x0a, 0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc,
+	0x7c, 0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73,
+	0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01,
+	0x6d, 0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d,
+	0x26, 0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3,
+	0x39, 0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85,
+	0x29, 0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc,
+	0xe0, 0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x21,
+	0x51, 0x20, 0x92, 0xd6, 0xd0, 0x2a, 0xe6, 0xbe,
+	0x2f, 0xe3, 0x93, 0x0e, 0xa5, 0x1f, 0xd6, 0x98,
+	0x96, 0x32, 0x24, 0x56, 0xe9, 0xdf, 0xc7, 0x32,
+	0x5e, 0x0b, 0x78, 0x68, 0xb6, 0x90, 0x73, 0x2a,
+	0x0c, 0x0f, 0x07, 0x77, 0xc1, 0x15, 0x40, 0x4b,
+	0xe1, 0xfc, 0x83, 0x9b, 0x7d, 0x30, 0x4f, 0x4f,
+	0xe6, 0xfa, 0x46, 0xae, 0x12, 0xa3, 0x08, 0x3a,
+	0xcf, 0x24, 0x06, 0x67, 0x91, 0x06, 0xbf, 0xae,
+	0x50, 0x31, 0x79, 0xdd, 0x50, 0x33, 0x49, 0x12,
+	0xbf, 0xc6, 0xda, 0x33, 0x6d, 0xd6, 0x18, 0x25,
+	0x43, 0x54, 0x4d, 0xb5, 0x88, 0xd6, 0xae, 0x67,
+	0x35, 0x7a, 0xfd, 0xb0, 0x5f, 0x95, 0xb7
 };
 
 /*
diff --git a/plat/qemu/common/qemu_pm.c b/plat/qemu/common/qemu_pm.c
index c2b5091..5f64d70 100644
--- a/plat/qemu/common/qemu_pm.c
+++ b/plat/qemu/common/qemu_pm.c
@@ -102,22 +102,6 @@
 }
 
 /*******************************************************************************
- * Platform handler called to check the validity of the non secure
- * entrypoint.
- ******************************************************************************/
-static int qemu_validate_ns_entrypoint(uintptr_t entrypoint)
-{
-	/*
-	 * Check if the non secure entrypoint lies within the non
-	 * secure DRAM.
-	 */
-	if ((entrypoint >= NS_DRAM0_BASE) &&
-	    (entrypoint < (NS_DRAM0_BASE + NS_DRAM0_SIZE)))
-		return PSCI_E_SUCCESS;
-	return PSCI_E_INVALID_ADDRESS;
-}
-
-/*******************************************************************************
  * Platform handler called when a CPU is about to enter standby.
  ******************************************************************************/
 static void qemu_cpu_standby(plat_local_state_t cpu_state)
@@ -241,7 +225,6 @@
 	.system_off = qemu_system_off,
 	.system_reset = qemu_system_reset,
 	.validate_power_state = qemu_validate_power_state,
-	.validate_ns_entrypoint = qemu_validate_ns_entrypoint
 };
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 95620d3..db9d65a 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -342,8 +342,11 @@
  * Tables
  */
 #define PLAT_QEMU_L0_GPT_BASE		(PLAT_QEMU_L1_GPT_BASE -	\
-					 PLAT_QEMU_L0_GPT_SIZE)
+					 (PLAT_QEMU_L0_GPT_SIZE +	\
+					  PLAT_QEMU_GPT_BITLOCK_SIZE))
 #define PLAT_QEMU_L0_GPT_SIZE		(2 * PAGE_SIZE)
+/* Two pages so the L0 GPT is naturally aligned.  */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE	(2 * PAGE_SIZE)
 
 #define PLAT_QEMU_L1_GPT_BASE		(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
 					 PLAT_QEMU_L1_GPT_SIZE)
@@ -353,7 +356,8 @@
 
 #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_L0_GPT_SIZE +	\
+					 PLAT_QEMU_GPT_BITLOCK_SIZE)
 
 #ifndef __ASSEMBLER__
 /* L0 table greater than 4KB must be naturally aligned */
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
index c108920..bcbea21 100644
--- a/plat/qemu/qemu/include/qemu_pas_def.h
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -22,7 +22,7 @@
  *             | 1GB     |L0 GPT|ANY   |Flash            |
  *    00000000 |         |      |      |IO               |
  * ---------------------------------------------------------------------------
- *       224MB | 1KB     |L0 GPT|ANY   |Secure RAM (EL3) |
+ *       224MB | 1KB     |L1 GPT|ANY   |Secure RAM (EL3) |
  *    0e000000 |         |      |      |  (shared)       |
  * ---------------------------------------------------------------------------
  *             | 1MB-1KB |L1 GPT|ROOT  |Secure RAM (EL3) |
@@ -31,10 +31,10 @@
  *       225MB | 14MB    |L1 GPT|SECURE|Secure RAM       |
  *    0e100000 |         |      |      |  (EL2, EL1)     |
  * ---------------------------------------------------------------------------
- *             | 1MB+8KB |L1 GPT|ROOT  |L0 and L1 GPTs   |
- *    0eefe000 |         |      |      |                 |
+ *             | 2MB     |L1 GPT|ROOT  |L0 and L1 GPTs,  |
+ *    0edfc000 |  +16KB  |      |      | bitlocks        |
  * ---------------------------------------------------------------------------
- *       240MB | 800MB   |L0 GPT|ANY   |IO               |
+ *       240MB | 800MB   |L1 GPT|ANY   |IO               |
  *    0f000000 |         |      |      |                 |
  * ---------------------------------------------------------------------------
  *         1GB | 1MB     |L1 GPT|NS    |DRAM             |
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 436e425..066554a 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -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
 #
@@ -79,12 +79,12 @@
     certificates: $(ROT_KEY)
 
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
 
@@ -226,14 +226,14 @@
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
 qemu_fw.bios: bl1 fip
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
-	$(Q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
+	$(q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
 
 qemu_fw.rom: qemu_fw.bios
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
-	$(Q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
+	$(q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
 
 ifneq (${BL33},)
 all: qemu_fw.bios qemu_fw.rom
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 535f0eb..83e66f3 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -30,6 +30,7 @@
 #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
 #define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
 #define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
+#define SIP_SVC_GET_CPU_TOPOLOGY SIP_FUNCTION_ID(202)
 #define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
 #define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
 
@@ -46,10 +47,24 @@
 	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;
 
@@ -71,12 +86,46 @@
  * 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;
-	uint32_t nodeid = 0;
 	uintptr_t mpidr;
 
 	/*
@@ -118,14 +167,12 @@
 			panic();
 		}
 
-		if (fdt_getprop(dtb, node, "numa-node-id", NULL))  {
-			fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
-		}
-
-		dynamic_platform_info.cpu[cpu].nodeid = nodeid;
 		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, nodeid, mpidr);
+		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
+				dynamic_platform_info.cpu[cpu].nodeid, mpidr);
 
 		cpu++;
 
@@ -135,6 +182,8 @@
 
 	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)
@@ -143,7 +192,6 @@
 	const char *type;
 	int prev, node;
 	int len;
-	uint32_t nodeid = 0;
 	uint32_t memnode = 0;
 	uint32_t higher_value, lower_value;
 	uint64_t cur_base, cur_size;
@@ -172,11 +220,8 @@
 
 		type = fdt_getprop(dtb, node, "device_type", &len);
 		if (type && strncmp(type, "memory", len) == 0) {
-			if (fdt_getprop(dtb, node, "numa-node-id", NULL)) {
-				fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
-			}
-
-			dynamic_platform_info.memory[memnode].nodeid = nodeid;
+			dynamic_platform_info.memory[memnode].nodeid =
+				fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
 
 			/*
 			 * Get the 'reg' property of this node and
@@ -274,10 +319,10 @@
 
 	node = fdt_path_offset(dtb, "/");
 	if (node >= 0) {
-		platform_version_major = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-major", NULL));
-		platform_version_minor = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-minor", NULL));
+		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);
 	}
 }
 
@@ -354,6 +399,18 @@
 			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);
+		} 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);
 
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
index c4cd259..804ad42 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -142,10 +142,10 @@
 	qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3);
 
 	qti_ns_ctx->spsr_el1 =
-	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1);
+	    read_el1_ctx_common(get_el1_sysregs_ctx(ctx), spsr_el1);
 	qti_ns_ctx->elr_el1 =
-	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1);
-	qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1);
+	    read_el1_ctx_common(get_el1_sysregs_ctx(ctx), elr_el1);
+	qti_ns_ctx->sp_el1 = read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sp_el1);
 
 	qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0);
 	qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1);
diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h
index f1c2553..8676444 100644
--- a/plat/renesas/common/include/rcar_def.h
+++ b/plat/renesas/common/include/rcar_def.h
@@ -310,4 +310,31 @@
 #define LOSSY_FMT2			LOSSY_FMT_YUV422INTLV
 #define LOSSY_ENA_DIS2			LOSSY_DISABLE
 
+#define RCAR_CC63_BASE			0xE6600000U
+#define CC63_TRNG_ISR_REG_ADDR			0x104U
+#define CC63_TRNG_ISR_REG_EHR_VALID			BIT_32(0)
+#define CC63_TRNG_ISR_REG_AUTOCORR_ERR			BIT_32(1)
+#define CC63_TRNG_ICR_REG_ADDR			0x108U
+#define CC63_TRNG_CONFIG_REG_ADDR		0x10CU
+#define CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH		3
+#define CC63_TRNG_VALID_REG_ADDR		0x110U
+#define CC63_TRNG_VALID_REG_EHR_NOT_READY		0x0
+#define CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR	0x114U
+#define CC63_TRNG_SOURCE_ENABLE_REG_ADDR	0x12CU
+#define CC63_TRNG_SOURCE_ENABLE_REG_SET			0x1
+#define CC63_TRNG_SOURCE_ENABLE_REG_CLR			0x0
+#define CC63_TRNG_SAMPLE_CNT1_REG_ADDR		0x130U
+#define CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT		100
+#define CC63_TRNG_DEBUG_CONTROL_REG_ADDR	0x138U
+#define CC63_TRNG_DEBUG_CONTROL_REG_VNC_BYPASS		BIT_32(1)
+#define CC63_TRNG_DEBUG_CONTROL_REG_AUTOCORR_BYPASS	BIT_32(3)
+#define CC63_TRNG_DEBUG_CONTROL_REG_80090B		\
+	(CC63_TRNG_DEBUG_CONTROL_REG_VNC_BYPASS |	\
+	 CC63_TRNG_DEBUG_CONTROL_REG_AUTOCORR_BYPASS)
+#define CC63_TRNG_SW_RESET_REG_ADDR		0x140U
+#define CC63_TRNG_SW_RESET_REG_SET			0x1
+#define CC63_TRNG_VERSION_REG_ADDR		0x1C0U
+#define CC63_TRNG_CLK_ENABLE_REG_ADDR		0x1C4U
+#define CC63_TRNG_CLK_ENABLE_REG_SET			0x1
+
 #endif /* RCAR_DEF_H */
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 41031d6..c548240 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -756,6 +756,69 @@
 #endif
 }
 
+static void bl2_add_kaslr_seed(void)
+{
+	uint32_t cnt, isr, prr;
+	uint64_t seed;
+	int ret, node;
+
+	/* SCEG is only available on H3/M3-W/M3-N */
+	prr = mmio_read_32(RCAR_PRR);
+	switch (prr & PRR_PRODUCT_MASK) {
+	case PRR_PRODUCT_H3:
+	case PRR_PRODUCT_M3:
+	case PRR_PRODUCT_M3N:
+		break;
+	default:
+		return;
+	}
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SW_RESET_REG_ADDR,
+		      CC63_TRNG_SW_RESET_REG_SET);
+
+	do {
+		mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CLK_ENABLE_REG_ADDR,
+			      CC63_TRNG_CLK_ENABLE_REG_SET);
+		mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR,
+			      CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+		cnt = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR);
+	} while (cnt != CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CONFIG_REG_ADDR,
+		      CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_DEBUG_CONTROL_REG_ADDR,
+		      CC63_TRNG_DEBUG_CONTROL_REG_80090B);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+		      CC63_TRNG_SOURCE_ENABLE_REG_SET);
+
+	do {
+		isr = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_ISR_REG_ADDR);
+		if ((isr & CC63_TRNG_ISR_REG_AUTOCORR_ERR) != 0U) {
+			panic();
+		}
+	} while ((isr & CC63_TRNG_ISR_REG_EHR_VALID) == 0U);
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_ICR_REG_ADDR, UINT32_MAX);
+	seed = mmio_read_64(RCAR_CC63_BASE + CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+		      CC63_TRNG_SOURCE_ENABLE_REG_CLR);
+
+	node = ret = fdt_add_subnode(fdt, 0, "chosen");
+	if (ret < 0) {
+		goto err;
+	}
+
+	ret = fdt_setprop_u64(fdt, node, "kaslr-seed", seed);
+	if (ret < 0) {
+		goto err;
+	}
+
+	return;
+err:
+	NOTICE("BL2: Cannot add KASLR seed to FDT (ret=%i)\n", ret);
+	panic();
+}
+
 static void bl2_add_dram_entry(uint64_t start, uint64_t size)
 {
 	char nodename[32] = { 0 };
@@ -1215,6 +1278,9 @@
 	/* Print DRAM layout */
 	bl2_advertise_dram_size(product);
 
+	/* Add KASLR seed */
+	bl2_add_kaslr_seed();
+
 	if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
 	    boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
 		if (rcar_emmc_init() != EMMC_SUCCESS) {
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 8e3f52e..4813949 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -351,13 +351,13 @@
 LAYOUT_TOOLPATH ?= tools/renesas/rcar_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rcar_layout_tool
 rcar_layout_tool:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -365,16 +365,16 @@
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
 $(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
-	@echo "generating srec: $(SREC_PATH)/bl2.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
 
 $(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
-	@echo "generating srec: $(SREC_PATH)/bl31.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
 
 .PHONY: rcar_srecord
 rcar_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/renesas/rzg/platform.mk b/plat/renesas/rzg/platform.mk
index 354eada..5da6052 100644
--- a/plat/renesas/rzg/platform.mk
+++ b/plat/renesas/rzg/platform.mk
@@ -249,13 +249,13 @@
 LAYOUT_TOOLPATH ?= tools/renesas/rzg_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rzg_layout_create
 rzg_layout_create:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -263,16 +263,16 @@
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
 $(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
-	@echo "generating srec: $(SREC_PATH)/bl2.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
 
 $(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
-	@echo "generating srec: $(SREC_PATH)/bl31.srec"
-	$(Q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
 
 .PHONY: rzg_srecord
 rzg_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
index 9030951..25ee964 100644
--- a/plat/rockchip/common/aarch32/platform_common.c
+++ b/plat/rockchip/common/aarch32/platform_common.c
@@ -12,7 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index c4c0dec..dde66aa 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,7 +150,12 @@
 	 * Per-CPU Secure entry point - resume or power up
 	 * --------------------------------------------------------------------
 	 */
+
+#if USE_COHERENT_MEM
 	.section .tzfw_coherent_mem, "a"
+#else
+	.data
+#endif
 	.align  3
 cpuson_entry_point:
 	.rept	PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 81e8520..df51d89 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
@@ -42,9 +42,10 @@
 		mmap_add_region(ro_start, ro_start,			\
 				ro_limit - ro_start,			\
 				MT_MEMORY | MT_RO | MT_SECURE);		\
-		mmap_add_region(coh_start, coh_start,			\
-				coh_limit - coh_start,			\
-				MT_DEVICE | MT_RW | MT_SECURE);		\
+		if ((coh_limit - coh_start) != 0)			\
+			mmap_add_region(coh_start, coh_start,		\
+					coh_limit - coh_start,		\
+					MT_DEVICE | MT_RW | MT_SECURE);	\
 		mmap_add(plat_rk_mmap);					\
 		rockchip_plat_mmu_el##_el();				\
 		init_xlat_tables();					\
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 59db3d8..6214722 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -93,10 +93,19 @@
 {
 	plat_cci_init();
 	plat_cci_enable();
+#if USE_COHERENT_MEM
 	plat_configure_mmu_el3(BL_CODE_BASE,
 			       BL_COHERENT_RAM_END - BL_CODE_BASE,
 			       BL_CODE_BASE,
 			       BL_CODE_END,
 			       BL_COHERENT_RAM_BASE,
 			       BL_COHERENT_RAM_END);
+#else
+	plat_configure_mmu_el3(BL31_START,
+			       BL31_END - BL31_START,
+			       BL_CODE_BASE,
+			       BL_CODE_END,
+			       0,
+			       0);
+#endif
 }
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 990d106..44a0c46 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
-#include <lib/psci/psci.h>
-#include <lib/xlat_tables/xlat_tables.h>
 #include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat_params.h>
 
 #define __sramdata __attribute__((section(".sram.data")))
@@ -49,7 +49,7 @@
 #endif
 
 #ifndef BITS_SHIFT
-#define BITS_SHIFT(bits, shift)	(bits << (shift))
+#define BITS_SHIFT(bits, shift)	((bits) << (shift))
 #endif
 
 #ifndef BITS_WITH_WMASK
@@ -135,7 +135,6 @@
 extern void *pmu_cpuson_entrypoint;
 extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
 extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
-
 extern const mmap_region_t plat_rk_mmap[];
 
 uint32_t rockchip_get_uart_base(void);
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 2abcc18..e742591 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -6,6 +6,7 @@
 
 toolchains := rk3399-m0
 
+include ../../../../../make_helpers/common.mk
 include ../../../../../make_helpers/toolchain.mk
 
 # Cross Compile
@@ -18,13 +19,6 @@
 PLAT_M0		?= rk3399m0
 PLAT_M0_PMU	?= rk3399m0pmu
 
-ifeq (${V},0)
-	Q=@
-else
-	Q=
-endif
-export Q
-
 .SUFFIXES:
 
 INCLUDES		+= -Iinclude/ \
@@ -71,16 +65,16 @@
 -include $(patsubst %.o,%.d,$(OBJ))
 
 $(OBJ) : $(2)
-	@echo "  CC      $$<"
-	$$(Q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
+	$(s)echo "  CC      $$<"
+	$$(q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
 endef
 
 define MAKE_S
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 
 $(OBJ) : $(2)
-	@echo "  AS      $$<"
-	$$(Q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
+	$(s)echo "  AS      $$<"
+	$$(q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
 endef
 
 define MAKE_OBJS
@@ -105,16 +99,16 @@
 -include $(LINKERFILE).d
 
 $(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
 
 %.bin : %.elf
-	@echo "  BIN     $@"
-	$(Q)$(rk3399-m0-oc) -O binary $< $@
+	$(s)echo "  BIN     $@"
+	$(q)$(rk3399-m0-oc) -O binary $< $@
 
 $(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -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/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 2394dce..9d0e215 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -104,9 +104,8 @@
 ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW)
 ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S: $(RK3399M0FW)
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
 .PHONY: $(RK3399M0FW)
-$(RK3399M0FW): | ${BUILD_M0}
+$(RK3399M0FW): | $$(@D)/
 	$(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 BUILD=$(abspath ${BUILD_PLAT}/m0)
 
 # Do not enable SVE
diff --git a/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..8ddea0e
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.macro	func_rockchip_clst_warmboot
+	/* Nothing to do for rk3568 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+	/* Nothing to do for rk3568 */
+.endm
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.c b/plat/rockchip/rk3568/drivers/pmu/pmu.c
new file mode 100644
index 0000000..970caec
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * The power management unit (PMU) is designed for controlling power resources.
+ * The PMU is dedicated for managing the power of the whole chip.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bakery_lock.h>
+#include <cortex_a55.h>
+#include <dsu_def.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_private.h>
+#include <soc.h>
+
+/*
+ * Use this macro to instantiate lock before it is used in below
+ * rockchip_pd_lock_xxx() macros
+ */
+DECLARE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t grf_ddr_con3;
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+/*
+ * These are wrapper macros to the powe domain Bakery Lock API.
+ */
+#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
+#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
+#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	uint64_t ctrl;
+
+	__asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
+	ctrl |= 0x01;
+	__asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
+	isb();
+
+	while (1)
+		wfi();
+}
+
+static void pmu_pmic_sleep_mode_config(void)
+{
+	/* pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0),  WRITE_MASK_SET(BIT(7)));
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
+}
+
+static void pmu_wakeup_source_config(void)
+{
+	/* config wakeup source */
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
+
+	INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
+	     mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
+}
+
+static void pmu_pll_powerdown_config(void)
+{
+	uint32_t pll_id;
+
+	/* PLL power down by PMU */
+	pll_id = BIT(APLL_PD_ENA) |
+		BIT(CPLL_PD_ENA) |
+		BIT(GPLL_PD_ENA) |
+		BIT(MPLL_PD_ENA) |
+		BIT(NPLL_PD_ENA) |
+		BIT(HPLL_PD_ENA) |
+		BIT(PPLL_PD_ENA) |
+		BIT(VPLL_PD_ENA);
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
+	INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+}
+
+static void pmu_stable_count_config(void)
+{
+	mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
+}
+
+static void pmu_pd_powerdown_config(void)
+{
+	uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
+	uint32_t pmu_bus_idle_con1;
+
+	/* Pd power down by PMU */
+	pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
+	pwr_gate_con = ~pwr_dwn_st & 0x3ff;
+
+	if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
+	}
+
+	if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
+	}
+
+	if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
+	}
+
+	if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
+	}
+
+	pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
+		BIT(IDLE_REQ_MSCH) |
+		BIT(IDLE_REQ_PHP) |
+		BIT(IDLE_REQ_SECURE_FLASH) |
+		BIT(IDLE_REQ_PERIMID) |
+		BIT(IDLE_REQ_USB) |
+		BIT(IDLE_REQ_BUS);
+
+	/* Enable power down PD by PMU automatically */
+	pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
+		BIT(PD_NPU_DWN_ENA) |
+		BIT(PD_VPU_DWN_ENA) |
+		BIT(PD_RKVENC_DWN_ENA) |
+		BIT(PD_RKVDEC_DWN_ENA) |
+		BIT(PD_RGA_DWN_ENA) |
+		BIT(PD_VI_DWN_ENA) |
+		BIT(PD_VO_DWN_ENA) |
+		BIT(PD_PIPE_DWN_ENA)) << 16;
+
+	pmu_bus_idle_con1 = 0;
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
+
+	/* When perform idle operation,
+	 * corresponding clock can be opened or gated automatically
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
+
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
+
+	INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
+	     PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
+	INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
+	     PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
+	INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_ddr_suspend_config(void)
+{
+	uint32_t pmu_ddr_pwr_con;
+
+	pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
+		BIT(DDRIO_RET_ENTER_ENA) |
+		BIT(DDRIO_RET_EXIT_ENA) |
+		BIT(DDRPHY_AUTO_GATING_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
+	/* DPLL power down by PMU */
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
+
+	grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
+
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
+
+	pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
+
+	INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+	INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
+	     PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
+
+	if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
+		INFO("\t DDR_SREF_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
+		INFO("\t DDRIO_RET_ENTER_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
+		INFO("\t DDRIO_RET_EXIT_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
+		INFO("\t DDRPHY_AUTO_GATING_ENA\n");
+	}
+}
+
+static void pmu_dsu_suspend_config(void)
+{
+	uint32_t pmu_dsu_pwr_con;
+
+	pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
+	dsu_pwr_dwn();
+
+	INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
+	     PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
+	INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
+	     PMU_CLUSTER_IDLE_CON,  mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
+	INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_cpu_powerdown_config(void)
+{
+	uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
+
+	pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	cpus_state = pmu_cluster_pwr_st & 0x0f;
+
+	cpus_bypass = cpus_state << CPU0_BYPASS;
+
+	INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
+	     PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
+
+	INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
+	     PMU_PWR_CON,  mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pvtm_32k_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+	uint32_t pvtm_freq_khz, pvtm_div;
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
+	dsb();
+
+	while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
+		;
+	}
+
+	dsb();
+	while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
+		;
+	}
+
+	pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
+		PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
+	pvtm_div = (pvtm_freq_khz + 16) / 32;
+
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
+
+	pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_cru_suspendmode_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+
+	pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_suspend_cru_fsm(void)
+{
+	pmu_pmic_sleep_mode_config();
+
+	/* Global interrupt disable */
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
+
+	pmu_stable_count_config();
+	pmu_wakeup_source_config();
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
+	/* default cru config */
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
+
+	pmu_cru_suspendmode_config();
+	pmu_cpu_powerdown_config();
+	pmu_pll_powerdown_config();
+	pmu_pd_powerdown_config();
+	pmu_ddr_suspend_config();
+	pmu_dsu_suspend_config();
+	pvtm_32k_config();
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
+}
+
+static void pmu_reinit(void)
+{
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	psram_sleep_cfg->pm_flag = 0;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+	pmu_suspend_cru_fsm();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pmu_reinit();
+	plat_rockchip_gic_cpuif_enable();
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t apm_value, offset, idx;
+
+	apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
+
+	if (pd_cfg == core_pwr_wfi_int) {
+		apm_value |= BIT(core_pm_int_wakeup_en);
+	}
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(apm_value, 0xf, offset));
+	dsb();
+
+	return 0;
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	uint32_t offset, idx;
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      WMSK_BIT(core_pm_en + offset));
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
+	dsb();
+
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+
+	cpus_power_domain_on(cpu_id);
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_off(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	cpus_power_domain_off(cpu_id,
+			      core_pwr_wfi);
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	uint32_t offset, idx;
+
+	/* Disable core_pm */
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(0, 0xf, offset));
+
+	return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t tmp;
+
+	cpus_power_domain_off(1, 0);
+	cpus_power_domain_off(2, 0);
+	cpus_power_domain_off(3, 0);
+
+	mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
+	mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
+	sev();
+
+	do {
+		tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	} while ((tmp & 0xe) != 0xe);
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	uint32_t cpu;
+
+	rockchip_pd_lock_init();
+	nonboot_cpus_off();
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
+
+	psram_sleep_cfg->ddr_data = (uint64_t)0;
+	psram_sleep_cfg->sp = PSRAM_SP_TOP;
+	psram_sleep_cfg->ddr_flag = 0x00;
+	psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+	/*
+	 * When perform idle operation, corresponding clock can be
+	 * opened or gated automatically.
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	/* grf_con_pmic_sleep_sel
+	 * pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
+
+	/*
+	 * force jtag control
+	 * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
+	 * 1'b0: CPU debug port IO mux IS controlled by GRF
+	 */
+	mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
+
+	/*
+	 * remap
+	 * 2'b00: Boot from boot-rom.
+	 * 2'b01: Boot from pmu mem.
+	 * 2'b10: Boot from sys mem.
+	 */
+	mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
+}
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.h b/plat/rockchip/rk3568/drivers/pmu/pmu.h
new file mode 100644
index 0000000..5821514
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_VERSION			0x0000
+#define PMU_PWR_CON			0x0004
+#define PMU_MAIN_PWR_STATE		0x0008
+#define PMU_INT_MASK_CON		0x000C
+#define PMU_WAKEUP_INT_CON		0x0010
+#define PMU_WAKEUP_INT_ST		0x0014
+#define PMU_WAKEUP_EDGE_CON		0x0018
+#define PMU_WAKEUP_EDGE_ST		0x001C
+#define PMU_BUS_IDLE_CON0		0x0040
+#define PMU_BUS_IDLE_CON1		0x0044
+#define PMU_BUS_IDLE_SFTCON0		0x0050
+#define PMU_BUS_IDLE_SFTCON1		0x0054
+#define PMU_BUS_IDLE_ACK		0x0060
+#define PMU_BUS_IDLE_ST			0x0068
+#define PMU_NOC_AUTO_CON0		0x0070
+#define PMU_NOC_AUTO_CON1		0x0074
+#define PMU_DDR_PWR_CON			0x0080
+#define PMU_DDR_PWR_SFTCON		0x0084
+#define PMU_DDR_PWR_STATE		0x0088
+#define PMU_DDR_PWR_ST			0x008C
+#define PMU_PWR_GATE_CON		0x0090
+#define PMU_PWR_GATE_STATE		0x0094
+#define PMU_PWR_DWN_ST			0x0098
+#define PMU_PWR_GATE_SFTCON		0x00A0
+#define PMU_VOL_GATE_SFTCON		0x00A8
+#define PMU_CRU_PWR_CON			0x00B0
+#define PMU_CRU_PWR_SFTCON		0x00B4
+#define PMU_CRU_PWR_STATE		0x00B8
+#define PMU_PLLPD_CON			0x00C0
+#define PMU_PLLPD_SFTCON		0x00C4
+#define PMU_INFO_TX_CON			0x00D0
+#define PMU_DSU_STABLE_CNT		0x0100
+#define PMU_PMIC_STABLE_CNT		0x0104
+#define PMU_OSC_STABLE_CNT		0x0108
+#define PMU_WAKEUP_RSTCLR_CNT		0x010C
+#define PMU_PLL_LOCK_CNT		0x0110
+#define PMU_DSU_PWRUP_CNT		0x0118
+#define PMU_DSU_PWRDN_CNT		0x011C
+#define PMU_GPU_VOLUP_CNT		0x0120
+#define PMU_GPU_VOLDN_CNT		0x0124
+#define PMU_WAKEUP_TIMEOUT_CNT		0x0128
+#define PMU_PWM_SWITCH_CNT		0x012C
+#define PMU_DBG_RST_CNT			0x0130
+#define PMU_SYS_REG0			0x0180
+#define PMU_SYS_REG1			0x0184
+#define PMU_SYS_REG2			0x0188
+#define PMU_SYS_REG3			0x018C
+#define PMU_SYS_REG4			0x0190
+#define PMU_SYS_REG5			0x0194
+#define PMU_SYS_REG6			0x0198
+#define PMU_SYS_REG7			0x019C
+#define PMU_DSU_PWR_CON			0x0300
+#define PMU_DSU_PWR_SFTCON		0x0304
+#define PMU_DSU_AUTO_CON		0x0308
+#define PMU_DSU_PWR_STATE		0x030C
+#define PMU_CPU_AUTO_PWR_CON0		0x0310
+#define PMU_CPU_AUTO_PWR_CON1		0x0314
+#define PMU_CPU_PWR_SFTCON		0x0318
+#define PMU_CLUSTER_PWR_ST		0x031C
+#define PMU_CLUSTER_IDLE_CON		0x0320
+#define PMU_CLUSTER_IDLE_SFTCON		0x0324
+#define PMU_CLUSTER_IDLE_ACK		0x0328
+#define PMU_CLUSTER_IDLE_ST		0x032C
+#define PMU_DBG_PWR_CON			0x0330
+
+/* PMU_SGRF */
+#define PMU_SGRF_SOC_CON1		0x0004
+#define PMU_SGRF_FAST_BOOT_ADDR		0x0180
+
+/* sys grf */
+#define GRF_CPU_STATUS0			0x0420
+
+#define CRU_SOFTRST_CON00		0x0400
+
+#define CORES_PM_DISABLE		0x0
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+
+#define PMUSGRF_SOC_CON(i)		((i) * 0x4)
+/* Needed aligned 16 bytes for sp stack top */
+#define PSRAM_SP_TOP			((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define PMU_CPUAPM_CON(cpu)		(0x0310 + (cpu) * 0x4)
+
+#define PMIC_SLEEP_FUN			0x07000100
+#define PMIC_SLEEP_GPIO			0x07000000
+#define GPIO_SWPORT_DR_L		0x0000
+#define GPIO_SWPORT_DR_H		0x0004
+#define GPIO_SWPORT_DDR_L		0x0008
+#define GPIO_SWPORT_DDR_H		0x000C
+#define PMIC_SLEEP_HIGH_LEVEL		0x00040004
+#define PMIC_SLEEP_LOW_LEVEL		0x00040000
+#define PMIC_SLEEP_OUT			0x00040004
+#define CPUS_BYPASS			0x007e4f7e
+#define CLB_INT_DISABLE			0x00010001
+#define WRITE_MASK_SET(value)		((value << 16) | value)
+#define WRITE_MASK_CLR(value)		((value << 16))
+
+enum pmu_cores_pm_by_wfi {
+	core_pm_en = 0,
+	core_pm_int_wakeup_en,
+	core_pm_int_wakeup_glb_msk,
+	core_pm_sft_wakeup_en,
+};
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+	core_pwr_pd = 0,
+	core_pwr_wfi = 1,
+	core_pwr_wfi_int = 2
+};
+
+/* PMU_PWR_DWN_ST */
+enum pmu_pdid {
+	PD_GPU,
+	PD_NPU,
+	PD_VPU,
+	PD_RKVENC,
+	PD_RKVDEC,
+	PD_RGA,
+	PD_VI,
+	PD_VO,
+	PD_PIPE,
+	PD_CENTER,
+	PD_END
+};
+
+/* PMU_PWR_CON */
+enum pmu_pwr_con {
+	POWRMODE_EN,
+	DSU_BYPASS,
+	BUS_BYPASS = 4,
+	DDR_BYPASS,
+	PWRDN_BYPASS,
+	CRU_BYPASS,
+	CPU0_BYPASS,
+	CPU1_BYPASS,
+	CPU2_BYPASS,
+	CPU3_BYPASS,
+	PMU_SLEEP_LOW = 15,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu_cru_pwr_con {
+	ALIVE_32K_ENA,
+	OSC_DIS_ENA,
+	WAKEUP_RST_ENA,
+	INPUT_CLAMP_ENA,
+
+	ALIVE_OSC_ENA,
+	POWER_OFF_ENA,
+	PWM_SWITCH_ENA,
+	PWM_GPIO_IOE_ENA,
+
+	PWM_SWITCH_IOUT,
+	PD_BUS_CLK_SRC_GATE_ENA,
+	PD_PERI_CLK_SRC_GATE_ENA,
+	PD_PMU_CLK_SRC_GATE_ENA,
+
+	PMUMEM_CLK_SRC_GATE_ENA,
+	PWR_CON_END
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+	APLL_PD_ENA,
+	DPLL_PD_ENA,
+	CPLL_PD_ENA,
+	GPLL_PD_ENA,
+	MPLL_PD_ENA,
+	NPLL_PD_ENA,
+	HPLL_PD_ENA,
+	PPLL_PD_ENA,
+	VPLL_PD_ENA,
+	PLL_PD_END
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+	DSU_PWRDN_ENA = 2,
+	DSU_PWROFF_ENA,
+	DSU_RET_ENA = 6,
+	CLUSTER_CLK_SRC_GATE_ENA,
+	DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+	CPU_POWER_ON,
+	CPU_POWER_OFF,
+	CPU_EMULATION_OFF,
+	CPU_RETENTION,
+	CPU_DEBUG
+};
+
+enum dsu_power_state {
+	DSU_POWER_ON,
+	CLUSTER_TRANSFER_IDLE,
+	DSU_POWER_DOWN,
+	DSU_OFF,
+	DSU_WAKEUP,
+	DSU_POWER_UP,
+	CLUSTER_TRANSFER_RESUME,
+	DSU_FUNCTION_RETENTION
+};
+
+enum pmu_wakeup_int_con {
+	WAKEUP_CPU0_INT_EN,
+	WAKEUP_CPU1_INT_EN,
+	WAKEUP_CPU2_INT_EN,
+	WAKEUP_CPU3_INT_EN,
+	WAKEUP_GPIO0_INT_EN,
+	WAKEUP_UART0_EN,
+	WAKEUP_SDMMC0_EN,
+	WAKEUP_SDMMC1_EN,
+	WAKEUP_SDMMC2_EN,
+	WAKEUP_USB_EN,
+	WAKEUP_PCIE_EN,
+	WAKEUP_VAD_EN,
+	WAKEUP_TIMER_EN,
+	WAKEUP_PWM0_EN,
+	WAKEUP_TIMEROUT_EN,
+	WAKEUP_MCU_SFT_EN,
+};
+
+enum pmu_wakeup_int_st {
+	WAKEUP_CPU0_INT_ST,
+	WAKEUP_CPU1_INT_ST,
+	WAKEUP_CPU2_INT_ST,
+	WAKEUP_CPU3_INT_ST,
+	WAKEUP_GPIO0_INT_ST,
+	WAKEUP_UART0_ST,
+	WAKEUP_SDMMC0_ST,
+	WAKEUP_SDMMC1_ST,
+	WAKEUP_SDMMC2_ST,
+	WAKEUP_USB_ST,
+	WAKEUP_PCIE_ST,
+	WAKEUP_VAD_ST,
+	WAKEUP_TIMER_ST,
+	WAKEUP_PWM0_ST,
+	WAKEUP_TIMEOUT_ST,
+	WAKEUP_SYS_INT_ST,
+};
+
+enum pmu_bus_idle_con0 {
+	IDLE_REQ_MSCH,
+	IDLE_REQ_GPU,
+	IDLE_REQ_NPU,
+	IDLE_REQ_VI,
+	IDLE_REQ_VO,
+	IDLE_REQ_RGA,
+	IDLE_REQ_VPU,
+	IDLE_REQ_RKVENC,
+	IDLE_REQ_RKVDEC,
+	IDLE_REQ_GIC_AUDIO,
+	IDLE_REQ_PHP,
+	IDLE_REQ_PIPE,
+	IDLE_REQ_SECURE_FLASH,
+	IDLE_REQ_PERIMID,
+	IDLE_REQ_USB,
+	IDLE_REQ_BUS,
+};
+
+enum pmu_bus_idle_con1 {
+	IDLE_REQ_TOP1,
+	IDLE_REQ_TOP2,
+	IDLE_REQ_PMU,
+};
+
+enum pmu_pwr_gate_con {
+	PD_GPU_DWN_ENA,
+	PD_NPU_DWN_ENA,
+	PD_VPU_DWN_ENA,
+	PD_RKVENC_DWN_ENA,
+
+	PD_RKVDEC_DWN_ENA,
+	PD_RGA_DWN_ENA,
+	PD_VI_DWN_ENA,
+	PD_VO_DWN_ENA,
+
+	PD_PIPE_DWN_ENA,
+	PD_CENTER_DWN_ENA,
+};
+
+enum pmu_ddr_pwr_con {
+	DDR_SREF_ENA,
+	DDRIO_RET_ENTER_ENA,
+	DDRIO_RET_EXIT_ENA = 2,
+	DDRPHY_AUTO_GATING_ENA = 4,
+};
+
+enum pmu_vol_gate_soft_con {
+	VD_GPU_ENA,
+	VD_NPU_ENA,
+};
+
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.c b/plat/rockchip/rk3568/drivers/soc/soc.c
new file mode 100644
index 0000000..2af3887
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RKFPGA_DEV_RNG0_BASE, RKFPGA_DEV_RNG0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+
+	{ 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+static void secure_timer_init(void)
+{
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_DIS);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+static void sgrf_init(void)
+{
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(0), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(1), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(2), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(3), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(4), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(5), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(6), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(7), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(8), 0xffff0000);
+
+	mmio_write_32(DDRSGRF_BASE + FIREWALL_DDR_FW_DDR_CON_REG, 0xffff0000);
+}
+
+static void set_pll_slow_mode(uint32_t clk_pll)
+{
+	mmio_write_32(CRU_BASE + CRU_MODE_CON00, 0x03 << (16 + clk_pll * 2));
+}
+
+static void __dead2 soc_global_soft_reset(void)
+{
+	set_pll_slow_mode(CLK_CPLL);
+	set_pll_slow_mode(CLK_GPLL);
+	set_pll_slow_mode(CLK_NPLL);
+	set_pll_slow_mode(CLK_VPLL);
+	set_pll_slow_mode(CLK_USBPLL);
+	set_pll_slow_mode(CLK_APLL);
+	mmio_write_32(PMUCRU_BASE + PMUCRU_MODE_CON00, 0x000f0000);
+
+	dsb();
+	mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to excute valid codes.
+	 */
+	while (1) {
+		;
+	}
+}
+
+static void rockchip_system_reset_init(void)
+{
+	mmio_write_32(GRF_BASE + 0x0508, 0x00100010);
+	mmio_write_32(CRU_BASE + 0x00dc, 0x01030103);
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	soc_global_soft_reset();
+}
+
+void plat_rockchip_soc_init(void)
+{
+	secure_timer_init();
+	sgrf_init();
+	rockchip_system_reset_init();
+	NOTICE("BL31: Rockchip release version: v%d.%d\n",
+		MAJOR_VERSION, MINOR_VERSION);
+}
+
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.h b/plat/rockchip/rk3568/drivers/soc/soc.h
new file mode 100644
index 0000000..41a2586
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+#define RKFPGA_DEV_RNG0_BASE		0xf8000000
+#define RKFPGA_DEV_RNG0_SIZE		0x07fff000
+
+#define CRU_MODE_CON00			0x00c0
+#define PMUCRU_MODE_CON00		0x0080
+
+#define CRU_GLB_SRST_FST		0x00d4
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define PMU_GRF_GPIO0A_IOMUX_L		0x00
+#define PMU_GRF_SOC_CON(i)		(0x0100 + i * 4)
+
+#define CRU_SOFTRST_CON			0x300
+#define CRU_SOFTRSTS_CON(n)		(CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT		26
+#define GRF_DDR_CON3			0x000c
+#define SGRF_FIREWALL_SLV_CON(i)	(0x240 + i * 4)
+
+#define FIREWALL_DDR_FW_DDR_CON_REG	0x80
+
+ /* low 32 bits */
+#define TIMER_LOAD_COUNT0		0x00
+#define TIMER_LOAD_COUNT1		0x04
+#define TIMER_CURRENT_VALUE0		0x08
+#define TIMER_CURRENT_VALUE1		0x0c
+#define TIMER_CONTROL_REG		0x10
+#define TIMER_INTSTATUS			0x18
+#define TIMER_DIS			0x0
+#define TIMER_EN			0x1
+#define STIMER0_CHN_BASE(n)		(STIME_BASE + 0x20 * (n))
+
+#define PMU_GRF_GPIO0B_IOMUX_L		0x0008
+#define PMUCRU_PMUCLKSEL_CON00		0x0100
+#define PMUPVTM_BASE			0xfdd80000
+#define PVTM_CON0			0x0004
+#define PVTM_CON1			0x0008
+#define PVTM_STATUS0			0x0080
+#define PVTM_STATUS1			0x0084
+#define PMUCRU_PMUGATE_CON01		0x0184
+#define PVTM_CALC_CNT			0x200
+#define PMU_GRF_DLL_CON0		0x0180
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_REVSERVED,
+	CLK_NPLL,
+	CLK_VPLL,
+	CLK_USBPLL,
+};
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3568/include/plat.ld.S b/plat/rockchip/rk3568/include/plat.ld.S
new file mode 100644
index 0000000..ddd584d
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+MEMORY {
+    PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+	. = PMUSRAM_BASE;
+
+	/*
+	 * pmu_cpuson_entrypoint request address
+	 * align 64K when resume, so put it in the
+	 * start of pmusram
+	 */
+	.pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		KEEP(*(.pmusram.entry))
+
+		__bl31_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		__bl31_pmusram_text_end = .;
+		__bl31_pmusram_data_start = .;
+		*(.pmusram.data)
+		__bl31_pmusram_data_end = .;
+	} >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3568/include/plat_sip_calls.h b/plat/rockchip/rk3568/include/plat_sip_calls.h
new file mode 100644
index 0000000..6acb876
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3568/include/platform_def.h b/plat/rockchip/rk3568/include/platform_def.h
new file mode 100644
index 0000000..19363a4
--- /dev/null
+++ b/plat/rockchip/rk3568/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3568_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT		1
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT +	\
+					 PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT	8
+
+/*
+ * 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		1
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		2
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 512KB */
+#define TZRAM_BASE		(0x0)
+#define TZRAM_SIZE		(0x100000)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted RAM
+ */
+#define BL31_BASE		(TZRAM_BASE + 0x40000)
+#define BL31_LIMIT		(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+#define ADDR_SPACE_SIZE			(1ull << 32)
+#define MAX_XLAT_TABLES			18
+#define MAX_MMAP_REGIONS		27
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT	6
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE	PLAT_GICD_BASE
+#define PLAT_RK_GICC_BASE	PLAT_GICC_BASE
+#define PLAT_RK_GICR_BASE	PLAT_GICR_BASE
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+		       INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_UART_BASE		FPGA_UART_BASE
+#define PLAT_RK_UART_CLOCK		FPGA_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE	FPGA_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU	0x0
+
+#define ATAGS_PHYS_SIZE		0x2000
+#define ATAGS_PHYS_BASE		(0x200000 - ATAGS_PHYS_SIZE)/* [2M-8K, 2M] */
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3568/plat_sip_calls.c b/plat/rockchip/rk3568/plat_sip_calls.c
new file mode 100644
index 0000000..b0f3a03
--- /dev/null
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_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)
+{
+	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3568/platform.mk b/plat/rockchip/rk3568/platform.mk
new file mode 100644
index 0000000..1155ff8
--- /dev/null
+++ b/plat/rockchip/rk3568/platform.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RK_PLAT			:=	plat/rockchip
+RK_PLAT_SOC		:=	${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON		:=	${RK_PLAT}/common
+
+DISABLE_BIN_GENERATION	:=	1
+GICV3_SUPPORT_GIC600	:=	1
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iinclude/bl31					\
+				-Iinclude/common				\
+				-Iinclude/drivers				\
+				-Iinclude/drivers/arm				\
+				-Iinclude/drivers/auth				\
+				-Iinclude/drivers/io				\
+				-Iinclude/drivers/ti/uart			\
+				-Iinclude/lib					\
+				-Iinclude/lib/cpus/${ARCH}			\
+				-Iinclude/lib/el3_runtime			\
+				-Iinclude/lib/pmf				\
+				-Iinclude/lib/psci				\
+				-Iinclude/plat/common				\
+				-Iinclude/services				\
+				-Iinclude/plat/common/				\
+				-Idrivers/arm/gic/v3/				\
+				-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/pmusram/			\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_COMMON}/drivers/parameter/		\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES		:=	${GICV3_SOURCES}				\
+				plat/common/plat_gicv3.c			\
+				${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}				\
+				common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
+				lib/bl_aux_params/bl_aux_params.c		\
+				plat/common/plat_psci_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
+BL31_SOURCES		+=	${RK_GIC_SOURCES}				\
+				drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a55.S			\
+				drivers/ti/uart/aarch64/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				$(LIBFDT_SRCS)					\
+				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
+				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
+				${RK_PLAT_COMMON}/params_setup.c		\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
+				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c
+
+ENABLE_PLAT_COMPAT	:=	0
+MULTI_CONSOLE_API	:=	1
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+#Enable errata for cortex_a55
+ERRATA_A55_1530923	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS	:=	0
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
new file mode 100644
index 0000000..0d1e5d1
--- /dev/null
+++ b/plat/rockchip/rk3568/rk3568_def.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define MAJOR_VERSION		(1)
+#define MINOR_VERSION		(0)
+
+#define SIZE_K(n)		((n) * 1024)
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define GIC600_BASE		0xfd400000
+#define GIC600_SIZE		SIZE_K(64)
+
+#define PMUSGRF_BASE		0xfdc00000
+#define SYSSGRF_BASE		0xfdc10000
+#define PMUGRF_BASE		0xfdc20000
+#define CPUGRF_BASE		0xfdc30000
+#define DDRGRF_BASE		0xfdc40000
+#define PIPEGRF_BASE		0xfdc50000
+#define GRF_BASE		0xfdc60000
+#define PIPEPHY_GRF0		0xfdc70000
+#define PIPEPHY_GRF1		0xfdc80000
+#define PIPEPHY_GRF2		0xfdc90000
+#define USBPHY_U3_GRF		0xfdca0000
+#define USB2PHY_U2_GRF		0xfdca8000
+#define EDPPHY_GRF		0xfdcb0000
+#define SYSSRAM_BASE		0xfdcc0000
+#define PCIE30PHY_GRF		0xfdcb8000
+#define USBGRF_BASE		0xfdcf0000
+
+#define PMUCRU_BASE		0xfdd00000
+#define SCRU_BASE		0xfdd10000
+#define SGRF_BASE		0xfdd18000
+#define STIME_BASE		0xfdd1c000
+#define CRU_BASE		0xfdd20000
+#define PMUSCRU_BASE		0xfdd30000
+#define I2C0_BASE		0xfdd40000
+
+#define UART0_BASE		0xfdd50000
+#define GPIO0_BASE		0xfdd60000
+#define PMUPVTM_BASE		0xfdd80000
+#define PMU_BASE		0xfdd90000
+#define PMUSRAM_BASE		0xfdcd0000
+#define PMUSRAM_SIZE		SIZE_K(128)
+#define PMUSRAM_RSIZE		SIZE_K(8)
+
+#define DDRSGRF_BASE		0xfe200000
+#define UART1_BASE		0xfe650000
+#define UART2_BASE		0xfe660000
+#define GPIO1_BASE		0xfe740000
+#define GPIO2_BASE		0xfe750000
+#define GPIO3_BASE		0xfe760000
+#define GPIO4_BASE		0xfe770000
+
+#define REMAP_BASE		0xffff0000
+#define REMAP_SIZE		SIZE_K(64)
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define FPGA_UART_BASE		UART2_BASE
+#define FPGA_BAUDRATE		1500000
+#define FPGA_UART_CLOCK		24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS	24000000
+#define SYS_COUNTER_FREQ_IN_MHZ		24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE		GIC600_BASE
+#define PLAT_GICC_BASE		0
+#define PLAT_GICR_BASE		(GIC600_BASE + 0x60000)
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER	29
+
+#define RK_IRQ_SEC_SGI_0	8
+#define RK_IRQ_SEC_SGI_1	9
+#define RK_IRQ_SEC_SGI_2	10
+#define RK_IRQ_SEC_SGI_3	11
+#define RK_IRQ_SEC_SGI_4	12
+#define RK_IRQ_SEC_SGI_5	13
+#define RK_IRQ_SEC_SGI_6	14
+#define RK_IRQ_SEC_SGI_7	15
+
+#define SHARE_MEM_BASE		0x100000/* [1MB, 1MB+60K]*/
+#define SHARE_MEM_PAGE_NUM	15
+#define SHARE_MEM_SIZE		SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rpi/rpi4/rpi4_pci_svc.c b/plat/rpi/common/rpi_pci_svc.c
similarity index 76%
rename from plat/rpi/rpi4/rpi4_pci_svc.c
rename to plat/rpi/common/rpi_pci_svc.c
index e4ef5c1..c22f6d8 100644
--- a/plat/rpi/rpi4/rpi4_pci_svc.c
+++ b/plat/rpi/common/rpi_pci_svc.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * The RPi4 has a single nonstandard PCI config region. It is broken into two
+ * The RPi has a single nonstandard PCI config region. It is broken into two
  * pieces, the root port config registers and a window to a single device's
  * config space which can move between devices. There isn't (yet) an
  * authoritative public document on this since the available BCM2711 reference
@@ -29,62 +30,63 @@
 
 #include <lib/mmio.h>
 
-static spinlock_t pci_lock;
-
-#define PCIE_REG_BASE		U(RPI_IO_BASE + 0x01500000)
 #define PCIE_MISC_PCIE_STATUS	0x4068
 #define PCIE_EXT_CFG_INDEX	0x9000
-/* A small window pointing at the ECAM of the device selected by CFG_INDEX */
 #define PCIE_EXT_CFG_DATA	0x8000
+#define	PCIE_EXT_CFG_BDF_SHIFT	12
+
 #define INVALID_PCI_ADDR	0xFFFFFFFF
 
-#define	PCIE_EXT_BUS_SHIFT	20
-#define	PCIE_EXT_DEV_SHIFT	15
-#define	PCIE_EXT_FUN_SHIFT	12
+static spinlock_t pci_lock;
 
+static uint64_t pcie_rc_bases[] = { RPI_PCIE_RC_BASES };
 
 static uint64_t pci_segment_lib_get_base(uint32_t address, uint32_t offset)
 {
-	uint64_t	base;
-	uint32_t	bus, dev, fun;
-	uint32_t	status;
+	uint64_t base;
+	uint32_t seg, bus, dev, fun;
 
-	base = PCIE_REG_BASE;
+	seg = PCI_ADDR_SEG(address);
 
-	offset &= PCI_OFFSET_MASK;  /* Pick off the 4k register offset */
+	if (seg >= ARRAY_SIZE(pcie_rc_bases)) {
+		return INVALID_PCI_ADDR;
+	}
 
 	/* The root port is at the base of the PCIe register space */
-	if (address != 0U) {
-		/*
-		 * The current device must be at CFG_DATA, a 4K window mapped,
-		 * via CFG_INDEX, to the device we are accessing. At the same
-		 * time we must avoid accesses to certain areas of the cfg
-		 * space via CFG_DATA. Detect those accesses and report that
-		 * the address is invalid.
-		 */
-		base += PCIE_EXT_CFG_DATA;
-		bus = PCI_ADDR_BUS(address);
-		dev = PCI_ADDR_DEV(address);
-		fun = PCI_ADDR_FUN(address);
-		address = (bus << PCIE_EXT_BUS_SHIFT) |
-			  (dev << PCIE_EXT_DEV_SHIFT) |
-			  (fun << PCIE_EXT_FUN_SHIFT);
+	base = pcie_rc_bases[seg];
 
-		/* Allow only dev = 0 on root port and bus 1 */
-		if ((bus < 2U) && (dev > 0U)) {
-			return INVALID_PCI_ADDR;
-		}
+	bus = PCI_ADDR_BUS(address);
+	dev = PCI_ADDR_DEV(address);
+	fun = PCI_ADDR_FUN(address);
 
-		/* Assure link up before reading bus 1 */
-		status = mmio_read_32(PCIE_REG_BASE + PCIE_MISC_PCIE_STATUS);
-		if ((status & 0x30) != 0x30) {
-			return INVALID_PCI_ADDR;
-		}
-
-		/* Adjust which device the CFG_DATA window is pointing at */
-		mmio_write_32(PCIE_REG_BASE + PCIE_EXT_CFG_INDEX, address);
+	/* There can only be the root port on bus 0 */
+	if ((bus == 0U) && ((dev > 0U) || (fun > 0U))) {
+		return INVALID_PCI_ADDR;
 	}
-	return base + offset;
+
+	/* There can only be one device on bus 1 */
+	if ((bus == 1U) && (dev > 0U)) {
+		return INVALID_PCI_ADDR;
+	}
+
+	if (bus > 0) {
+#if RPI_PCIE_ECAM_SERROR_QUIRK
+		uint32_t status = mmio_read_32(base + PCIE_MISC_PCIE_STATUS);
+
+		/* Assure link up before accessing downstream of root port */
+		if ((status & 0x30) == 0U) {
+			return INVALID_PCI_ADDR;
+		}
+#endif
+		/*
+		 * Device function is mapped at CFG_DATA, a 4 KB window
+		 * movable by writing its B/D/F location to CFG_INDEX.
+		 */
+		mmio_write_32(base + PCIE_EXT_CFG_INDEX, address << PCIE_EXT_CFG_BDF_SHIFT);
+		base += PCIE_EXT_CFG_DATA;
+	}
+
+	return base + (offset & PCI_OFFSET_MASK);
 }
 
 /**
@@ -130,7 +132,7 @@
 			*val = mmio_read_32(base);
 			break;
 		default: /* should be unreachable */
-			*val = 0;
+			*val = 0U;
 			ret = SMC_PCI_CALL_INVAL_PARAM;
 		}
 	}
@@ -204,9 +206,12 @@
 uint32_t pci_get_bus_for_seg(uint32_t seg, uint32_t *bus_range, uint32_t *nseg)
 {
 	uint32_t ret = SMC_PCI_CALL_SUCCESS;
-	*nseg = 0U; /* only a single segment */
-	if (seg == 0U) {
-		*bus_range = 0xFF00; /* start 0, end 255 */
+	uint32_t rc_count = ARRAY_SIZE(pcie_rc_bases);
+
+	*nseg = (seg < rc_count - 1U) ? seg + 1U : 0U;
+
+	if (seg < rc_count) {
+		*bus_range = 0U + (0xFF << 8); /* start 0, end 255 */
 	} else {
 		*bus_range = 0U;
 		ret = SMC_PCI_CALL_NOT_IMPL;
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 8034fa4..eaaff7d 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -73,13 +73,13 @@
 # This target concatenates BL1 and the FIP so that the base addresses match the
 # ones defined in the memory map
 armstub: bl1 fip
-	@echo "  CAT     $@"
-	${Q}cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
-	${Q}truncate --size=131072 ${RPI3_BL1_PAD_BIN}
-	${Q}cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  CAT     $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
+	$(q)truncate --size=131072 ${RPI3_BL1_PAD_BIN}
+	$(q)cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 # Build config flags
 # ------------------
@@ -213,11 +213,11 @@
     certificates: $(ROT_KEY)
 
     $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
     $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 endif
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index 8162492..53ce0f8 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -69,4 +69,11 @@
 #define	RPI4_LOCAL_CONTROL_BASE_ADDRESS		ULL(0xff800000)
 #define	RPI4_LOCAL_CONTROL_PRESCALER		ULL(0xff800008)
 
+/*
+ * PCI Express
+ */
+#define RPI_PCIE_RC_BASES		(RPI_IO_BASE + ULL(0x01500000))
+
+#define RPI_PCIE_ECAM_SERROR_QUIRK	1
+
 #endif /* RPI_HW_H */
diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk
index f17911f..cbfa6f2 100644
--- a/plat/rpi/rpi4/platform.mk
+++ b/plat/rpi/rpi4/platform.mk
@@ -113,5 +113,5 @@
 endif
 
 ifeq ($(SMC_PCI_SUPPORT), 1)
-BL31_SOURCES            +=      plat/rpi/rpi4/rpi4_pci_svc.c
+BL31_SOURCES            +=      plat/rpi/common/rpi_pci_svc.c
 endif
diff --git a/plat/rpi/rpi5/include/rpi_hw.h b/plat/rpi/rpi5/include/rpi_hw.h
index 384542e..a737676 100644
--- a/plat/rpi/rpi5/include/rpi_hw.h
+++ b/plat/rpi/rpi5/include/rpi_hw.h
@@ -48,4 +48,11 @@
 #define	RPI4_LOCAL_CONTROL_BASE_ADDRESS		(RPI_IO_BASE + ULL(0x7c280000))
 #define	RPI4_LOCAL_CONTROL_PRESCALER		(RPI_IO_BASE + ULL(0x7c280008))
 
+/*
+ * PCI Express
+ */
+#define RPI_PCIE_RC_BASES		RPI_IO_BASE + ULL(0x00100000), \
+					RPI_IO_BASE + ULL(0x00110000), \
+					RPI_IO_BASE + ULL(0x00120000)
+
 #endif /* RPI_HW_H */
diff --git a/plat/rpi/rpi5/platform.mk b/plat/rpi/rpi5/platform.mk
index 81b7ded..70c5add 100644
--- a/plat/rpi/rpi5/platform.mk
+++ b/plat/rpi/rpi5/platform.mk
@@ -86,6 +86,9 @@
 # Use normal memory mapping for ROM, FIP, SRAM and DRAM
 RPI3_USE_UEFI_MAP		:= 0
 
+# SMCCC PCI support (should be enabled for ACPI builds)
+SMC_PCI_SUPPORT			:= 0
+
 # Process platform flags
 # ----------------------
 
@@ -96,6 +99,7 @@
 endif
 $(eval $(call add_define,RPI3_RUNTIME_UART))
 $(eval $(call add_define,RPI3_USE_UEFI_MAP))
+$(eval $(call add_define,SMC_PCI_SUPPORT))
 
 ifeq (${ARCH},aarch32)
   $(error Error: AArch32 not supported on rpi5)
@@ -105,3 +109,7 @@
 PLAT_BL_COMMON_SOURCES	+=	drivers/rpi3/rng/rpi3_rng.c		\
 				plat/rpi/common/rpi3_stack_protector.c
 endif
+
+ifeq ($(SMC_PCI_SUPPORT), 1)
+BL31_SOURCES		+=	plat/rpi/common/rpi_pci_svc.c
+endif
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index a6d9bef..a5ab4f7 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -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
 #
@@ -72,12 +72,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 
 endif	# TRUSTED_BOARD_BOOT
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d466aa1..ebb9b8c 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.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
 #
@@ -106,12 +106,12 @@
 
 certificates: $(ROT_KEY)
 $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
 $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	$(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
 
 endif
@@ -136,5 +136,5 @@
 .PHONY: bl2_gzip
 bl2_gzip: $(BUILD_PLAT)/bl2.bin.gz
 %.gz: %
-	@echo "  GZIP    $@"
-	$(Q)gzip -n -f -9 $< --stdout > $@
+	$(s)echo "  GZIP    $@"
+	$(q)gzip -n -f -9 $< --stdout > $@
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index f8a0c18..c17ac7e 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -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
  */
@@ -47,6 +47,7 @@
 uintptr_t storage_dev_handle;
 
 static const io_dev_connector_t *fip_dev_con;
+static uint32_t nand_block_sz __maybe_unused;
 
 #ifndef DECRYPTION_SUPPORT_none
 static const io_dev_connector_t *enc_dev_con;
@@ -310,11 +311,55 @@
 }
 #endif /* STM32MP_SPI_NOR */
 
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+/*
+ * This function returns 0 if it can find an alternate
+ * image to be loaded or a negative errno otherwise.
+ */
+static int try_nand_backup_partitions(unsigned int image_id)
+{
+	static unsigned int backup_id;
+	static unsigned int backup_block_nb;
+
+	/* Check if NAND storage used */
+	if (nand_block_sz == 0U) {
+		return -ENODEV;
+	}
+
+	if (backup_id != image_id) {
+		backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz;
+		backup_id = image_id;
+	}
+
+	if (backup_block_nb-- == 0U) {
+		return -ENOSPC;
+	}
+
+#if PSA_FWU_SUPPORT
+	if (((image_block_spec.offset < STM32MP_NAND_FIP_B_OFFSET) &&
+	     ((image_block_spec.offset + nand_block_sz) >= STM32MP_NAND_FIP_B_OFFSET)) ||
+	    (image_block_spec.offset + nand_block_sz >= STM32MP_NAND_FIP_B_MAX_OFFSET)) {
+		return 0;
+	}
+#endif
+
+	image_block_spec.offset += nand_block_sz;
+
+	return 0;
+}
+
+static const struct plat_try_images_ops try_img_ops = {
+	.next_instance = try_nand_backup_partitions,
+};
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
 #if STM32MP_RAW_NAND
 static void boot_fmc2_nand(boot_api_context_t *boot_context)
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_fmc2_init();
 	assert(io_result == 0);
 
@@ -326,6 +371,8 @@
 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_RAW_NAND */
 
@@ -334,6 +381,8 @@
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_qspi_init();
 	assert(io_result == 0);
 
@@ -345,6 +394,8 @@
 				(uintptr_t)&spi_nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = spi_nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_SPI_NAND */
 
@@ -530,7 +581,14 @@
 #if STM32MP_SPI_NAND
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
 #endif
+/*
+ * With FWU Multi Bank feature enabled, the selection of
+ * the image to boot will be done by fwu_init calling the
+ * platform hook, plat_fwu_set_images_source.
+ */
+#if !PSA_FWU_SUPPORT
 		image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
+#endif
 		break;
 #endif
 
@@ -596,7 +654,7 @@
 	return rc;
 }
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 /*
  * In each boot in non-trial mode, we set the BKP register to
  * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
@@ -710,6 +768,19 @@
 			}
 			break;
 #endif
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+			if (guidcmp(img_guid, &STM32MP_NAND_FIP_A_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_A_OFFSET;
+			} else if (guidcmp(img_guid, &STM32MP_NAND_FIP_B_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_B_OFFSET;
+			} else {
+				ERROR("Invalid uuid mentioned in metadata\n");
+				panic();
+			}
+			break;
+#endif
 		default:
 			panic();
 			break;
@@ -717,9 +788,9 @@
 	}
 }
 
-static int plat_set_image_source(unsigned int image_id,
-				 uintptr_t *handle,
-				 uintptr_t *image_spec)
+static int set_metadata_image_source(unsigned int image_id,
+				     uintptr_t *handle,
+				     uintptr_t *image_spec)
 {
 	struct plat_io_policy *policy;
 	io_block_spec_t *spec __maybe_unused;
@@ -762,6 +833,19 @@
 		spec->length = sizeof(struct fwu_metadata);
 		break;
 #endif
+
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+		if (image_id == FWU_METADATA_IMAGE_ID) {
+			spec->offset = STM32MP_NAND_METADATA1_OFFSET;
+		} else {
+			spec->offset = STM32MP_NAND_METADATA2_OFFSET;
+		}
+
+		spec->length = sizeof(struct fwu_metadata);
+		break;
+#endif
 	default:
 		panic();
 		break;
@@ -780,6 +864,6 @@
 	assert((image_id == FWU_METADATA_IMAGE_ID) ||
 	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
 
-	return plat_set_image_source(image_id, handle, image_spec);
+	return set_metadata_image_source(image_id, handle, image_spec);
 }
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index 7ef7665..7395a36 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -28,6 +28,24 @@
 TF_CFLAGS			+=	-Wsign-compare
 TF_CFLAGS			+=	-Wformat-signedness
 
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES		:=	2
+
+# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
+PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + $(STM32_EXTRA_PARTS))))
+
+ifeq (${PSA_FWU_SUPPORT},1)
+# Number of banks of updatable firmware
+NR_OF_FW_BANKS			:=	2
+NR_OF_IMAGES_IN_FW_BANK		:=	1
+
+FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
+ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
+$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
+$(PLAT_PARTITION_MAX_ENTRIES)")
+endif
+endif
+
 # Boot devices
 STM32MP_EMMC			?=	0
 STM32MP_SDMMC			?=	0
@@ -120,6 +138,9 @@
 include lib/fconf/fconf.mk
 include lib/libfdt/libfdt.mk
 include lib/zlib/zlib.mk
+ifeq (${PSA_FWU_SUPPORT},1)
+include drivers/fwu/fwu.mk
+endif
 
 PLAT_BL_COMMON_SOURCES		+=	common/uuid.c					\
 					plat/st/common/stm32mp_common.c
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index 212a67d..fba7783 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -15,7 +15,7 @@
 bl2: check_boot_device
 
 check_boot_device:
-	@if [ ${STM32MP_EMMC} != 1 ] && \
+	$(q)if [ ${STM32MP_EMMC} != 1 ] && \
 	    [ ${STM32MP_SDMMC} != 1 ] && \
 	    [ ${STM32MP_RAW_NAND} != 1 ] && \
 	    [ ${STM32MP_SPI_NAND} != 1 ] && \
@@ -29,55 +29,55 @@
 stm32image: ${STM32IMAGE}
 
 ${STM32IMAGE}: ${STM32IMAGE_SRC}
-	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+	$(q)${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
 
 clean_stm32image:
-	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
 
 check_dtc_version:
-	@if [ ${DTC_VERSION} -lt 10407 ]; then \
+	$(q)if [ ${DTC_VERSION} -lt 10407 ]; then \
 		echo "dtc version too old (${DTC_V}), you need at least version 1.4.7"; \
 		false; \
 	fi
 
 # Create DTB file for BL2
-${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL2_DTSI}"' >> $@
+${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | $$(@D)/
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL2_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
 
 ${BUILD_PLAT}/$(PLAT)-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb $(STM32_BINARY_MAPPING) bl2
-	@echo "  AS      $${PLAT}.S"
-	${Q}$($(ARCH)-as) -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) ${ASFLAGS} ${TF_CFLAGS} \
+	$(s)echo "  AS      $${PLAT}.S"
+	$(q)$($(ARCH)-as) -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) ${ASFLAGS} ${TF_CFLAGS} \
 		-DDTB_BIN_PATH=\"$<\" \
 		-c $(word 2,$^) -o $@
 
 $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},$(STM32_LD_FILE),bl2))
 
 tf-a-%.elf: $(PLAT)-%.o ${STM32_TF_LINKERFILE}
-	@echo "  LDS     $<"
+	$(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 -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} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
 endif
 
 tf-a-%.bin: tf-a-%.elf
-	${Q}$($(ARCH)-oc) -O binary $< $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(q)$($(ARCH)-oc) -O binary $< $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 tf-a-%.stm32: tf-a-%.bin ${STM32_DEPS}
-	@echo
-	@echo "Generate $@"
+	$(s)echo
+	$(s)echo "Generate $@"
 	$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep '^RAM' | awk '{print $$2}'))
 	$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
-	${Q}${STM32IMAGE} -s $< -d $@ \
+	$(q)${STM32IMAGE} -s $< -d $@ \
 		-l $(LOADADDR) -e ${ENTRY} \
 		-v ${STM32_TF_VERSION} \
 		-m ${STM32_HEADER_VERSION_MAJOR} \
 		-n ${STM32_HEADER_VERSION_MINOR} \
 		-b ${STM32_HEADER_BL2_BINARY_TYPE}
-	@echo
+	$(s)echo
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 41b86ae..9af221c 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -131,7 +131,8 @@
 void stm32_display_board_info(uint32_t board_id);
 
 #if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void);
+uintptr_t stm32_get_bkpr_fwu_info_addr(void);
+void stm32_fwu_set_boot_idx(void);
 uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
 void stm32_set_max_fwu_trial_boot_cnt(void);
 void stm32_clear_fwu_trial_boot_cnt(void);
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 6f36011..d2f8784 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -55,6 +55,12 @@
 #define BOOT_INST_MASK			GENMASK_32(11, 8)
 #define BOOT_INST_SHIFT			8
 
+/* Layout for fwu update information. */
+#define FWU_INFO_IDX_MSK		GENMASK(3, 0)
+#define FWU_INFO_IDX_OFF		U(0)
+#define FWU_INFO_CNT_MSK		GENMASK(7, 4)
+#define FWU_INFO_CNT_OFF		U(4)
+
 static console_t console;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -378,3 +384,53 @@
 	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
 	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
 }
+
+#if PSA_FWU_SUPPORT
+void stm32_fwu_set_boot_idx(void)
+{
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(stm32_get_bkpr_fwu_info_addr(),
+			   FWU_INFO_IDX_MSK,
+			   (plat_fwu_get_boot_idx() << FWU_INFO_IDX_OFF) &
+			   FWU_INFO_IDX_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+	uint32_t try_cnt;
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & FWU_INFO_CNT_MSK) >> FWU_INFO_CNT_OFF;
+
+	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+	if (try_cnt != 0U) {
+		mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+				   (try_cnt - 1U) << FWU_INFO_CNT_OFF);
+	}
+	clk_disable(TAMP_BKP_REG_CLK);
+
+	return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+			   (FWU_MAX_TRIAL_REBOOT << FWU_INFO_CNT_OFF) & FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+void stm32_clear_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 5514c09..6ed09d9 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,12 +27,12 @@
 };
 #endif
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 
 /* By default, STM32 platforms load images from the FIP */
 struct plat_io_policy policies[MAX_NUMBER_IDS] = {
@@ -58,7 +58,7 @@
 		.check = open_storage
 	},
 #endif
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 	[FWU_METADATA_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
 		.image_spec = (uintptr_t)&metadata_block_spec,
@@ -71,7 +71,7 @@
 		.img_type_guid = NULL_GUID,
 		.check = open_storage
 	},
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 };
 
 #define DEFAULT_UUID_NUMBER	U(7)
diff --git a/plat/st/common/stm32mp_gic.c b/plat/st/common/stm32mp_gic.c
index d02b635..a4cc4a5 100644
--- a/plat/st/common/stm32mp_gic.c
+++ b/plat/st/common/stm32mp_gic.c
@@ -1,11 +1,12 @@
 /*
- * 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
  */
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
@@ -45,25 +46,29 @@
 	int node;
 	void *fdt;
 	const fdt32_t *cuint;
-	struct dt_node_info dt_gic;
+	uintptr_t addr;
+	int err;
 
 	if (fdt_get_address(&fdt) == 0) {
 		panic();
 	}
 
-	node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+	node = fdt_node_offset_by_compatible(fdt, -1, "arm,cortex-a7-gic");
 	if (node < 0) {
 		panic();
 	}
 
-	platform_gic_data.gicd_base = dt_gic.base;
-
-	cuint = fdt_getprop(fdt, node, "reg", NULL);
-	if (cuint == NULL) {
+	err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, NULL);
+	if (err < 0) {
 		panic();
 	}
+	platform_gic_data.gicd_base = addr;
 
-	platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+	err = fdt_get_reg_props_by_index(fdt, node, 1, &addr, NULL);
+	if (err < 0) {
+		panic();
+	}
+	platform_gic_data.gicc_base = addr;
 
 	cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
 	if (cuint == NULL) {
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index bd3903d..9da311e 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -331,7 +331,7 @@
 		print_pmic_info_and_debug();
 	}
 
-	stm32mp1_syscfg_init();
+	stm32mp_syscfg_init();
 
 	if (stm32_iwdg_init() < 0) {
 		panic();
@@ -365,7 +365,7 @@
 	}
 #endif
 
-	stm32mp1_syscfg_enable_io_compensation_finish();
+	stm32mp_syscfg_enable_io_compensation_finish();
 
 	fconf_populate("TB_FW", STM32MP_DTB_BASE);
 
@@ -440,8 +440,7 @@
 				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
 				if (paged_mem_params != NULL) {
 					paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
-						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
-						 STM32MP_DDR_SHMEM_SIZE);
+						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE);
 					paged_mem_params->image_info.image_max_size =
 						STM32MP_DDR_S_SIZE;
 				}
@@ -462,7 +461,8 @@
 		break;
 
 	case BL32_IMAGE_ID:
-		if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
+		if ((bl_mem_params->image_info.image_base != 0UL) &&
+		    (optee_header_is_valid(bl_mem_params->image_info.image_base))) {
 			image_info_t *paged_image_info = NULL;
 
 			/* BL32 is OP-TEE header */
@@ -508,7 +508,7 @@
 		assert(bl32_mem_params != NULL);
 		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
 #if PSA_FWU_SUPPORT
-		stm32mp1_fwu_set_boot_idx();
+		stm32_fwu_set_boot_idx();
 #endif /* PSA_FWU_SUPPORT */
 		break;
 
diff --git a/plat/st/stm32mp1/cert_create_tbbr.mk b/plat/st/stm32mp1/cert_create_tbbr.mk
index e747e39..fb9e5ec 100644
--- a/plat/st/stm32mp1/cert_create_tbbr.mk
+++ b/plat/st/stm32mp1/cert_create_tbbr.mk
@@ -11,7 +11,7 @@
 PLAT_INCLUDE	+= -I${PLAT_DIR}include
 
 src/stm32mp1_tbb_cert.o: ${PLAT_DIR}stm32mp1_tbb_cert.c
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 PLAT_OBJECTS	= src/stm32mp1_tbb_cert.o
 
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index f6e5a8f..55227fb 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -14,19 +14,19 @@
 void stm32mp1_arch_security_setup(void);
 void stm32mp1_security_setup(void);
 
-void stm32mp1_syscfg_init(void);
-void stm32mp1_syscfg_enable_io_compensation_start(void);
-void stm32mp1_syscfg_enable_io_compensation_finish(void);
-void stm32mp1_syscfg_disable_io_compensation(void);
-uint32_t stm32mp1_syscfg_get_chip_version(void);
-uint32_t stm32mp1_syscfg_get_chip_dev_id(void);
+void stm32mp_syscfg_init(void);
+void stm32mp_syscfg_enable_io_compensation_start(void);
+void stm32mp_syscfg_enable_io_compensation_finish(void);
+void stm32mp_syscfg_disable_io_compensation(void);
+uint32_t stm32mp_syscfg_get_chip_version(void);
+uint32_t stm32mp_syscfg_get_chip_dev_id(void);
 #if STM32MP13
-void stm32mp1_syscfg_boot_mode_enable(void);
-void stm32mp1_syscfg_boot_mode_disable(void);
+void stm32mp_syscfg_boot_mode_enable(void);
+void stm32mp_syscfg_boot_mode_disable(void);
 #endif
 #if STM32MP15
-static inline void stm32mp1_syscfg_boot_mode_enable(void){}
-static inline void stm32mp1_syscfg_boot_mode_disable(void){}
+static inline void stm32mp_syscfg_boot_mode_enable(void){}
+static inline void stm32mp_syscfg_boot_mode_disable(void){}
 #endif
 
 void stm32mp1_deconfigure_uart_pins(void);
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index ddc5289..138f16c 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,9 +1,13 @@
 #
-# 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
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS	:=	4
+
 include plat/st/common/common.mk
 
 ARM_CORTEX_A7		:=	yes
@@ -60,11 +64,6 @@
 # STM32 image header version v1.0
 STM32_HEADER_VERSION_MAJOR:=	1
 STM32_HEADER_VERSION_MINOR:=	0
-
-# Add OP-TEE reserved shared memory area in mapping
-STM32MP15_OPTEE_RSV_SHM	:=	0
-$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
-
 STM32MP_CRYPTO_ROM_LIB :=	1
 
 # Decryption support
@@ -85,25 +84,6 @@
 WORKAROUND_CVE_2017_5715:=	0
 WORKAROUND_CVE_2022_23960:=	0
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
-
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
-
-ifeq (${PSA_FWU_SUPPORT},1)
-# Number of banks of updatable firmware
-NR_OF_FW_BANKS			:=	2
-NR_OF_IMAGES_IN_FW_BANK		:=	1
-
-FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
-ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
-$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
-$(PLAT_PARTITION_MAX_ENTRIES)")
-endif
-endif
-
 ifeq ($(STM32MP13),1)
 STM32_HASH_VER		:=	4
 STM32_RNG_VER		:=	4
@@ -233,10 +213,6 @@
 BL2_SOURCES		+=	plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
 
-ifeq (${PSA_FWU_SUPPORT},1)
-include drivers/fwu/fwu.mk
-endif
-
 BL2_SOURCES		+=	drivers/st/crypto/stm32_hash.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
@@ -279,11 +255,11 @@
 
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
-${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL32_DTSI}"' >> $@
+${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | $$(@D)/
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL32_DTSI}"' >> $@
 
-${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
+${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts | $$(@D)/
 endif
 
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 0d401f9..824563f 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -10,6 +10,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/st/stm32mp1_rcc.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp1-resets.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
@@ -231,21 +232,7 @@
 #endif
 #define GPIO_BANK_OFFSET		U(0x1000)
 
-/* Bank IDs used in GPIO driver API */
-#define GPIO_BANK_A			U(0)
-#define GPIO_BANK_B			U(1)
-#define GPIO_BANK_C			U(2)
-#define GPIO_BANK_D			U(3)
-#define GPIO_BANK_E			U(4)
-#define GPIO_BANK_F			U(5)
-#define GPIO_BANK_G			U(6)
-#define GPIO_BANK_H			U(7)
-#define GPIO_BANK_I			U(8)
 #if STM32MP15
-#define GPIO_BANK_J			U(9)
-#define GPIO_BANK_K			U(10)
-#define GPIO_BANK_Z			U(25)
-
 #define STM32MP_GPIOZ_PIN_MAX_COUNT	8
 #endif
 
@@ -634,6 +621,11 @@
 #define PLAT_NB_FIXED_REGUS		U(2)
 
 /*******************************************************************************
+ * STM32MP1 CLOCKS
+ ******************************************************************************/
+#define PLL1_NOMINAL_FREQ_IN_KHZ	U(650000) /* 650MHz */
+
+/*******************************************************************************
  * Device Tree defines
  ******************************************************************************/
 #if STM32MP13
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index e37e2e6..165f152 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,7 @@
 #ifndef STM32MP1_FIP_DEF_H
 #define STM32MP1_FIP_DEF_H
 
-#if STM32MP15_OPTEE_RSV_SHM
-#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
-#else
 #define STM32MP_DDR_S_SIZE		U(0x02000000)	/* 32 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0)		/* empty */
-#endif
 
 #if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
 #if STM32MP15
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index ff2218f..97e1ac6 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -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,6 +13,7 @@
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/clk.h>
+#include <drivers/st/stm32mp_reset.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
@@ -149,13 +150,7 @@
 
 static void __dead2 stm32_system_reset(void)
 {
-	mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR,
-			RCC_MP_GRSTCSETR_MPSYSRST);
-
-	/* Loop in case system reset is not immediately caught */
-	for ( ; ; ) {
-		;
-	}
+	stm32mp_system_reset();
 }
 
 static int stm32_validate_power_state(unsigned int power_state,
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index f098eb3..32de391 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -29,10 +29,6 @@
  * (so it should be in Zone 2).
  */
 #define TAMP_BOOT_FWU_INFO_REG_ID	U(10)
-#define TAMP_BOOT_FWU_INFO_IDX_MSK	GENMASK(3, 0)
-#define TAMP_BOOT_FWU_INFO_IDX_OFF	U(0)
-#define TAMP_BOOT_FWU_INFO_CNT_MSK	GENMASK(7, 4)
-#define TAMP_BOOT_FWU_INFO_CNT_OFF	U(4)
 
 #if defined(IMAGE_BL2)
 #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -115,14 +111,14 @@
 uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ_BASE;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
@@ -131,14 +127,14 @@
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return 0;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return bank * GPIO_BANK_OFFSET;
@@ -161,14 +157,14 @@
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA + (bank - GPIO_BANK_A);
@@ -284,7 +280,7 @@
 uint32_t stm32mp_get_chip_version(void)
 {
 #if STM32MP13
-	return stm32mp1_syscfg_get_chip_version();
+	return stm32mp_syscfg_get_chip_version();
 #endif
 #if STM32MP15
 	uint32_t version = 0U;
@@ -301,7 +297,7 @@
 uint32_t stm32mp_get_chip_dev_id(void)
 {
 #if STM32MP13
-	return stm32mp1_syscfg_get_chip_dev_id();
+	return stm32mp_syscfg_get_chip_dev_id();
 #endif
 #if STM32MP15
 	uint32_t dev_id;
@@ -674,53 +670,8 @@
 }
 
 #if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void)
+uintptr_t stm32_get_bkpr_fwu_info_addr(void)
 {
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
-			   TAMP_BOOT_FWU_INFO_IDX_MSK,
-			   (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
-			   TAMP_BOOT_FWU_INFO_IDX_MSK);
-	clk_disable(RTCAPB);
-}
-
-uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
-{
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-	uint32_t try_cnt;
-
-	clk_enable(RTCAPB);
-	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
-		TAMP_BOOT_FWU_INFO_CNT_OFF;
-
-	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
-
-	if (try_cnt != 0U) {
-		mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-				   (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
-	}
-	clk_disable(RTCAPB);
-
-	return try_cnt;
-}
-
-void stm32_set_max_fwu_trial_boot_cnt(void)
-{
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-			   (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
-			   TAMP_BOOT_FWU_INFO_CNT_MSK);
-	clk_disable(RTCAPB);
-}
-
-void stm32_clear_fwu_trial_boot_cnt(void)
-{
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-
-	clk_enable(RTCAPB);
-	mmio_clrbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK);
-	clk_disable(RTCAPB);
+	return tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
 }
 #endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c
index 75dd709..199bdc9 100644
--- a/plat/st/stm32mp1/stm32mp1_syscfg.c
+++ b/plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -261,7 +261,7 @@
 #endif
 }
 
-static void stm32mp1_syscfg_set_hslv(void)
+static void stm32mp_syscfg_set_hslv(void)
 {
 	uint32_t otp_value;
 	uint32_t vdd_voltage;
@@ -310,7 +310,7 @@
 	}
 }
 
-void stm32mp1_syscfg_init(void)
+void stm32mp_syscfg_init(void)
 {
 #if STM32MP15
 	uint32_t bootr;
@@ -328,12 +328,12 @@
 			   bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
 #endif
 
-	stm32mp1_syscfg_set_hslv();
+	stm32mp_syscfg_set_hslv();
 
-	stm32mp1_syscfg_enable_io_compensation_start();
+	stm32mp_syscfg_enable_io_compensation_start();
 }
 
-void stm32mp1_syscfg_enable_io_compensation_start(void)
+void stm32mp_syscfg_enable_io_compensation_start(void)
 {
 	/*
 	 * Activate automatic I/O compensation.
@@ -353,7 +353,7 @@
 #endif
 }
 
-void stm32mp1_syscfg_enable_io_compensation_finish(void)
+void stm32mp_syscfg_enable_io_compensation_finish(void)
 {
 	enable_io_comp_cell_finish(SYSCFG_CMPCR);
 #if STM32MP13
@@ -362,7 +362,7 @@
 #endif
 }
 
-void stm32mp1_syscfg_disable_io_compensation(void)
+void stm32mp_syscfg_disable_io_compensation(void)
 {
 	clk_enable(SYSCFG);
 
@@ -385,7 +385,7 @@
  * @brief  Get silicon revision from SYSCFG registers.
  * @retval chip version (REV_ID).
  */
-uint32_t stm32mp1_syscfg_get_chip_version(void)
+uint32_t stm32mp_syscfg_get_chip_version(void)
 {
 	return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
 		SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
@@ -395,18 +395,18 @@
  * @brief  Get device ID from SYSCFG registers.
  * @retval device ID (DEV_ID).
  */
-uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
+uint32_t stm32mp_syscfg_get_chip_dev_id(void)
 {
 	return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
 }
 
 #if STM32MP13
-void stm32mp1_syscfg_boot_mode_enable(void)
+void stm32mp_syscfg_boot_mode_enable(void)
 {
 	mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
 }
 
-void stm32mp1_syscfg_boot_mode_disable(void)
+void stm32mp_syscfg_boot_mode_disable(void)
 {
 	mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
 }
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index bf2952d..d9a4d79 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and fsbl-m (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS		:=	6
+
 include plat/st/common/common.mk
 
 CRASH_REPORTING			:=	1
@@ -19,13 +23,6 @@
 STM32_HEADER_VERSION_MAJOR	:=	2
 STM32_HEADER_VERSION_MINOR	:=	2
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
-
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) and fsbl-m (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 6)))
-
 # Set load address for serial boot devices
 DWL_BUFFER_BASE 	?=	0x87000000
 
@@ -54,7 +51,11 @@
 PLAT_BL_COMMON_SOURCES		+=	drivers/st/uart/${ARCH}/stm32_console.S
 PLAT_BL_COMMON_SOURCES		+=	plat/st/stm32mp2/${ARCH}/stm32mp2_helper.S
 
-PLAT_BL_COMMON_SOURCES		+=	drivers/st/bsec/bsec3.c
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/bsec/bsec3.c					\
+					drivers/st/reset/stm32mp2_reset.c
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/clk/clk-stm32-core.c				\
+					drivers/st/clk/clk-stm32mp2.c
 
 BL2_SOURCES			+=	plat/st/stm32mp2/plat_bl2_mem_params_desc.c
 BL2_SOURCES			+=	plat/st/stm32mp2/bl2_plat_setup.c
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 56c62e1..d65fcea 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -14,6 +14,7 @@
 #include <drivers/st/stm32mp25_rcc.h>
 #include <dt-bindings/clock/stm32mp25-clks.h>
 #include <dt-bindings/clock/stm32mp25-clksrc.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp25-resets.h>
 
 #ifndef __ASSEMBLER__
@@ -292,6 +293,11 @@
 #define SYSCFG_BASE				U(0x44230000)
 
 /*******************************************************************************
+ * STM32MP CA35SSC
+ ******************************************************************************/
+#define A35SSC_BASE				U(0x48800000)
+
+/*******************************************************************************
  * REGULATORS
  ******************************************************************************/
 /* 3 PWR + 1 VREFBUF + 14 PMIC regulators + 1 FIXED */
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 3fcb62f..ffee805 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,9 +53,6 @@
 				      uint32_t flag);
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 				      uint32_t flag);
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag);
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag);
 uint32_t pm_get_shutdown_scope(void);
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index c1872d0..055fa3d 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -95,8 +95,6 @@
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AI engine NPI ISR clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
-	/* Register SGI to TF-A */
-	IOCTL_SET_SGI = 25,
 };
 
 /**
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 36ea8ed..0a6e810 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -287,112 +287,6 @@
 }
 
 /**
- * pm_pll_set_param() - Set PLL parameter.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Value to set for PLL parameter.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
-				    uint32_t value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
-			 clk_id, param, value);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Buffer to store PLL parameter value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
-				    uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
-			 clk_id, param);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
-			 clk_id, mode);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: Buffer to store PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
-/**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
  *                        be powered down forcefully.
  * @target: Device ID of the PU node to be forced powered down.
@@ -448,110 +342,6 @@
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data.
- * @qid: The type of data to query.
- * @arg1: Argument 1 to requested query data call.
- * @arg2: Argument 2 to requested query data call.
- * @arg3: Argument 3 to requested query data call.
- * @data: Returned output data.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: 0 if success else non-zero error code of type
- *         enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
-				 uint32_t arg3, uint32_t *data, uint32_t flag)
-{
-	uint32_t ret;
-	uint32_t version[PAYLOAD_ARG_CNT] = {0};
-	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t fw_api_version;
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
-			 arg1, arg2, arg3);
-
-	ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
-		if ((fw_api_version == 2U) &&
-		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
-		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-			if (ret == PM_RET_SUCCESS) {
-				ret = data[0];
-				data[0] = data[1];
-				data[1] = data[2];
-				data[2] = data[3];
-			}
-		} else {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-		}
-	}
-	return ret;
-}
-/**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs.
- * @device_id: Device ID.
- * @ioctl_id: ID of the requested IOCTL.
- * @arg1: Argument 1 to requested IOCTL call.
- * @arg2: Argument 2 to requested IOCTL call.
- * @arg3: Argument 3 to requested IOCTL call.
- * @value: Returned output value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * Return: Returns status, either 0 on success or non-zero error code
- *         of type enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag)
-{
-	enum pm_ret_status ret;
-
-	switch (ioctl_id) {
-	case IOCTL_SET_PLL_FRAC_MODE:
-		ret =  pm_pll_set_mode(arg1, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_MODE:
-		ret =  pm_pll_get_mode(arg1, value, flag);
-		break;
-	case IOCTL_SET_PLL_FRAC_DATA:
-		ret =  pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_DATA:
-		ret =  pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
-		break;
-	case IOCTL_SET_SGI:
-		/* Get the sgi number */
-		ret = pm_register_sgi(arg1, arg2);
-		if (ret != 0) {
-			return PM_RET_ERROR_ARGS;
-		}
-		ret = PM_RET_SUCCESS;
-		break;
-	default:
-		return PM_RET_ERROR_NOTSUPPORTED;
-	}
-
-	return ret;
-}
-
-/**
  * pm_set_wakeup_source() - PM call to specify the wakeup source while
  *                          suspended.
  * @target: Device id of the targeted PU or subsystem
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 7d8f244..7ac0ac1 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -149,6 +149,9 @@
 				}
 			}
 			notify_os();
+		} else if (payload[2] == EVENT_CPU_PWRDWN) {
+			request_cpu_pwrdwn();
+			(void)psci_cpu_off();
 		}
 		break;
 	case PM_RET_ERROR_INVALID_CRC:
@@ -240,6 +243,14 @@
 	}
 
 	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,
+				   0x0U, 0x1U, SECURE_FLAG);
+	if (ret != 0) {
+		WARN("BL31: registering idle callback for restart/force power down failed\n");
+	}
+
 	return ret;
 }
 
@@ -265,30 +276,6 @@
 
 	switch (api_id) {
 
-	case (uint32_t)PM_IOCTL:
-	{
-		uint32_t value = 0U;
-
-		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
-				   pm_arg[3], pm_arg[4],
-				   &value, security_flag);
-		if (ret == PM_RET_ERROR_NOTSUPPORTED)
-			return (uintptr_t)0;
-
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	case (uint32_t)PM_QUERY_DATA:
-	{
-		uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
-
-		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
-				    pm_arg[3], data, security_flag);
-
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
-			 (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
-	}
-
 	case (uint32_t)PM_FEATURE_CHECK:
 	{
 		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 08c0205..594784f 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -118,19 +118,6 @@
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
-
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index b38f394..5af2b1d 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -59,6 +59,20 @@
 					DISABLE_ALL_EXCEPTIONS);
 }
 
+/* Define read and write function for clusterbusqos register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(cluster_bus_qos, S3_0_C15_C4_4)
+
+static void versal_net_setup_qos(void)
+{
+	int ret;
+
+	ret = read_cluster_bus_qos();
+	INFO("BL31: default cluster bus qos: 0x%x\n", ret);
+	write_cluster_bus_qos(0);
+	ret = read_cluster_bus_qos();
+	INFO("BL31: cluster bus qos written: 0x%x\n", ret);
+}
+
 /*
  * Perform any BL31 specific platform actions. Here is an opportunity to copy
  * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
@@ -103,6 +117,8 @@
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
+	versal_net_setup_qos();
+
 	/* Initialize the platform config for future decision making */
 	versal_net_config_setup();
 
@@ -137,18 +153,6 @@
 
 		INFO("BL31: PLM to TF-A handover success\n");
 
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	} else {
 		INFO("BL31: setting up default configs\n");
 
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index dba1734..b0bd8a1 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,7 @@
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <services/arm_arch_svc.h>
 
@@ -28,9 +28,9 @@
  * configure_mmu_elx() will give the available subset of that,
  */
 const mmap_region_t plat_zynqmp_mmap[] = {
-	{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
-	{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
-	{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{0}
 };
 
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 0a34f72..50d4240 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <libfdt.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -220,5 +221,5 @@
 	custom_mmap_add();
 
 	setup_page_tables(bl_regions, plat_get_mmap());
-	enable_mmu_el3(0);
+	enable_mmu(0);
 }
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index afa102d..1b41b7c 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/bl_common.h>
 #include <drivers/cadence/cdns_uart.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 void zynqmp_config_setup(void);
 
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index e266615..c340009 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -2,7 +2,7 @@
 # Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
 # Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
 # Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -16,6 +16,7 @@
 IPI_CRC_CHECK := 0
 override RESET_TO_BL31 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
+ENABLE_LTO := 1
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
@@ -34,10 +35,6 @@
 
 WORKAROUND_CVE_2017_5715	:=	0
 
-ARM_XLAT_TABLES_LIB_V1		:=	1
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
 ifdef ZYNQMP_ATF_MEM_BASE
     $(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
 
@@ -95,10 +92,9 @@
 include lib/libfdt/libfdt.mk
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
+include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
-				lib/xlat_tables/aarch64/xlat_tables.c		\
-				drivers/arm/dcc/dcc_console.c			\
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV2_SOURCES}				\
@@ -111,7 +107,8 @@
 				plat/xilinx/zynqmp/zynqmp_ipi.c			\
 				plat/common/aarch64/crash_console_helpers.S	\
 				plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S	\
-				plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+				plat/xilinx/zynqmp/aarch64/zynqmp_common.c	\
+				${XLAT_TABLES_LIB_SRCS}
 
 ZYNQMP_CONSOLE	?=	cadence
 ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc))
diff --git a/poetry.lock b/poetry.lock
index 08b2b37..b465f48 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
@@ -13,163 +13,179 @@
 
 [[package]]
 name = "anytree"
-version = "2.8.0"
-description = "Powerful and Lightweight Python Tree Data Structure.."
+version = "2.12.1"
+description = "Powerful and Lightweight Python Tree Data Structure with various plugins"
 optional = false
-python-versions = "*"
+python-versions = ">=3.7.2,<4"
 files = [
-    {file = "anytree-2.8.0-py2.py3-none-any.whl", hash = "sha256:14c55ac77492b11532395049a03b773d14c7e30b22aa012e337b1e983de31521"},
-    {file = "anytree-2.8.0.tar.gz", hash = "sha256:3f0f93f355a91bc3e6245319bf4c1d50e3416cc7a35cc1133c1ff38306bbccab"},
+    {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"},
+    {file = "anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830"},
 ]
 
 [package.dependencies]
-six = ">=1.9.0"
-
-[package.extras]
-dev = ["check-manifest"]
-test = ["coverage"]
+six = "*"
 
 [[package]]
 name = "babel"
-version = "2.12.1"
+version = "2.15.0"
 description = "Internationalization utilities"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
-    {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+    {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"},
+    {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"},
 ]
 
 [package.dependencies]
 pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
 
+[package.extras]
+dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
+
 [[package]]
 name = "build"
-version = "0.10.0"
+version = "1.2.1"
 description = "A simple, correct Python build frontend"
 optional = false
-python-versions = ">= 3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"},
-    {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"},
+    {file = "build-1.2.1-py3-none-any.whl", hash = "sha256:75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4"},
+    {file = "build-1.2.1.tar.gz", hash = "sha256:526263f4870c26f26c433545579475377b2b7588b6f1eac76a001e873ae3e19d"},
 ]
 
 [package.dependencies]
 colorama = {version = "*", markers = "os_name == \"nt\""}
-packaging = ">=19.0"
+importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""}
+packaging = ">=19.1"
 pyproject_hooks = "*"
 tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
 
 [package.extras]
-docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"]
-test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"]
-typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"]
+docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
+test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
+typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
+uv = ["uv (>=0.1.18)"]
 virtualenv = ["virtualenv (>=20.0.35)"]
 
 [[package]]
 name = "certifi"
-version = "2023.7.22"
+version = "2024.7.4"
 description = "Python package for providing Mozilla's CA Bundle."
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
-    {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
+    {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
+    {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
 ]
 
 [[package]]
 name = "charset-normalizer"
-version = "3.1.0"
+version = "3.3.2"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 optional = false
 python-versions = ">=3.7.0"
 files = [
-    {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
-    {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+    {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+    {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
 ]
 
 [[package]]
 name = "click"
-version = "8.1.3"
+version = "8.1.7"
 description = "Composable command line interface toolkit"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
-    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
 ]
 
 [package.dependencies]
@@ -187,6 +203,20 @@
 ]
 
 [[package]]
+name = "commonmark"
+version = "0.9.1"
+description = "Python parser for the CommonMark Markdown spec"
+optional = false
+python-versions = "*"
+files = [
+    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
+    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
+]
+
+[package.extras]
+test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
+
+[[package]]
 name = "docutils"
 version = "0.18.1"
 description = "Docutils -- Python Documentation Utilities"
@@ -199,13 +229,13 @@
 
 [[package]]
 name = "idna"
-version = "3.4"
+version = "3.7"
 description = "Internationalized Domain Names in Applications (IDNA)"
 optional = false
 python-versions = ">=3.5"
 files = [
-    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
-    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+    {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
+    {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
 ]
 
 [[package]]
@@ -221,32 +251,32 @@
 
 [[package]]
 name = "importlib-metadata"
-version = "6.6.0"
+version = "8.2.0"
 description = "Read metadata from Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"},
-    {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"},
+    {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"},
+    {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"},
 ]
 
 [package.dependencies]
 zipp = ">=0.5"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 perf = ["ipython"]
-testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
+test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"]
 
 [[package]]
 name = "jinja2"
-version = "3.1.2"
+version = "3.1.4"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
-    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+    {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
+    {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
 ]
 
 [package.dependencies]
@@ -281,61 +311,71 @@
 
 [[package]]
 name = "markupsafe"
-version = "2.1.2"
+version = "2.1.5"
 description = "Safely add untrusted strings to HTML/XML markup."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
-    {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+    {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
 ]
 
 [[package]]
@@ -396,35 +436,35 @@
 
 [[package]]
 name = "packaging"
-version = "23.1"
+version = "24.1"
 description = "Core utilities for Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
-    {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
 ]
 
 [[package]]
 name = "pip"
-version = "23.1.2"
+version = "24.2"
 description = "The PyPA recommended tool for installing Python packages."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "pip-23.1.2-py3-none-any.whl", hash = "sha256:3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18"},
-    {file = "pip-23.1.2.tar.gz", hash = "sha256:0e7c86f486935893c708287b30bd050a36ac827ec7fe5e43fe7cb198dd835fba"},
+    {file = "pip-24.2-py3-none-any.whl", hash = "sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2"},
+    {file = "pip-24.2.tar.gz", hash = "sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8"},
 ]
 
 [[package]]
 name = "pip-tools"
-version = "6.13.0"
+version = "6.14.0"
 description = "pip-tools keeps your pinned dependencies fresh."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pip-tools-6.13.0.tar.gz", hash = "sha256:61d46bd2eb8016ed4a924e196e6e5b0a268cd3babd79e593048720db23522bb1"},
-    {file = "pip_tools-6.13.0-py3-none-any.whl", hash = "sha256:50943f151d87e752abddec8158622c34ad7f292e193836e90e30d87da60b19d9"},
+    {file = "pip-tools-6.14.0.tar.gz", hash = "sha256:06366be0e08d86b416407333e998b4d305d5bd925151b08942ed149380ba3e47"},
+    {file = "pip_tools-6.14.0-py3-none-any.whl", hash = "sha256:c5ad042cd27c0b343b10db1db7f77a7d087beafbec59ae6df1bba4d3368dfe8c"},
 ]
 
 [package.dependencies]
@@ -432,28 +472,29 @@
 click = ">=8"
 pip = ">=22.2"
 setuptools = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
 wheel = "*"
 
 [package.extras]
-coverage = ["pytest-cov"]
-testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist"]
+coverage = ["covdefaults", "pytest-cov"]
+testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist", "tomli-w"]
 
 [[package]]
 name = "prettytable"
-version = "3.7.0"
+version = "3.10.2"
 description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "prettytable-3.7.0-py3-none-any.whl", hash = "sha256:f4aaf2ed6e6062a82fd2e6e5289bbbe705ec2788fe401a3a1f62a1cea55526d2"},
-    {file = "prettytable-3.7.0.tar.gz", hash = "sha256:ef8334ee40b7ec721651fc4d37ecc7bb2ef55fde5098d994438f0dfdaa385c0c"},
+    {file = "prettytable-3.10.2-py3-none-any.whl", hash = "sha256:1cbfdeb4bcc73976a778a0fb33cb6d752e75396f16574dcb3e2d6332fd93c76a"},
+    {file = "prettytable-3.10.2.tar.gz", hash = "sha256:29ec6c34260191d42cd4928c28d56adec360ac2b1208a26c7e4f14b90cc8bc84"},
 ]
 
 [package.dependencies]
 wcwidth = "*"
 
 [package.extras]
-tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"]
+tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"]
 
 [[package]]
 name = "pyelftools"
@@ -468,101 +509,109 @@
 
 [[package]]
 name = "pygments"
-version = "2.15.1"
+version = "2.18.0"
 description = "Pygments is a syntax highlighting package written in Python."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
-    {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+    {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
+    {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
 ]
 
 [package.extras]
-plugins = ["importlib-metadata"]
+windows-terminal = ["colorama (>=0.4.6)"]
 
 [[package]]
 name = "pyproject-hooks"
-version = "1.0.0"
+version = "1.1.0"
 description = "Wrappers to call pyproject.toml-based build backend hooks."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
-    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
+    {file = "pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"},
+    {file = "pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965"},
 ]
 
-[package.dependencies]
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-
 [[package]]
 name = "pytz"
-version = "2023.3"
+version = "2024.1"
 description = "World timezone definitions, modern and historical"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
-    {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+    {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
+    {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
 ]
 
 [[package]]
 name = "pyyaml"
-version = "6.0"
+version = "6.0.1"
 description = "YAML parser and emitter for Python"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
-    {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
-    {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
-    {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
-    {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
-    {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
-    {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
-    {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
-    {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
-    {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
-    {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
-    {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
-    {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
-    {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
-    {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
-    {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
-    {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
-    {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
-    {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
-    {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
+    {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
+    {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+    {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
+    {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
+    {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
+    {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
+    {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+    {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
+    {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
+    {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+    {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
+    {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+    {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
+    {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
+    {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
+    {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
+    {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
+    {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+    {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
+    {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
+    {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
+    {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
+    {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+    {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
+    {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
+    {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
+    {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
 ]
 
 [[package]]
 name = "requests"
-version = "2.31.0"
+version = "2.32.3"
 description = "Python HTTP for Humans."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
-    {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
 ]
 
 [package.dependencies]
@@ -576,20 +625,50 @@
 use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
 
 [[package]]
+name = "rich"
+version = "10.16.2"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+    {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
+    {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
+]
+
+[package.dependencies]
+colorama = ">=0.4.0,<0.5.0"
+commonmark = ">=0.9.0,<0.10.0"
+pygments = ">=2.6.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
+
+[[package]]
 name = "setuptools"
-version = "67.7.2"
+version = "72.1.0"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"},
-    {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"},
+    {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"},
+    {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"},
 ]
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+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"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+description = "Tool to Detect Surrounding Shell"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
+    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
+]
 
 [[package]]
 name = "six"
@@ -650,19 +729,19 @@
 
 [[package]]
 name = "sphinx-rtd-theme"
-version = "1.2.0"
+version = "1.3.0"
 description = "Read the Docs theme for Sphinx"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
 files = [
-    {file = "sphinx_rtd_theme-1.2.0-py2.py3-none-any.whl", hash = "sha256:f823f7e71890abe0ac6aaa6013361ea2696fc8d3e1fa798f463e82bdb77eeff2"},
-    {file = "sphinx_rtd_theme-1.2.0.tar.gz", hash = "sha256:a0d8bd1a2ed52e0b338cbe19c4b2eef3c5e7a048769753dac6a9f059c7b641b8"},
+    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
+    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
 ]
 
 [package.dependencies]
 docutils = "<0.19"
-sphinx = ">=1.6,<7"
-sphinxcontrib-jquery = {version = ">=2.0.0,<3.0.0 || >3.0.0", markers = "python_version > \"3\""}
+sphinx = ">=1.6,<8"
+sphinxcontrib-jquery = ">=4,<5"
 
 [package.extras]
 dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
@@ -804,6 +883,25 @@
 cairosvg = ["cairosvg (>=1.0)"]
 
 [[package]]
+name = "tlc"
+version = "0.9.0"
+description = "Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."
+optional = false
+python-versions = "^3.8"
+files = []
+develop = false
+
+[package.dependencies]
+click = "^8.1.7"
+pyyaml = "^6.0.1"
+rich = "^10.14.0"
+typer = {version = "^0.4.0", extras = ["all"]}
+
+[package.source]
+type = "directory"
+url = "tools/tlc"
+
+[[package]]
 name = "tomli"
 version = "2.0.1"
 description = "A lil' TOML parser"
@@ -815,74 +913,96 @@
 ]
 
 [[package]]
-name = "typing-extensions"
-version = "4.5.0"
-description = "Backported and Experimental Type Hints for Python 3.7+"
+name = "typer"
+version = "0.4.2"
+description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.6"
 files = [
-    {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
-    {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
+    {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
+    {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
+]
+
+[package.dependencies]
+click = ">=7.1.1,<9.0.0"
+colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""}
+shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""}
+
+[package.extras]
+all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
 
 [[package]]
 name = "urllib3"
-version = "2.0.2"
+version = "2.2.2"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"},
-    {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"},
+    {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
+    {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
 ]
 
 [package.extras]
 brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+h2 = ["h2 (>=4,<5)"]
 socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
 zstd = ["zstandard (>=0.18.0)"]
 
 [[package]]
 name = "wcwidth"
-version = "0.2.6"
+version = "0.2.13"
 description = "Measures the displayed width of unicode strings in a terminal"
 optional = false
 python-versions = "*"
 files = [
-    {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"},
-    {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"},
+    {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
+    {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
 ]
 
 [[package]]
 name = "wheel"
-version = "0.40.0"
+version = "0.43.0"
 description = "A built-package format for Python"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"},
-    {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"},
+    {file = "wheel-0.43.0-py3-none-any.whl", hash = "sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81"},
+    {file = "wheel-0.43.0.tar.gz", hash = "sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85"},
 ]
 
 [package.extras]
-test = ["pytest (>=6.0.0)"]
+test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
 
 [[package]]
 name = "zipp"
-version = "3.15.0"
+version = "3.19.2"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
-    {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
+    {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"},
+    {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"},
 ]
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
 
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
+content-hash = "8798a2d1efd456c3b68ae464a216f015afaa1bbb653a905148bef17ab8ce278e"
diff --git a/pyproject.toml b/pyproject.toml
index 0fe2383..03d898e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "trusted-firmware-a"
-version = "2.10.0"
+version = "2.11.0"
 description = "Trusted Firmware-A (TF-A) Python dependencies."
 authors = ["Arm Ltd."]
 license = "BSD-3-Clause"
@@ -14,8 +14,12 @@
 
 [tool.poetry.dependencies]
 python = "^3.8"
+tlc = {path = "tools/tlc"}
 
-[tool.poetry.group.doc.dependencies]
+[tool.poetry.group.docs]
+optional = true
+
+[tool.poetry.group.docs.dependencies]
 sphinx = "^5.3.0"
 myst-parser = "^0.18.1"
 sphinxcontrib-plantuml = "^0.24.1"
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index d6c0040..9e83848 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -552,13 +552,14 @@
 
 		if (opteed_rw == OPTEE_AARCH64) {
 			arg0 = (uint64_t)dt;
+			arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
 			arg2 = 0;
 		} else {
-			arg2 = (uint64_t)dt;
 			arg0 = 0;
+			arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+			arg2 = (uint64_t)dt;
 		}
-		arg1 = TRANSFER_LIST_SIGNATURE |
-			REGISTER_CONVENTION_VERSION_MASK;
+
 		arg3 = (uint64_t)bl31_tl;
 	} else {
 		/* Default handoff arguments */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index 7daebcd..f2048a3 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.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
@@ -160,9 +160,9 @@
 	(void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
 	ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
 	ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
-	ctx->fiq_sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1);
+	ctx->fiq_sp_el1 = read_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1);
 
-	write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
+	write_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1, ctx->fiq_handler_sp);
 	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
 
 	SMC_RET0(handle);
@@ -221,7 +221,7 @@
 	 */
 	(void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
 	ctx->fiq_handler_active = 0;
-	write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
+	write_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1, ctx->fiq_sp_el1);
 	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
 
 	SMC_RET0(handle);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 2d59fc9..61e1076 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -45,7 +45,7 @@
 };
 
 struct em_cpu_list{
-	unsigned long cpu_partnumber;	/* cpu specific part number defined in midr reg */
+	unsigned long cpu_midr;	/* cpu specific part number is bit[15:4] of midr value */
 	struct   em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
 };
 
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 0a1d4f3..0d0ecc3 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -23,7 +23,7 @@
 struct em_cpu_list cpu_list[] = {
 #if CORTEX_A78_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_MIDR,
+	.cpu_midr = CORTEX_A78_MIDR,
 	.cpu_errata_list = {
 		[0] = {2712571, 0x00, 0x12},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -33,7 +33,7 @@
 
 #if CORTEX_A78_AE_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_AE_MIDR,
+	.cpu_midr = CORTEX_A78_AE_MIDR,
 	.cpu_errata_list = {
 		[0] = {2712574, 0x00, 0x02},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -43,7 +43,7 @@
 
 #if CORTEX_A78C_H_INC
 {
-	.cpu_partnumber = CORTEX_A78C_MIDR,
+	.cpu_midr = CORTEX_A78C_MIDR,
 	.cpu_errata_list = {
 		[0] = {2712575, 0x01, 0x02},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -53,7 +53,7 @@
 
 #if NEOVERSE_V1_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V1_MIDR,
+	.cpu_midr = NEOVERSE_V1_MIDR,
 	.cpu_errata_list = {
 		[0] = {2701953, 0x00, 0x11},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -63,7 +63,7 @@
 
 #if CORTEX_A710_H_INC
 {
-	.cpu_partnumber = CORTEX_A710_MIDR,
+	.cpu_midr = CORTEX_A710_MIDR,
 	.cpu_errata_list = {
 		[0] = {2701952, 0x00, 0x21},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -73,7 +73,7 @@
 
 #if NEOVERSE_N2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_N2_MIDR,
+	.cpu_midr = NEOVERSE_N2_MIDR,
 	.cpu_errata_list = {
 		[0] = {2728475, 0x00, 0x02},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -83,7 +83,7 @@
 
 #if CORTEX_X2_H_INC
 {
-	.cpu_partnumber = CORTEX_X2_MIDR,
+	.cpu_midr = CORTEX_X2_MIDR,
 	.cpu_errata_list = {
 		[0] = {2701952, 0x00, 0x21},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -93,7 +93,7 @@
 
 #if NEOVERSE_V2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V2_MIDR,
+	.cpu_midr = NEOVERSE_V2_MIDR,
 	.cpu_errata_list = {
 		[0] = {2719103, 0x00, 0x01},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -103,7 +103,7 @@
 
 #if CORTEX_X3_H_INC
 {
-	.cpu_partnumber = CORTEX_X3_MIDR,
+	.cpu_midr = CORTEX_X3_MIDR,
 	.cpu_errata_list = {
 		[0] = {2701951, 0x00, 0x11},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -113,7 +113,7 @@
 
 #if CORTEX_X4_H_INC
 {
-	.cpu_partnumber = CORTEX_X4_MIDR,
+	.cpu_midr = CORTEX_X4_MIDR,
 	.cpu_errata_list = {
 		[0] = {2701112, 0x00, 0x00},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -142,7 +142,7 @@
 		 * If the cpu partnumber in the cpu list, matches the midr
 		 * part number, check to see if the errata ID matches
 		 */
-		if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber)) {
+		if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_midr)) {
 
 			struct em_cpu *ptr = NULL;
 
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 6ccb003..15b3724 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -202,19 +202,23 @@
 	int rc;
 
 	/* Make sure RME is supported. */
-	assert(is_feat_rme_present());
+	if (is_feat_rme_present() == 0U) {
+		/* Mark the RMM boot as failed for all the CPUs */
+		rmm_boot_failed = true;
+		return -ENOTSUP;
+	}
 
 	rmm_ep_info = bl31_plat_get_next_image_ep_info(REALM);
-	if (rmm_ep_info == NULL) {
+	if ((rmm_ep_info == NULL) || (rmm_ep_info->pc == 0)) {
 		WARN("No RMM image provided by BL2 boot loader, Booting "
 		     "device without RMM initialization. SMCs destined for "
 		     "RMM will return SMC_UNK\n");
+
+		/* Mark the boot as failed for all the CPUs */
+		rmm_boot_failed = true;
 		return -ENOENT;
 	}
 
-	/* Under no circumstances will this parameter be 0 */
-	assert(rmm_ep_info->pc == RMM_BASE);
-
 	/* Initialise an entrypoint to set up the CPU context */
 	ep_attr = EP_REALM;
 	if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U) {
@@ -239,6 +243,8 @@
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
+		/* Mark the boot as failed for all the CPUs */
+		rmm_boot_failed = true;
 		return rc;
 	}
 	flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index 609d968..e8beae1 100644
--- a/services/std_svc/spm/el3_spmc/spmc_setup.c
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -319,24 +319,35 @@
 		      xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
 		      EL1_EL0_REGIME);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1,
 		      mmu_cfg_params[MMU_CFG_MAIR]);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1, mmu_cfg_params[MMU_CFG_TCR]);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1,
 		      mmu_cfg_params[MMU_CFG_TCR]);
+#endif /* ERRATA_SPECULATIVE_AT */
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1,
 		      mmu_cfg_params[MMU_CFG_TTBR0]);
 }
 
 static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx)
 {
-	u_register_t sctlr_el1;
+	u_register_t sctlr_el1_val;
 
 	/* Setup SCTLR_EL1 */
-	sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1);
+#if (ERRATA_SPECULATIVE_AT)
+	sctlr_el1_val = read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+				 CTX_ERRATA_SPEC_AT_SCTLR_EL1);
+#else
+	sctlr_el1_val = read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
 
-	sctlr_el1 |=
+	sctlr_el1_val |=
 		/*SCTLR_EL1_RES1 |*/
 		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
 		SCTLR_UCI_BIT |
@@ -357,7 +368,7 @@
 		/* Enable MMU. */
 		SCTLR_M_BIT;
 
-	sctlr_el1 &= ~(
+	sctlr_el1_val &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT |
 		/*
@@ -369,7 +380,13 @@
 		SCTLR_UMA_BIT
 	);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1, sctlr_el1_val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, sctlr_el1_val);
+#endif /* ERRATA_SPECULATIVE_AT */
 }
 
 static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp,
@@ -383,10 +400,10 @@
 	/* Setup other system registers. */
 
 	/* Shim Exception Vector Base Address */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1,
 			SPM_SHIM_EXCEPTIONS_PTR);
 #if NS_TIMER_SWITCH
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cntkctl_el1,
 		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
 #endif
 
@@ -397,7 +414,7 @@
 	 * TTA: Enable access to trace registers.
 	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
 	 */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1,
 			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
 }
 
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 4e65c9c..bb9c7a9 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -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.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -27,7 +27,7 @@
 void spm_sp_setup(sp_context_t *sp_ctx)
 {
 	cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
-
+	u_register_t sctlr_el1_val;
 	/* Pointer to the MP information from the platform port. */
 	const spm_mm_boot_info_t *sp_boot_info =
 			plat_get_secure_partition_boot_info(NULL);
@@ -122,19 +122,30 @@
 		      xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
 		      EL1_EL0_REGIME);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1,
 		      mmu_cfg_params[MMU_CFG_MAIR]);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1, mmu_cfg_params[MMU_CFG_TCR]);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1,
 		      mmu_cfg_params[MMU_CFG_TCR]);
+#endif /* ERRATA_SPECULATIVE_AT */
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1,
 		      mmu_cfg_params[MMU_CFG_TTBR0]);
 
 	/* Setup SCTLR_EL1 */
-	u_register_t sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1);
+#if (ERRATA_SPECULATIVE_AT)
+	sctlr_el1_val = read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+				 CTX_ERRATA_SPEC_AT_SCTLR_EL1);
+#else
+	sctlr_el1_val = read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
 
-	sctlr_el1 |=
+	sctlr_el1_val |=
 		/*SCTLR_EL1_RES1 |*/
 		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
 		SCTLR_UCI_BIT							|
@@ -156,7 +167,7 @@
 		SCTLR_M_BIT
 	;
 
-	sctlr_el1 &= ~(
+	sctlr_el1_val &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT							|
 		/*
@@ -168,7 +179,13 @@
 		SCTLR_UMA_BIT
 	);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1, sctlr_el1_val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, sctlr_el1_val);
+#endif /* ERRATA_SPECULATIVE_AT */
 
 	/*
 	 * Setup other system registers
@@ -176,10 +193,10 @@
 	 */
 
 	/* Shim Exception Vector Base Address */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1,
 			SPM_SHIM_EXCEPTIONS_PTR);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+	write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1,
 		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
 
 	/*
@@ -189,7 +206,7 @@
 	 * TTA: Enable access to trace registers.
 	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
 	 */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1,
 			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
 
 	/*
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 0715b13..e3d7fbd 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -52,26 +52,11 @@
 static entry_point_info_t *spmc_ep_info;
 
 /*******************************************************************************
- * SPM Core context on CPU based on mpidr.
- ******************************************************************************/
-spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr)
-{
-	int core_idx = plat_core_pos_by_mpidr(mpidr);
-
-	if (core_idx < 0) {
-		ERROR("Invalid mpidr: %" PRIx64 ", returned ID: %d\n", mpidr, core_idx);
-		panic();
-	}
-
-	return &spm_core_context[core_idx];
-}
-
-/*******************************************************************************
  * SPM Core context on current CPU get helper.
  ******************************************************************************/
 spmd_spm_core_context_t *spmd_get_context(void)
 {
-	return spmd_get_context_by_mpidr(read_mpidr());
+	return &spm_core_context[plat_my_core_pos()];
 }
 
 /*******************************************************************************
@@ -217,7 +202,6 @@
 {
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
-	unsigned int linear_id = plat_my_core_pos();
 	int64_t rc;
 
 	/* Sanity check the security state when the exception was generated */
@@ -248,7 +232,7 @@
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
-		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, linear_id);
+		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, plat_my_core_pos());
 	}
 
 	ctx->secure_interrupt_ongoing = false;
@@ -677,6 +661,7 @@
 {
 	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
+	void *ctx_out;
 
 #if SPMD_SPM_AT_SEL2
 	if ((secure_state_out == SECURE) && (is_sve_hint_set(flags) == true)) {
@@ -703,6 +688,7 @@
 #endif
 	cm_set_next_eret_context(secure_state_out);
 
+	ctx_out = cm_get_context(secure_state_out);
 #if SPMD_SPM_AT_SEL2
 	/*
 	 * If SPMC is at SEL2, save additional registers x8-x17, which may
@@ -715,7 +701,7 @@
 	 * preserved, so the SPMD passes through these registers and expects the
 	 * SPMC to save and restore (potentially also modify) them.
 	 */
-	SMC_RET18(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
+	SMC_RET18(ctx_out, smc_fid, x1, x2, x3, x4,
 			SMC_GET_GP(handle, CTX_GPREG_X5),
 			SMC_GET_GP(handle, CTX_GPREG_X6),
 			SMC_GET_GP(handle, CTX_GPREG_X7),
@@ -732,7 +718,7 @@
 			);
 
 #else
-	SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
+	SMC_RET8(ctx_out, smc_fid, x1, x2, x3, x4,
 			SMC_GET_GP(handle, CTX_GPREG_X5),
 			SMC_GET_GP(handle, CTX_GPREG_X6),
 			SMC_GET_GP(handle, CTX_GPREG_X7));
@@ -852,7 +838,6 @@
 			  void *handle,
 			  uint64_t flags)
 {
-	unsigned int linear_id = plat_my_core_pos();
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	bool secure_origin;
 	int ret;
@@ -863,7 +848,7 @@
 
 	VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64
 		" 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n",
-		    linear_id, smc_fid, x1, x2, x3, x4,
+		    plat_my_core_pos(), smc_fid, x1, x2, x3, x4,
 		    SMC_GET_GP(handle, CTX_GPREG_X5),
 		    SMC_GET_GP(handle, CTX_GPREG_X6),
 		    SMC_GET_GP(handle, CTX_GPREG_X7));
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index e782d09..5cfe5f9 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -66,7 +66,7 @@
 
 #if ENABLE_RME
 	if (rmmd_setup() != 0) {
-		ret = 1;
+		WARN("RMMD setup failed. Continuing boot.\n");
 	}
 #endif
 
diff --git a/tools/amlogic/Makefile b/tools/amlogic/Makefile
index 5ff26e5..7a53437 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -10,11 +10,11 @@
 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}
 OBJECTS := doimage.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -24,26 +24,20 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 21523f6..16f4aa3 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -5,7 +5,6 @@
 #
 
 PLAT		:= none
-V		?= 0
 DEBUG		:= 0
 CRTTOOL		?= cert_create${BIN_EXT}
 BINARY		:= $(notdir ${CRTTOOL})
@@ -16,8 +15,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}defaults.mk
 include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
+include ${MAKE_HELPERS_DIRECTORY}utilities.mk
 
 ifneq (${PLAT},none)
 TF_PLATFORM_ROOT	:=	../../plat/
@@ -60,13 +61,7 @@
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=20
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCCFLAGS += ${DEFINES}
+HOSTCCFLAGS += ${DEFINES} -DPLAT_MSG=$(call escape-shell,"$(PLAT_MSG)")
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
 # computed value.
 HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
@@ -89,23 +84,20 @@
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
-                const char platform_msg[] = "${PLAT_MSG}";' | \
-                $(host-cc) -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}$(host-cc) src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 14610ed..edc2d68 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.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
  */
@@ -66,10 +66,8 @@
 static int save_keys;
 static int print_cert;
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
-extern const char platform_msg[];
-
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
+static const char platform_msg[] = PLAT_MSG;
 
 static char *strdup(const char *str)
 {
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index d0efab8..56cb21a 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.10.0",
+  "version": "2.11.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 83f2f57..0210c36 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,10 +1,10 @@
 #
+# Copyright (c) 2024, Arm Limited. All rights reserved.
 # Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-V		?= 0
 BUILD_INFO	?= 1
 DEBUG		:= 0
 ENCTOOL		?= encrypt_fw${BIN_EXT}
@@ -16,6 +16,7 @@
 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
 
@@ -38,11 +39,6 @@
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=10
 endif
 endif
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
 
 HOSTCCFLAGS += ${DEFINES}
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
@@ -68,22 +64,20 @@
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
-                $(host-cc) -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}$(host-cc) src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
index 39b7af7..6e43e73 100644
--- a/tools/encrypt_fw/src/main.c
+++ b/tools/encrypt_fw/src/main.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited. All rights reserved.
  * Author: Sumit Garg <sumit.garg@linaro.org>
  *
@@ -25,8 +26,7 @@
 
 /* Global options */
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
 
 static char *key_algs_str[] = {
 	[KEY_ALG_GCM] = "gcm",
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 865ff4c..23c8e64 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -9,13 +9,13 @@
 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}
 PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
-V ?= 0
 STATIC ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
@@ -55,12 +55,6 @@
 
 HOSTCCFLAGS += ${DEFINES}
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 ifneq (${PLAT},)
 TF_PLATFORM_ROOT	:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
@@ -81,22 +75,22 @@
 all: --openssl ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@ $(LDOPTS)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ $(LDOPTS)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
 
 -include $(DEPS)
 
 --openssl:
 ifeq ($(STATIC),0)
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 endif # STATIC
 
diff --git a/tools/marvell/doimage/Makefile b/tools/marvell/doimage/Makefile
index 6e59aa2..488b768 100644
--- a/tools/marvell/doimage/Makefile
+++ b/tools/marvell/doimage/Makefile
@@ -6,6 +6,7 @@
 
 toolchains := host
 
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 PROJECT = doimage
@@ -36,16 +37,16 @@
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
-	${Q}${RM} ${PROJECT}
-	${Q}${RM} ${OBJECTS}
+	$(q)${RM} ${PROJECT}
+	$(q)${RM} ${OBJECTS}
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index b6b3b04..7648b7f 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -9,13 +9,13 @@
 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}
 OBJECTS_1 := create_pbl.o
 PROJECT_2 := byte_swap${BIN_EXT}
 OBJECTS_2 := byte_swap.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 CFLAGS := -Wall -Werror -pedantic -std=c99
@@ -26,12 +26,6 @@
 endif
 LDLIBS :=
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS :=
 
 .PHONY: all clean distclean
@@ -39,22 +33,22 @@
 all: create_pbl byte_swap
 
 ${PROJECT_1}: ${OBJECTS_1} Makefile
-	@echo "  LD      $@"
-	${Q}$(host-cc) ${OBJECTS_1} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_1} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ${PROJECT_2}: ${OBJECTS_2} Makefile
-	@echo "  LD      $@"
-	${Q}$(host-cc) ${OBJECTS_2} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_2} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c %.h Makefile
-	@echo "  CC      $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  CC      $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT_1} ${OBJECTS_1})
diff --git a/tools/nxp/create_pbl/pbl_ch2.mk b/tools/nxp/create_pbl/pbl_ch2.mk
index e6f1d8b..bf05a12 100644
--- a/tools/nxp/create_pbl/pbl_ch2.mk
+++ b/tools/nxp/create_pbl/pbl_ch2.mk
@@ -15,12 +15,12 @@
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 	# Add bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
 			-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;\
@@ -31,7 +31,7 @@
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl;
 endif # SWAP
 endif # BOOT_MODE
@@ -39,22 +39,19 @@
 endif
 else  # NON SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# -a option appends the image for Chassis 3 devices in case of non secure boot
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl;
 endif # SWAP
 endif # BOOT_MODE
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
 endif
 endif # SECURE_BOOT
-
-
-
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index 9283474..15129e4 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -21,13 +21,13 @@
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 
 	# Add Block Copy command for bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
@@ -39,14 +39,14 @@
 			-o ${BUILD_PLAT}/rcw_sec.pbl
 
 	# Sign and add "Load Security Header command to PBI commands
-	$(Q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
 
 	# Append the bl2_hdr to the RCW image
-	@echo "${bl2_hdr_loc}"
+	$(s)echo "${bl2_hdr_loc}"
 	dd if=${BUILD_PLAT}/hdr_bl2 of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_hdr_loc}
 
 	# Append the bl2.bin to the RCW image
-	@echo "${bl2_loc}"
+	$(s)echo "${bl2_loc}"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_loc}
 
 	rm ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl
@@ -54,16 +54,16 @@
 endif
 else  #SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 
 	# Add Block Copy command and populate boot loc ptrfor bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl -f ${BL2_SRC_OFFSET};
 
 	# Append the bl2.bin to the RCW image
-	@echo "bl2_loc is ${bl2_loc} KB"
+	$(s)echo "bl2_loc is ${bl2_loc} KB"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl bs=1K seek=${bl2_loc}
 
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index 919c1de..7a64b19 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -1,4 +1,5 @@
 #
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -6,6 +7,8 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/build-rules.mk
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 ###################################################
@@ -84,33 +87,37 @@
 # command
 
 .PHONY: all
-all: $(OUTPUT_FILE_SA0) $(OUTPUT_FILE_SA6)
+
+all: $(FILE_NAME_SA0).srec $(FILE_NAME_SA0).bin
+all: $(FILE_NAME_SA6).srec $(FILE_NAME_SA6).bin
+
 ###################################################
 # Linker
 ###################################################
-$(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib	\
-	-T $(MEMORY_DEF_SA0)			\
-	-o $(OUTPUT_FILE_SA0)			\
-	-Wl,-Map $(FILE_NAME_SA0).map 		\
 
-	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
-	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+$(FILE_NAME_SA0).srec: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
 
-$(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib	\
-	-T $(MEMORY_DEF_SA6)			\
-	-o $(OUTPUT_FILE_SA6)			\
-	-Wl,-Map $(FILE_NAME_SA6).map 		\
+$(FILE_NAME_SA0).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
-	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
-	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).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
+
+$(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
+
+$(FILE_NAME_SA6).bin: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(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
 
 ###################################################
 # Compile
 ###################################################
 
-%.o: %.c
+%.o: %.c | $$(@D)/
 	$(aarch64-cc) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
diff --git a/tools/renesas/rzg_layout_create/makefile b/tools/renesas/rzg_layout_create/makefile
index e1c242d..936420d 100644
--- a/tools/renesas/rzg_layout_create/makefile
+++ b/tools/renesas/rzg_layout_create/makefile
@@ -1,4 +1,5 @@
 #
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -6,6 +7,8 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/build-rules.mk
+include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
 ###################################################
@@ -81,33 +84,37 @@
 # command
 
 .PHONY: all
-all: $(OUTPUT_FILE_SA0) $(OUTPUT_FILE_SA6)
+
+all: $(FILE_NAME_SA0).srec $(FILE_NAME_SA0).bin
+all: $(FILE_NAME_SA6).srec $(FILE_NAME_SA6).bin
+
 ###################################################
 # Linker
 ###################################################
-$(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib	\
-	-T $(MEMORY_DEF_SA0)			\
-	-o $(OUTPUT_FILE_SA0)			\
-	-Wl,-Map $(FILE_NAME_SA0).map 		\
 
-	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
-	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+$(FILE_NAME_SA0).srec: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
 
-$(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib	\
-	-T $(MEMORY_DEF_SA6)			\
-	-o $(OUTPUT_FILE_SA6)			\
-	-Wl,-Map $(FILE_NAME_SA6).map 		\
+$(FILE_NAME_SA0).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
-	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
-	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).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
+
+$(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
+
+$(FILE_NAME_SA6).bin: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(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
 
 ###################################################
 # Compile
 ###################################################
 
-%.o: %.c
+%.o: %.c | $$(@D)/
 	$(aarch64-cc) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index a913ce5..e336a0c 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -9,12 +9,12 @@
 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}
 PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99
@@ -24,12 +24,6 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS := -I../../include/tools_share
 
 .PHONY: all clean distclean
@@ -37,15 +31,15 @@
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index c75e941..2b34ef8 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -9,11 +9,11 @@
 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}
 OBJECTS := stm32image.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -23,26 +23,20 @@
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}$(host-cc) ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/tlc/Makefile b/tools/tlc/Makefile
new file mode 100644
index 0000000..e50b9dd
--- /dev/null
+++ b/tools/tlc/Makefile
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+##* Variables
+SHELL := /usr/bin/env bash
+PYTHON := python
+PYTHONPATH := `pwd`
+
+#* Docker variables
+IMAGE := tlc
+VERSION := latest
+
+#* Installation
+.PHONY: dist
+dist: clean
+	poetry build
+
+.PHONY: dev-install
+dev-install:
+	poetry lock -n --no-update && poetry export --without-hashes > requirements.txt
+	poetry install -n
+	-poetry run mypy --install-types --non-interactive ./
+
+.PHONY: install
+install: dist
+	pip install dist/*.whl
+
+.PHONY: pre-commit-install
+pre-commit-install:
+	poetry run pre-commit install
+
+#* Formatters
+.PHONY: codestyle
+codestyle:
+	poetry run pyupgrade --exit-zero-even-if-changed --py38-plus **/*.py
+	poetry run isort --settings-path pyproject.toml ./
+	poetry run black --config pyproject.toml ./
+
+.PHONY: formatting
+formatting: codestyle
+
+#* Linting
+.PHONY: test
+test:
+	PYTHONPATH=$(PYTHONPATH) poetry run pytest -c pyproject.toml --cov-report=html --cov=tlc tests/
+	poetry run coverage-badge -o assets/images/coverage.svg -f
+
+.PHONY: check-codestyle
+check-codestyle:
+	poetry run isort --diff --check-only --settings-path pyproject.toml ./
+	poetry run black --diff --check --config pyproject.toml ./
+	poetry run darglint --verbosity 2 tlc tests
+
+.PHONY: mypy
+mypy:
+	poetry run mypy --config-file pyproject.toml ./
+
+.PHONY: check-safety
+check-safety:
+	poetry check
+	poetry run safety check --full-report
+	poetry run bandit -ll --recursive tlc tests
+
+.PHONY: lint
+lint: test check-codestyle mypy check-safety
+
+.PHONY: update-dev-deps
+update-dev-deps:
+	poetry add -D bandit@latest darglint@latest "isort[colors]@latest" mypy@latest pre-commit@latest pydocstyle@latest pylint@latest pytest@latest pyupgrade@latest safety@latest coverage@latest coverage-badge@latest pytest-html@latest pytest-cov@latest
+	poetry add -D --allow-prereleases black@latest
+
+#* Docker
+.PHONY: docker-build docker-remove
+docker-build:
+	@echo Building docker $(IMAGE):$(VERSION) ...
+	docker build \
+		-t $(IMAGE):$(VERSION) . \
+		-f ./docker/Dockerfile --no-cache
+
+docker-remove:
+	@echo Removing docker $(IMAGE):$(VERSION) ...
+	docker rmi -f $(IMAGE):$(VERSION)
+
+
+#* Cleaning
+.PHONY: clean .clean-build clean-pyc clean-test
+clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
+
+clean-build: ## remove build artifacts
+	rm -fr build/
+	rm -fr dist/
+	rm -fr .eggs/
+	find . -name '*.egg-info' -exec rm -fr {} +
+	find . -name '*.egg' -exec rm -f {} +
+
+clean-pyc: ## remove Python file artifacts
+	find . -name '*.pyc' -exec rm -f {} +
+	find . -name '*.pyo' -exec rm -f {} +
+	find . -name '*~' -exec rm -f {} +
+	find . -name '__pycache__' -exec rm -fr {} +
+	find . | grep -E ".pytest_cache" | xargs rm -rf
+	find . | grep -E ".mypy_cache" | xargs rm -rf
+
+clean-test: ## remove test and coverage artifacts
+	rm -fr .tox/
+	rm -f .coverage
+	rm -fr htmlcov/
diff --git a/tools/tlc/assets/images/coverage.svg b/tools/tlc/assets/images/coverage.svg
new file mode 100644
index 0000000..b6c4e36
--- /dev/null
+++ b/tools/tlc/assets/images/coverage.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
+    <linearGradient id="b" x2="0" y2="100%">
+        <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
+        <stop offset="1" stop-opacity=".1"/>
+    </linearGradient>
+    <mask id="a">
+        <rect width="99" height="20" rx="3" fill="#fff"/>
+    </mask>
+    <g mask="url(#a)">
+        <path fill="#555" d="M0 0h63v20H0z"/>
+        <path fill="#4c1" d="M63 0h36v20H63z"/>
+        <path fill="url(#b)" d="M0 0h99v20H0z"/>
+    </g>
+    <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
+        <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
+        <text x="31.5" y="14">coverage</text>
+        <text x="80" y="15" fill="#010101" fill-opacity=".3">95%</text>
+        <text x="80" y="14">95%</text>
+    </g>
+</svg>
diff --git a/tools/tlc/poetry.lock b/tools/tlc/poetry.lock
new file mode 100644
index 0000000..839f236
--- /dev/null
+++ b/tools/tlc/poetry.lock
@@ -0,0 +1,1356 @@
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+
+[[package]]
+name = "astroid"
+version = "2.15.8"
+description = "An abstract syntax tree for Python with inference support."
+optional = false
+python-versions = ">=3.7.2"
+files = [
+    {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
+    {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
+]
+
+[package.dependencies]
+lazy-object-proxy = ">=1.4.0"
+typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
+wrapt = [
+    {version = ">=1.11,<2", markers = "python_version < \"3.11\""},
+    {version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
+]
+
+[[package]]
+name = "bandit"
+version = "1.7.9"
+description = "Security oriented static analyser for python code."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"},
+    {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
+PyYAML = ">=5.3.1"
+rich = "*"
+stevedore = ">=1.20.0"
+
+[package.extras]
+baseline = ["GitPython (>=3.1.30)"]
+sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"]
+test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"]
+toml = ["tomli (>=1.1.0)"]
+yaml = ["PyYAML"]
+
+[[package]]
+name = "black"
+version = "24.4.2"
+description = "The uncompromising code formatter."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"},
+    {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"},
+    {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"},
+    {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"},
+    {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"},
+    {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"},
+    {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"},
+    {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"},
+    {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"},
+    {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"},
+    {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"},
+    {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"},
+    {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"},
+    {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"},
+    {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"},
+    {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"},
+    {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"},
+    {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"},
+    {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"},
+    {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"},
+    {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"},
+    {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"},
+]
+
+[package.dependencies]
+click = ">=8.0.0"
+mypy-extensions = ">=0.4.3"
+packaging = ">=22.0"
+pathspec = ">=0.9.0"
+platformdirs = ">=2"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+colorama = ["colorama (>=0.4.3)"]
+d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+uvloop = ["uvloop (>=0.15.2)"]
+
+[[package]]
+name = "certifi"
+version = "2024.7.4"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
+    {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
+]
+
+[[package]]
+name = "cfgv"
+version = "3.4.0"
+description = "Validate configuration and produce human readable error messages."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
+    {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.3.2"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+    {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+    {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "commonmark"
+version = "0.9.1"
+description = "Python parser for the CommonMark Markdown spec"
+optional = false
+python-versions = "*"
+files = [
+    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
+    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
+]
+
+[package.extras]
+test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
+
+[[package]]
+name = "coverage"
+version = "6.5.0"
+description = "Code coverage measurement for Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"},
+    {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"},
+    {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"},
+    {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"},
+    {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"},
+    {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"},
+    {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"},
+    {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"},
+    {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"},
+    {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"},
+    {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"},
+    {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"},
+    {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"},
+    {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"},
+    {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"},
+    {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"},
+    {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"},
+    {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"},
+    {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"},
+    {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"},
+]
+
+[package.dependencies]
+tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
+
+[package.extras]
+toml = ["tomli"]
+
+[[package]]
+name = "coverage-badge"
+version = "1.1.1"
+description = "Generate coverage badges for Coverage.py."
+optional = false
+python-versions = "*"
+files = [
+    {file = "coverage-badge-1.1.1.tar.gz", hash = "sha256:42252df917404af6147380861228a4ace3d9a29804df8fc2d34a22b2bc4f45b6"},
+    {file = "coverage_badge-1.1.1-py2.py3-none-any.whl", hash = "sha256:1d8e566ad47c37910fa2bbc74ea19972b171b5b4e40624b31b3e2f2d93680266"},
+]
+
+[package.dependencies]
+coverage = "*"
+
+[[package]]
+name = "darglint"
+version = "1.8.1"
+description = "A utility for ensuring Google-style docstrings stay up to date with the source code."
+optional = false
+python-versions = ">=3.6,<4.0"
+files = [
+    {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"},
+    {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"},
+]
+
+[[package]]
+name = "dill"
+version = "0.3.8"
+description = "serialize all of Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"},
+    {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"},
+]
+
+[package.extras]
+graph = ["objgraph (>=1.7.2)"]
+profile = ["gprof2dot (>=2022.7.29)"]
+
+[[package]]
+name = "distlib"
+version = "0.3.8"
+description = "Distribution utilities"
+optional = false
+python-versions = "*"
+files = [
+    {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
+    {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
+]
+
+[[package]]
+name = "dparse"
+version = "0.6.3"
+description = "A parser for Python dependency files"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"},
+    {file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"},
+]
+
+[package.dependencies]
+packaging = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
+
+[package.extras]
+conda = ["pyyaml"]
+pipenv = ["pipenv (<=2022.12.19)"]
+
+[[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 = "filelock"
+version = "3.15.4"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"},
+    {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"]
+typing = ["typing-extensions (>=4.8)"]
+
+[[package]]
+name = "identify"
+version = "2.6.0"
+description = "File identification library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"},
+    {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"},
+]
+
+[package.extras]
+license = ["ukkonen"]
+
+[[package]]
+name = "idna"
+version = "3.7"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
+    {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+]
+
+[[package]]
+name = "isort"
+version = "5.13.2"
+description = "A Python utility / library to sort Python imports."
+optional = false
+python-versions = ">=3.8.0"
+files = [
+    {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
+    {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.4.6", optional = true, markers = "extra == \"colors\""}
+
+[package.extras]
+colors = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "jinja2"
+version = "3.1.4"
+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"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "lazy-object-proxy"
+version = "1.10.0"
+description = "A fast and thorough lazy object proxy."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"},
+    {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"},
+]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.5"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+    {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
+]
+
+[[package]]
+name = "mccabe"
+version = "0.7.0"
+description = "McCabe checker, plugin for flake8"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
+    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
+]
+
+[[package]]
+name = "mypy"
+version = "0.910"
+description = "Optional static typing for Python"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
+    {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
+    {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
+    {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
+    {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
+    {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
+    {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
+    {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
+    {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
+    {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
+    {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
+    {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
+    {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
+    {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
+    {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
+    {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
+    {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
+]
+
+[package.dependencies]
+mypy-extensions = ">=0.4.3,<0.5.0"
+toml = "*"
+typing-extensions = ">=3.7.4"
+
+[package.extras]
+dmypy = ["psutil (>=4.0)"]
+python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
+
+[[package]]
+name = "mypy-extensions"
+version = "0.4.4"
+description = "Experimental type system extensions for programs checked with the mypy typechecker."
+optional = false
+python-versions = ">=2.7"
+files = [
+    {file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
+]
+
+[[package]]
+name = "nodeenv"
+version = "1.9.1"
+description = "Node.js virtual environment builder"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
+    {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
+]
+
+[[package]]
+name = "packaging"
+version = "24.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+]
+
+[[package]]
+name = "pathspec"
+version = "0.12.1"
+description = "Utility library for gitignore style pattern matching of file paths."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
+    {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
+]
+
+[[package]]
+name = "pbr"
+version = "6.0.0"
+description = "Python Build Reasonableness"
+optional = false
+python-versions = ">=2.6"
+files = [
+    {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"},
+    {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.2.2"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"},
+    {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
+type = ["mypy (>=1.8)"]
+
+[[package]]
+name = "pluggy"
+version = "1.5.0"
+description = "plugin and hook calling mechanisms for python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
+
+[[package]]
+name = "pre-commit"
+version = "2.21.0"
+description = "A framework for managing and maintaining multi-language pre-commit hooks."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"},
+    {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"},
+]
+
+[package.dependencies]
+cfgv = ">=2.0.0"
+identify = ">=1.0.0"
+nodeenv = ">=0.11.1"
+pyyaml = ">=5.1"
+virtualenv = ">=20.10.0"
+
+[[package]]
+name = "pydocstyle"
+version = "6.3.0"
+description = "Python docstring style checker"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
+    {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
+]
+
+[package.dependencies]
+snowballstemmer = ">=2.2.0"
+
+[package.extras]
+toml = ["tomli (>=1.2.3)"]
+
+[[package]]
+name = "pygments"
+version = "2.18.0"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
+    {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
+]
+
+[package.extras]
+windows-terminal = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "pylint"
+version = "2.17.7"
+description = "python code static checker"
+optional = false
+python-versions = ">=3.7.2"
+files = [
+    {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
+    {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
+]
+
+[package.dependencies]
+astroid = ">=2.15.8,<=2.17.0-dev0"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+dill = [
+    {version = ">=0.2", markers = "python_version < \"3.11\""},
+    {version = ">=0.3.6", markers = "python_version >= \"3.11\""},
+]
+isort = ">=4.2.5,<6"
+mccabe = ">=0.6,<0.8"
+platformdirs = ">=2.2.0"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+tomlkit = ">=0.10.1"
+typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
+
+[package.extras]
+spelling = ["pyenchant (>=3.2,<4.0)"]
+testutils = ["gitpython (>3)"]
+
+[[package]]
+name = "pytest"
+version = "7.4.4"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
+    {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=0.12,<2.0"
+tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
+
+[package.extras]
+testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytest-cov"
+version = "3.0.0"
+description = "Pytest plugin for measuring coverage."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"},
+    {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"},
+]
+
+[package.dependencies]
+coverage = {version = ">=5.2.1", extras = ["toml"]}
+pytest = ">=4.6"
+
+[package.extras]
+testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
+
+[[package]]
+name = "pytest-html"
+version = "4.1.1"
+description = "pytest plugin for generating HTML reports"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"},
+    {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"},
+]
+
+[package.dependencies]
+jinja2 = ">=3.0.0"
+pytest = ">=7.0.0"
+pytest-metadata = ">=2.0.0"
+
+[package.extras]
+docs = ["pip-tools (>=6.13.0)"]
+test = ["assertpy (>=1.1)", "beautifulsoup4 (>=4.11.1)", "black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "pytest-mock (>=3.7.0)", "pytest-rerunfailures (>=11.1.2)", "pytest-xdist (>=2.4.0)", "selenium (>=4.3.0)", "tox (>=3.24.5)"]
+
+[[package]]
+name = "pytest-metadata"
+version = "3.1.1"
+description = "pytest plugin for test session metadata"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"},
+    {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"},
+]
+
+[package.dependencies]
+pytest = ">=7.0.0"
+
+[package.extras]
+test = ["black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "tox (>=3.24.5)"]
+
+[[package]]
+name = "pyupgrade"
+version = "2.38.4"
+description = "A tool to automatically upgrade syntax for newer versions."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pyupgrade-2.38.4-py2.py3-none-any.whl", hash = "sha256:944ff993c396ddc2b9012eb3de4cda138eb4c149b22c6c560d4c8bfd0e180982"},
+    {file = "pyupgrade-2.38.4.tar.gz", hash = "sha256:1eb43a49f416752929741ba4d706bf3f33593d3cac9bdc217fc1ef55c047c1f4"},
+]
+
+[package.dependencies]
+tokenize-rt = "<5"
+
+[[package]]
+name = "pyyaml"
+version = "6.0.1"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
+    {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
+    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+    {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
+    {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
+    {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
+    {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
+    {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
+    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+    {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
+    {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
+    {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+    {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
+    {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+    {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
+    {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
+    {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
+    {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
+    {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
+    {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
+    {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
+    {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
+    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+    {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
+    {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
+    {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
+    {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
+    {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
+    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+    {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
+    {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
+    {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
+    {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
+]
+
+[[package]]
+name = "requests"
+version = "2.32.3"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "rich"
+version = "10.16.2"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+    {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
+    {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
+]
+
+[package.dependencies]
+colorama = ">=0.4.0,<0.5.0"
+commonmark = ">=0.9.0,<0.10.0"
+pygments = ">=2.6.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
+
+[[package]]
+name = "ruamel-yaml"
+version = "0.18.6"
+description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"},
+    {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"},
+]
+
+[package.dependencies]
+"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""}
+
+[package.extras]
+docs = ["mercurial (>5.7)", "ryd"]
+jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
+
+[[package]]
+name = "ruamel-yaml-clib"
+version = "0.2.8"
+description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"},
+    {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"},
+]
+
+[[package]]
+name = "safety"
+version = "2.3.4"
+description = "Checks installed dependencies for known vulnerabilities and licenses."
+optional = false
+python-versions = "*"
+files = [
+    {file = "safety-2.3.4-py3-none-any.whl", hash = "sha256:6224dcd9b20986a2b2c5e7acfdfba6bca42bb11b2783b24ed04f32317e5167ea"},
+    {file = "safety-2.3.4.tar.gz", hash = "sha256:b9e74e794e82f54d11f4091c5d820c4d2d81de9f953bf0b4f33ac8bc402ae72c"},
+]
+
+[package.dependencies]
+Click = ">=8.0.2"
+dparse = ">=0.6.2"
+packaging = ">=21.0"
+requests = "*"
+"ruamel.yaml" = ">=0.17.21"
+setuptools = ">=19.3"
+
+[package.extras]
+github = ["jinja2 (>=3.1.0)", "pygithub (>=1.43.3)"]
+gitlab = ["python-gitlab (>=1.3.0)"]
+
+[[package]]
+name = "setuptools"
+version = "72.1.0"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"},
+    {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"},
+]
+
+[package.extras]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+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"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+description = "Tool to Detect Surrounding Shell"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
+    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+optional = false
+python-versions = "*"
+files = [
+    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "stevedore"
+version = "5.2.0"
+description = "Manage dynamic plugins for Python applications"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"},
+    {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"},
+]
+
+[package.dependencies]
+pbr = ">=2.0.0,<2.1.0 || >2.1.0"
+
+[[package]]
+name = "tokenize-rt"
+version = "4.2.1"
+description = "A wrapper around the stdlib `tokenize` which roundtrips."
+optional = false
+python-versions = ">=3.6.1"
+files = [
+    {file = "tokenize_rt-4.2.1-py2.py3-none-any.whl", hash = "sha256:08a27fa032a81cf45e8858d0ac706004fcd523e8463415ddf1442be38e204ea8"},
+    {file = "tokenize_rt-4.2.1.tar.gz", hash = "sha256:0d4f69026fed520f8a1e0103aa36c406ef4661417f20ca643f913e33531b3b94"},
+]
+
+[[package]]
+name = "toml"
+version = "0.10.2"
+description = "Python Library for Tom's Obvious, Minimal Language"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
+    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
+]
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[[package]]
+name = "tomlkit"
+version = "0.13.0"
+description = "Style preserving TOML library"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"},
+    {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"},
+]
+
+[[package]]
+name = "typer"
+version = "0.4.2"
+description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
+    {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
+]
+
+[package.dependencies]
+click = ">=7.1.1,<9.0.0"
+colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""}
+shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""}
+
+[package.extras]
+all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+]
+
+[[package]]
+name = "urllib3"
+version = "2.2.2"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
+    {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+h2 = ["h2 (>=4,<5)"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[[package]]
+name = "virtualenv"
+version = "20.26.3"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"},
+    {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"},
+]
+
+[package.dependencies]
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<5"
+
+[package.extras]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+
+[[package]]
+name = "wrapt"
+version = "1.16.0"
+description = "Module for decorators, wrappers and monkey patching."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"},
+    {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"},
+    {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"},
+    {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"},
+    {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"},
+    {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"},
+    {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"},
+    {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"},
+    {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"},
+    {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"},
+    {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"},
+    {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"},
+    {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"},
+    {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"},
+    {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"},
+    {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"},
+    {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"},
+    {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"},
+    {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"},
+    {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"},
+    {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"},
+    {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"},
+    {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"},
+    {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"},
+    {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"},
+    {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"},
+    {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"},
+    {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "cfcb196cda412f6139302937640455aa8154d7979c69017fe45ddd528e4a1bf2"
diff --git a/tools/tlc/pyproject.toml b/tools/tlc/pyproject.toml
new file mode 100644
index 0000000..5661abf
--- /dev/null
+++ b/tools/tlc/pyproject.toml
@@ -0,0 +1,147 @@
+# Poetry pyproject.toml: https://python-poetry.org/docs/pyproject/
+[build-system]
+requires = ["poetry_core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry]
+name = "tlc"
+version = "0.9.0"
+description = "Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."
+authors = ["Arm Ltd <tf-a@lists.trustedfirmware.org>"]
+license = "BSD-3"
+repository = "https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/"
+homepage = "https://trustedfirmware-a.readthedocs.io/en/latest/index.html"
+
+# Keywords description https://python-poetry.org/docs/pyproject/#keywords
+keywords = []  #! Update me
+
+# Pypi classifiers: https://pypi.org/classifiers/
+classifiers = [
+  "Development Status :: 3 - Alpha",
+  "Intended Audience :: Developers",
+  "Operating System :: OS Independent",
+  "Topic :: Software Development :: Libraries :: Python Modules",
+  "License :: OSI Approved :: BSD License",
+  "Programming Language :: Python :: 3",
+  "Programming Language :: Python :: 3.8",
+  "Programming Language :: Python :: 3.9",
+]
+
+[tool.poetry.scripts]
+# Entry points for the package https://python-poetry.org/docs/pyproject/#scripts
+"tlc" = "tlc.__main__:cli"
+
+[tool.poetry.dependencies]
+python = "^3.8"
+
+typer = {extras = ["all"], version = "^0.4.0"}
+rich = "^10.14.0"
+click = "^8.1.7"
+pyyaml = "^6.0.1"
+
+[tool.poetry.dev-dependencies]
+bandit = "^1.7.1"
+darglint = "^1.8.1"
+black = "^24.4.2"
+isort = {extras = ["colors"], version = "^5.10.1"}
+mypy = "^0.910"
+mypy-extensions = "^0.4.3"
+pre-commit = "^2.15.0"
+pydocstyle = "^6.1.1"
+pylint = "^2.11.1"
+pytest = "^7.0.0"
+pyupgrade = "^2.29.1"
+safety = "^2.2.0"
+coverage = "^6.1.2"
+coverage-badge = "^1.1.0"
+pytest-html = "^4.1.1"
+pytest-cov = "^3.0.0"
+
+[tool.black]
+# https://github.com/psf/black
+target-version = ["py38"]
+line-length = 88
+color = true
+
+exclude = '''
+/(
+    \.git
+    | \.hg
+    | \.mypy_cache
+    | \.tox
+    | \.venv
+    | _build
+    | buck-out
+    | build
+    | dist
+    | env
+    | venv
+)/
+'''
+
+[tool.isort]
+# https://github.com/timothycrosley/isort/
+py_version = 38
+line_length = 88
+
+known_typing = ["typing", "types", "typing_extensions", "mypy", "mypy_extensions"]
+sections = ["FUTURE", "TYPING", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
+include_trailing_comma = true
+profile = "black"
+multi_line_output = 3
+indent = 4
+color_output = true
+
+[tool.mypy]
+# https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
+python_version = 3.8
+pretty = true
+show_traceback = true
+color_output = true
+
+allow_redefinition = false
+check_untyped_defs = true
+disallow_any_generics = true
+disallow_incomplete_defs = true
+ignore_missing_imports = true
+implicit_reexport = false
+no_implicit_optional = true
+show_column_numbers = true
+show_error_codes = true
+show_error_context = true
+strict_equality = true
+strict_optional = true
+warn_no_return = true
+warn_redundant_casts = true
+warn_return_any = true
+warn_unreachable = true
+warn_unused_configs = true
+warn_unused_ignores = true
+
+
+[tool.pytest.ini_options]
+# https://docs.pytest.org/en/6.2.x/customize.html#pyproject-toml
+# Directories that are not visited by pytest collector:
+norecursedirs =["hooks", "*.egg", ".eggs", "dist", "build", "docs", ".tox", ".git", "__pycache__"]
+doctest_optionflags = ["NUMBER", "NORMALIZE_WHITESPACE", "IGNORE_EXCEPTION_DETAIL"]
+
+# Extra options:
+addopts = [
+  "--strict-markers",
+  "--tb=short",
+  "--doctest-modules",
+  "--doctest-continue-on-failure",
+]
+
+[tool.coverage.run]
+source = ["tests"]
+
+[coverage.paths]
+source = "tlc"
+
+[coverage.run]
+branch = true
+
+[coverage.report]
+fail_under = 50
+show_missing = true
diff --git a/tools/tlc/setup.cfg b/tools/tlc/setup.cfg
new file mode 100644
index 0000000..3c46a08
--- /dev/null
+++ b/tools/tlc/setup.cfg
@@ -0,0 +1,4 @@
+[darglint]
+# https://github.com/terrencepreilly/darglint
+strictness = long
+docstring_style = google
diff --git a/tools/tlc/tests/conftest.py b/tools/tlc/tests/conftest.py
new file mode 100644
index 0000000..b8f88b5
--- /dev/null
+++ b/tools/tlc/tests/conftest.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+""" Common configurations and fixtures for test environment."""
+
+import pytest
+import yaml
+from click.testing import CliRunner
+
+from tlc.cli import cli
+
+
+@pytest.fixture
+def tmptlstr(tmpdir):
+    return tmpdir.join("tl.bin").strpath
+
+
+@pytest.fixture
+def tmpyamlconfig(tmpdir):
+    return tmpdir.join("config.yaml").strpath
+
+
+@pytest.fixture
+def tmpfdt(tmpdir):
+    fdt = tmpdir.join("fdt.dtb")
+    fdt.write_binary(b"\x00" * 100)
+    return fdt
+
+
+@pytest.fixture(params=[1, 2, 3, 4, 5, 0x100, 0x101, 0x102, 0x104])
+def non_empty_tag_id(request):
+    return request.param
+
+
+@pytest.fixture
+def tmpyamlconfig_blob_file(tmpdir, tmpfdt, non_empty_tag_id):
+    config_path = tmpdir.join("config.yaml")
+
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [
+            {
+                "tag_id": non_empty_tag_id,
+                "blob_file_path": tmpfdt.strpath,
+            },
+        ],
+    }
+
+    with open(config_path, "w") as f:
+        yaml.safe_dump(config, f)
+
+    return config_path
+
+
+@pytest.fixture
+def tlcrunner(tmptlstr):
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        runner.invoke(cli, ["create", tmptlstr])
+    return runner
+
+
+@pytest.fixture
+def tlc_entries(tmpfdt):
+    return [(0, "/dev/null"), (1, tmpfdt.strpath), (0x102, tmpfdt.strpath)]
diff --git a/tools/tlc/tests/test_cli.py b/tools/tlc/tests/test_cli.py
new file mode 100644
index 0000000..99b5816
--- /dev/null
+++ b/tools/tlc/tests/test_cli.py
@@ -0,0 +1,413 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Contains unit tests for the CLI functionality."""
+
+from pathlib import Path
+from unittest import mock
+from math import log2, ceil
+
+import pytest
+import pytest
+import yaml
+from click.testing import CliRunner
+
+from tlc.cli import cli
+from tlc.te import TransferEntry
+from tlc.tl import TransferList
+
+
+def test_create_empty_tl(tmpdir):
+    runner = CliRunner()
+    test_file = tmpdir.join("tl.bin")
+
+    result = runner.invoke(cli, ["create", test_file.strpath])
+    assert result.exit_code == 0
+    assert TransferList.fromfile(test_file) is not None
+
+
+def test_create_with_fdt(tmpdir):
+    runner = CliRunner()
+    fdt = tmpdir.join("fdt.dtb")
+    fdt.write_binary(b"\x00" * 100)
+
+    result = runner.invoke(
+        cli,
+        [
+            "create",
+            "--fdt",
+            fdt.strpath,
+            "--size",
+            "1000",
+            tmpdir.join("tl.bin").strpath,
+        ],
+    )
+    assert result.exit_code == 0
+
+
+def test_add_single_entry(tlcrunner, tmptlstr):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+    assert tl.entries[0].id == 0
+
+
+def test_add_multiple_entries(tlcrunner, tlc_entries, tmptlstr):
+    for id, path in tlc_entries:
+        tlcrunner.invoke(cli, ["add", "--entry", id, path, tmptlstr])
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == len(tlc_entries)
+
+
+def test_info(tlcrunner, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+    tlcrunner.invoke(cli, ["add", "--fdt", tmpfdt.strpath, tmptlstr])
+
+    result = tlcrunner.invoke(cli, ["info", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+    assert "id" in result.stdout
+
+    result = tlcrunner.invoke(cli, ["info", "--header", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+    assert "id" not in result.stdout
+
+    result = tlcrunner.invoke(cli, ["info", "--entries", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" not in result.stdout
+    assert "id" in result.stdout
+
+
+def test_raises_max_size_error(tmptlstr, tmpfdt):
+    tmpfdt.write_binary(bytes(6000))
+
+    runner = CliRunner()
+    result = runner.invoke(cli, ["create", "--fdt", tmpfdt, tmptlstr])
+
+    assert result.exception
+    assert isinstance(result.exception, MemoryError)
+    assert "TL max size exceeded, consider increasing with the option -s" in str(
+        result.exception
+    )
+    assert "TL size has exceeded the maximum allocation" in str(
+        result.exception.__cause__
+    )
+
+
+def test_info_get_fdt_offset(tmptlstr, tmpfdt):
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        runner.invoke(cli, ["create", "--size", "1000", tmptlstr])
+        runner.invoke(cli, ["add", "--entry", "1", tmpfdt.strpath, tmptlstr])
+        result = runner.invoke(cli, ["info", "--fdt-offset", tmptlstr])
+
+    assert result.exit_code == 0
+    assert result.output.strip("\n").isdigit()
+
+
+def test_remove_tag(tlcrunner, tmptlstr):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+    result = tlcrunner.invoke(cli, ["info", tmptlstr])
+
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+
+    tlcrunner.invoke(cli, ["remove", "--tags", "0", tmptlstr])
+    tl = TransferList.fromfile(tmptlstr)
+
+    assert result.exit_code == 0
+    assert len(tl.entries) == 0
+
+
+def test_unpack_tl(tlcrunner, tmptlstr, tmpfdt, tmpdir):
+    with tlcrunner.isolated_filesystem(temp_dir=tmpdir):
+        tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+        tlcrunner.invoke(cli, ["unpack", tmptlstr])
+        assert Path("te_0_1.bin").exists()
+
+
+def test_unpack_multiple_tes(tlcrunner, tlc_entries, tmptlstr, tmpdir):
+    with tlcrunner.isolated_filesystem(temp_dir=tmpdir):
+        for id, path in tlc_entries:
+            tlcrunner.invoke(cli, ["add", "--entry", id, path, tmptlstr])
+
+    assert all(
+        filter(
+            lambda te: (Path(tmpdir.strpath) / f"te_{te[0]}.bin").exists(), tlc_entries
+        )
+    )
+
+
+def test_unpack_into_dir(tlcrunner, tmpdir, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["unpack", "-C", tmpdir.strpath, tmptlstr])
+
+    assert (Path(tmpdir.strpath) / "te_0_1.bin").exists()
+
+
+def test_unpack_into_dir_with_conflicting_tags(tlcrunner, tmpdir, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["unpack", "-C", tmpdir.strpath, tmptlstr])
+
+    assert (Path(tmpdir.strpath) / "te_0_1.bin").exists()
+    assert (Path(tmpdir.strpath) / "te_1_1.bin").exists()
+
+
+def test_validate_invalid_signature(tmptlstr, tlcrunner, monkeypatch):
+    tl = TransferList()
+    tl.signature = 0xDEADBEEF
+
+    mock_open = lambda tmptlstr, mode: mock.mock_open(read_data=tl.header_to_bytes())()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+    assert result.exit_code != 0
+
+
+def test_validate_misaligned_entries(tmptlstr, tlcrunner, monkeypatch):
+    """Base address of a TE must be 8-byte aligned."""
+    mock_open = lambda tmptlstr, mode: mock.mock_open(
+        read_data=TransferList().header_to_bytes()
+        + bytes(5)
+        + TransferEntry(0, 0, bytes(0)).header_to_bytes
+    )()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+
+    assert result.exit_code == 1
+
+
+@pytest.mark.parametrize(
+    "version", [0, TransferList.version, TransferList.version + 1, 1 << 8]
+)
+def test_validate_unsupported_version(version, tmptlstr, tlcrunner, monkeypatch):
+    tl = TransferList()
+    tl.version = version
+
+    mock_open = lambda tmptlstr, mode: mock.mock_open(read_data=tl.header_to_bytes())()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+
+    if version >= TransferList.version and version <= 0xFF:
+        assert result.exit_code == 0
+    else:
+        assert result.exit_code == 1
+
+
+def test_create_entry_from_yaml_and_blob_file(
+    tlcrunner, tmpyamlconfig_blob_file, tmptlstr, non_empty_tag_id
+):
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig_blob_file.strpath,
+            tmptlstr,
+        ],
+    )
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+    assert tl.entries[0].id == non_empty_tag_id
+
+
+@pytest.mark.parametrize(
+    "entry",
+    [
+        {"tag_id": 0},
+        {
+            "tag_id": 0x104,
+            "addr": 0x0400100000000010,
+            "size": 0x0003300000000000,
+        },
+        {
+            "tag_id": 0x100,
+            "pp_addr": 100,
+        },
+        {
+            "tag_id": "optee_pageable_part",
+            "pp_addr": 100,
+        },
+    ],
+)
+def test_create_from_yaml_check_sum_bytes(tlcrunner, tmpyamlconfig, tmptlstr, entry):
+    """Test creating a TL from a yaml file, but only check that the sum of the
+    data in the yaml file matches the sum of the data in the TL. This means
+    you don't have to type the exact sequence of expected bytes. All the data
+    in the yaml file must be integers (except for the tag IDs, which can be
+    strings).
+    """
+    # create yaml config file
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [entry],
+    }
+    with open(tmpyamlconfig, "w") as f:
+        yaml.safe_dump(config, f)
+
+    # invoke TLC
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig,
+            tmptlstr,
+        ],
+    )
+
+    # open created TL, and check
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+
+    # Check that the sum of all the data in the transfer entry in the yaml file
+    # is the same as the sum of all the data in the transfer list. Don't count
+    # the tag id or the TE headers.
+
+    # every item in the entry dict must be an integer
+    yaml_total = 0
+    for key, data in iter_nested_dict(entry):
+        if key != "tag_id":
+            num_bytes = ceil(log2(data + 1) / 8)
+            yaml_total += sum(data.to_bytes(num_bytes, "little"))
+
+    tl_total = sum(tl.entries[0].data)
+
+    assert tl_total == yaml_total
+
+
+@pytest.mark.parametrize(
+    "entry,expected",
+    [
+        (
+            {
+                "tag_id": 0x102,
+                "ep_info": {
+                    "h": {
+                        "type": 0x01,
+                        "version": 0x02,
+                        "attr": 8,
+                    },
+                    "pc": 67239936,
+                    "spsr": 965,
+                    "args": [67112976, 67112960, 0, 0, 0, 0, 0, 0],
+                },
+            },
+            (
+                "0x00580201 0x00000008 0x04020000 0x00000000 "
+                "0x000003C5 0x00000000 0x04001010 0x00000000 "
+                "0x04001000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000"
+            ),
+        ),
+        (
+            {
+                "tag_id": 0x102,
+                "ep_info": {
+                    "h": {
+                        "type": 0x01,
+                        "version": 0x02,
+                        "attr": "EP_NON_SECURE | EP_ST_ENABLE",
+                    },
+                    "pc": 67239936,
+                    "spsr": 965,
+                    "args": [67112976, 67112960, 0, 0, 0, 0, 0, 0],
+                },
+            },
+            (
+                "0x00580201 0x00000005 0x04020000 0x00000000 "
+                "0x000003C5 0x00000000 0x04001010 0x00000000 "
+                "0x04001000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000"
+            ),
+        ),
+    ],
+)
+def test_create_from_yaml_check_exact_data(
+    tlcrunner, tmpyamlconfig, tmptlstr, entry, expected
+):
+    """Test creating a TL from a yaml file, checking the exact sequence of
+    bytes. This is useful for checking that the alignment is correct. You can
+    get the expected sequence of bytes by copying it from the ArmDS debugger.
+    """
+    # create yaml config file
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [entry],
+    }
+    with open(tmpyamlconfig, "w") as f:
+        yaml.safe_dump(config, f)
+
+    # invoke TLC
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig,
+            tmptlstr,
+        ],
+    )
+
+    # open TL and check
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+
+    # check expected and actual data
+    actual = tl.entries[0].data
+    actual = bytes_to_hex(actual)
+
+    assert actual == expected
+
+
+def bytes_to_hex(data: bytes) -> str:
+    """Convert bytes to a hex string in the same format as the debugger in
+    ArmDS
+
+    You can copy data from the debugger in Arm Development Studio and put it
+    into a unit test. You can then run this function on the output from tlc,
+    and compare it to the data you copied.
+
+    The format is groups of 4 bytes with 0x prefixes separated by spaces.
+    Little endian is used.
+    """
+    words_hex = []
+    for i in range(0, len(data), 4):
+        word = data[i : i + 4]
+        word_int = int.from_bytes(word, "little")
+        word_hex = "0x" + f"{word_int:0>8x}".upper()
+        words_hex.append(word_hex)
+
+    return " ".join(words_hex)
+
+
+def iter_nested_dict(dictionary: dict):
+    for key, value in dictionary.items():
+        if isinstance(value, dict):
+            yield from iter_nested_dict(value)
+        else:
+            yield key, value
diff --git a/tools/tlc/tests/test_transfer_list.py b/tools/tlc/tests/test_transfer_list.py
new file mode 100644
index 0000000..e8c430e
--- /dev/null
+++ b/tools/tlc/tests/test_transfer_list.py
@@ -0,0 +1,234 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Contains unit tests for the types TransferEntry and TransferList."""
+
+import math
+
+import pytest
+
+from tlc.te import TransferEntry
+from tlc.tl import TransferList
+
+large_data = 0xDEADBEEF.to_bytes(4, "big")
+small_data = 0x1234.to_bytes(3, "big")
+test_entries = [
+    (0, b""),
+    (1, small_data),
+    (1, large_data),
+    (0xFFFFFF, small_data),
+    (0xFFFFFF, large_data),
+]
+
+
+@pytest.mark.parametrize(
+    "size,csum",
+    [
+        (-1, None),
+        (0x18, 0x9E),
+        (0x1000, 0xA6),
+        (0x2000, 0x96),
+        (0x4000, 0x76),
+    ],
+)
+def test_make_transfer_list(size, csum):
+    if size < 8:
+        with pytest.raises(AssertionError):
+            tl = TransferList(size)
+    else:
+        tl = TransferList(size)
+
+        assert tl.signature == 0x4A0FB10B
+        assert not tl.entries
+        assert tl.sum_of_bytes() == 0
+        assert tl.checksum == csum
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_add_transfer_entry(tag_id, data):
+    tl = TransferList(0x1000)
+    te = TransferEntry(tag_id, len(data), data)
+
+    tl.add_transfer_entry(tag_id, data)
+
+    assert te in tl.entries
+    assert tl.size == TransferList.hdr_size + te.size
+
+
+@pytest.mark.parametrize(
+    ("tag_id", "data"),
+    [
+        (-1, None),  # tag out of range
+        (1, None),  # no data provided
+        (1, bytes(8000)),  # very large data > total size
+        (0x100000, b"0dd0edfe"),  # tag out of range
+    ],
+)
+def test_add_out_of_range_transfer_entry(tag_id, data):
+    tl = TransferList()
+
+    with pytest.raises(Exception):
+        tl.add_transfer_entry(tag_id, data)
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_calculate_te_sum_of_bytes(tag_id, data):
+    te = TransferEntry(tag_id, len(data), data)
+    csum = (
+        sum(data)
+        + sum(len(data).to_bytes(4, "big"))
+        + te.hdr_size
+        + sum(tag_id.to_bytes(4, "big"))
+    ) % 256
+    assert te.sum_of_bytes == csum
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_calculate_tl_checksum(tag_id, data):
+    tl = TransferList(0x1000)
+
+    tl.add_transfer_entry(tag_id, data)
+    assert tl.sum_of_bytes() == 0
+
+
+def test_empty_transfer_list_blob(tmpdir):
+    """Check that we can correctly create a transfer list header."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList()
+    tl.write_to_file(test_file)
+
+    with open(test_file, "rb") as f:
+        assert f.read(tl.hdr_size) == tl.header_to_bytes()
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_single_te_transfer_list(tag_id, data, tmpdir):
+    """Check that we can create a complete TL with a single TE."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList(0x1000)
+
+    tl.add_transfer_entry(tag_id, data)
+    tl.write_to_file(test_file)
+
+    te = tl.entries[0]
+
+    with open(test_file, "rb") as f:
+        assert f.read(tl.hdr_size) == tl.header_to_bytes()
+        assert int.from_bytes(f.read(3), "little") == te.id
+        assert int.from_bytes(f.read(1), "little") == te.hdr_size
+        assert int.from_bytes(f.read(4), "little") == te.data_size
+        assert f.read(te.data_size) == te.data
+
+
+def test_multiple_te_transfer_list(tmpdir):
+    """Check that we can create a TL with multiple TE's."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList(0x1000)
+
+    for tag_id, data in test_entries:
+        tl.add_transfer_entry(tag_id, data)
+
+    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())
+            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
+
+
+def test_read_empty_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+    assert tl.header_to_bytes() == original_tl.header_to_bytes()
+    assert tl.sum_of_bytes() == 0
+
+
+def test_read_single_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+
+    original_tl.add_transfer_entry(test_entries[0][0], test_entries[0][1])
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+    assert tl.entries
+
+    te = tl.entries[0]
+    assert te.id == test_entries[0][0]
+    assert te.data == test_entries[0][1]
+    assert tl.sum_of_bytes() == 0
+
+
+def test_read_multiple_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+
+    for tag_id, data in test_entries:
+        original_tl.add_transfer_entry(tag_id, data)
+
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+
+    # The TE we derive from the file might have a an associated offset, compare
+    # the TE's based on the header in bytes, which doesn't account for this.
+    for te0, te1 in zip(tl.entries, original_tl.entries):
+        assert te0.header_to_bytes() == te1.header_to_bytes()
+
+    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)
+
+    for tag_id, data in test_entries:
+        tl.add_transfer_entry(tag_id, data)
+
+    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))
+
+
+def test_get_fdt_offset(tmpdir):
+    tl = TransferList(0x1000)
+    tl.add_transfer_entry(1, 0xEDFE0DD0.to_bytes(4, "big"))
+    f = tmpdir.join("blob.bin")
+
+    tl.write_to_file(f)
+
+    blob_tl = TransferList.fromfile(f)
+
+    assert blob_tl.hdr_size + TransferEntry.hdr_size == blob_tl.get_entry_data_offset(1)
+
+
+def test_get_missing_fdt_offset(tmpdir):
+    tl = TransferList(0x1000)
+    f = tmpdir.join("blob.bin")
+
+    tl.write_to_file(f)
+    blob_tl = TransferList.fromfile(f)
+
+    with pytest.raises(ValueError):
+        blob_tl.get_entry_data_offset(1)
diff --git a/tools/tlc/tlc/__init__.py b/tools/tlc/tlc/__init__.py
new file mode 100644
index 0000000..82f5f5b
--- /dev/null
+++ b/tools/tlc/tlc/__init__.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."""
+
+import sys
+
+if sys.version_info >= (3, 8):
+    from importlib import metadata as importlib_metadata
+else:
+    import importlib_metadata
+
+
+def get_version() -> str:
+    try:
+        return importlib_metadata.version(__name__)
+    except importlib_metadata.PackageNotFoundError:  # pragma: no cover
+        return "unknown"
+
+
+version: str = get_version()
diff --git a/tools/tlc/tlc/__main__.py b/tools/tlc/tlc/__main__.py
new file mode 100644
index 0000000..03ffa0e
--- /dev/null
+++ b/tools/tlc/tlc/__main__.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from tlc.cli import cli
+
+if __name__ == "__main__":
+    cli()
diff --git a/tools/tlc/tlc/cli.py b/tools/tlc/tlc/cli.py
new file mode 100644
index 0000000..1d4949d
--- /dev/null
+++ b/tools/tlc/tlc/cli.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module defining the Transfer List Compiler (TLC) command line interface."""
+
+from pathlib import Path
+
+import click
+import yaml
+
+from tlc.tl import *
+
+
+@click.group()
+@click.version_option()
+def cli():
+    pass
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(dir_okay=False))
+@click.option(
+    "-s", "--size", default=0x1000, type=int, help="Maximum size of the Transfer List"
+)
+@click.option(
+    "--fdt",
+    type=click.Path(exists=True),
+    help="Path to flattened device tree (FDT).",
+)
+@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>.",
+)
+@click.option(
+    "--flags",
+    default=TRANSFER_LIST_ENABLE_CHECKSUM,
+    show_default=True,
+    help="Settings for the TL's properties.",
+)
+@click.option(
+    "--from-yaml",
+    type=click.Path(exists=True),
+    help="Create the transfer list from a YAML config file.",
+)
+def create(filename, size, fdt, entry, flags, from_yaml):
+    """Create a new Transfer List."""
+    try:
+        if from_yaml:
+            with open(from_yaml, "r") as f:
+                config = yaml.safe_load(f)
+
+            tl = TransferList.from_dict(config)
+        else:
+            tl = TransferList(size)
+
+            entry = (*entry, (1, fdt)) if fdt else entry
+
+            for id, path in entry:
+                tl.add_transfer_entry_from_file(id, path)
+    except MemoryError as mem_excp:
+        raise MemoryError(
+            "TL max size exceeded, consider increasing with the option -s"
+        ) from mem_excp
+
+    tl.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--fdt-offset",
+    is_flag=True,
+    help="Returns the offset of FDT in the TL if it is present.",
+)
+@click.option(
+    "--header",
+    is_flag=True,
+    help="Print the Transfer List header.",
+)
+@click.option(
+    "--entries",
+    is_flag=True,
+    help="Print the Transfer List entries.",
+)
+def info(filename, fdt_offset, header, entries):
+    """Print the contents of an existing Transfer List.
+
+    This command allows you to extract the data stored in a binary blob
+    representing a transfer list (TL). The transfer list must comply with the
+    version of the firmware handoff specification supported by this tool.
+    """
+    tl = TransferList.fromfile(filename)
+
+    if fdt_offset:
+        return print(tl.get_entry_data_offset(1))
+
+    if header and entries or not (header or entries):
+        print(tl, sep="")
+        if tl.entries:
+            print("----", tl.get_transfer_entries_str(), sep="\n")
+    elif entries:
+        print(tl.get_transfer_entries_str())
+    elif header:
+        print(tl)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--tags",
+    type=int,
+    multiple=True,
+    help="Tags to be removed from TL.",
+)
+def remove(filename, tags):
+    """Remove Transfer Entries with given tags.
+
+    Remove Transfer Entries with given tags from a Transfer List."""
+    tl = TransferList.fromfile(filename)
+
+    for tag in tags:
+        tl.remove_tag(tag)
+    tl.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@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):
+    """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.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "-C", type=click.Path(exists=True), help="Output directory for extracted images."
+)
+def unpack(filename, c):
+    """Unpack images from a Transfer List."""
+    tl = TransferList.fromfile(filename)
+    pwd = Path(".") if not c else Path(c)
+
+    for i, te in enumerate(tl.entries):
+        with open(pwd / f"te_{i}_{te.id}.bin", "wb") as f:
+            f.write(te.data)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+def validate(filename):
+    """Validate the contents of an existing Transfer List."""
+    TransferList.fromfile(filename)
+    print("Valid TL!")
diff --git a/tools/tlc/tlc/te.py b/tools/tlc/tlc/te.py
new file mode 100644
index 0000000..cf7aa67
--- /dev/null
+++ b/tools/tlc/tlc/te.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module containing definitions pertaining to the 'Transfer Entry' (TE) type."""
+
+from typing import ClassVar
+
+import struct
+from dataclasses import dataclass
+
+
+@dataclass
+class TransferEntry:
+    """Class representing a Transfer Entry."""
+
+    id: int
+    data_size: int
+    data: bytes
+    hdr_size: int = 8
+    offset: int = 0
+    # Header encoding, with little-endian byte order.
+    encoding: ClassVar[str] = "<BI"
+
+    def __post_init__(self):
+        if self.id < 0 or self.id > 0xFFFFFF:
+            raise ValueError(
+                f"Out of bounds tag ID: {self.id:x}.\n"
+                f"Valid range is from 0 to 0xFFFFFF. Please ensure the tag ID is within this range."
+            )
+
+    def __str__(self) -> str:
+        return "\n".join(
+            [
+                f"{k:<10} {hex(v)}"
+                for k, v in vars(self).items()
+                if not isinstance(v, bytes)
+            ]
+        )
+
+    @property
+    def size(self) -> int:
+        return self.hdr_size + len(self.data)
+
+    @property
+    def sum_of_bytes(self) -> int:
+        return (sum(self.header_to_bytes()) + sum(self.data)) % 256
+
+    def header_to_bytes(self) -> bytes:
+        return self.id.to_bytes(3, "little") + struct.pack(
+            self.encoding, self.hdr_size, self.data_size
+        )
diff --git a/tools/tlc/tlc/tl.py b/tools/tlc/tlc/tl.py
new file mode 100644
index 0000000..3f0065d
--- /dev/null
+++ b/tools/tlc/tlc/tl.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module containing definitions pertaining to the 'Transfer List' (TL) type."""
+
+import typing
+
+import math
+import struct
+from dataclasses import dataclass
+from functools import reduce
+from pathlib import Path
+
+from tlc.te import TransferEntry
+
+TRANSFER_LIST_ENABLE_CHECKSUM = 0b1
+
+# Description of each TE type. For each TE, there is a tag ID, a format (to be
+# used in struct.pack to encode the TE), and a list of field names that can
+# appear in the yaml file for that TE. Some fields are missing, if that TE has
+# to be processed differently, or if it can only be added with a blob file.
+transfer_entry_formats = {
+    0: {
+        "tag_name": "empty",
+        "format": "4x",
+        "fields": [],
+    },
+    1: {
+        "tag_name": "fdt",
+    },
+    2: {
+        "tag_name": "hob_block",
+    },
+    3: {
+        "tag_name": "hob_list",
+    },
+    4: {
+        "tag_name": "acpi_table_aggregate",
+    },
+    5: {
+        "tag_name": "tpm_event_log_table",
+        "fields": ["event_log", "flags"],
+    },
+    6: {
+        "tag_name": "tpm_crb_base_address_table",
+        "format": "QI",
+        "fields": ["crb_base_address", "crb_size"],
+    },
+    0x100: {
+        "tag_name": "optee_pageable_part",
+        "format": "Q",
+        "fields": ["pp_addr"],
+    },
+    0x101: {
+        "tag_name": "dt_spmc_manifest",
+    },
+    0x102: {
+        "tag_name": "exec_ep_info",
+        "format": "2BHIQI4x8Q",
+        "fields": ["ep_info"],
+    },
+    0x104: {
+        "tag_name": "sram_layout",
+        "format": "2Q",
+        "fields": ["addr", "size"],
+    },
+}
+tag_name_to_tag_id = {
+    te["tag_name"]: tag_id for tag_id, te in transfer_entry_formats.items()
+}
+
+
+class TransferList:
+    """Class representing a Transfer List based on version 1.0 of the Firmware Handoff specification."""
+
+    # Header encoding, with little-endian byte order.
+    encoding = "<I4B4I"
+    hdr_size = 0x18
+    signature = 0x4A0FB10B
+    version = 1
+
+    def __init__(
+        self, max_size: int = hdr_size, flags: int = TRANSFER_LIST_ENABLE_CHECKSUM
+    ) -> None:
+        assert max_size >= self.hdr_size
+        self.checksum: int = 0
+        self.alignment: int = 3
+        self.size = self.hdr_size
+        self.total_size = max_size
+        self.flags = flags
+        self.entries: typing.List["TransferEntry"] = []
+        self.update_checksum()
+
+    def __str__(self) -> str:
+        return "\n".join(
+            [
+                f"{k:<10} {hex(v)}"
+                for k, v in vars(self).items()
+                if not isinstance(v, list)
+            ]
+        )
+
+    def get_transfer_entries_str(self):
+        return "\n----\n".join([str(te) for _, te in enumerate(self.entries)])
+
+    @classmethod
+    def fromfile(cls, filepath: Path) -> "TransferList":
+        tl = cls()
+
+        with open(filepath, "rb") as f:
+            (
+                tl.signature,
+                tl.checksum,
+                tl.version,
+                tl.hdr_size,
+                tl.alignment,
+                used_size,
+                tl.total_size,
+                tl.flags,
+                _,
+            ) = struct.unpack(
+                cls.encoding,
+                f.read(tl.hdr_size),
+            )
+
+            if tl.signature != TransferList.signature:
+                raise ValueError(f"Invalid TL signature 0x{tl.signature:x}!")
+            elif tl.version == 0 or tl.version > 0xFF:
+                raise ValueError(f"Invalid TL version 0x{tl.version:x}!")
+            else:
+                while tl.size < used_size:
+                    # We add an extra padding byte into the header so we can extract
+                    # 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(
+                        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))
+
+        return tl
+
+    @classmethod
+    def from_dict(cls, config: dict):
+        """Create a TL from data in a dictionary
+
+        The dictionary should have the same format as the yaml config files.
+        See the readme for more detail.
+
+        :param config: Dictionary containing the data described above.
+        """
+        # get settings from config and set defaults
+        max_size = config.get("max_size", 0x1000)
+        has_checksum = config.get("has_checksum", True)
+
+        flags = TRANSFER_LIST_ENABLE_CHECKSUM if has_checksum else 0
+
+        tl = cls(max_size, flags)
+
+        for entry in config["entries"]:
+            tl.add_transfer_entry_from_dict(entry)
+
+        return tl
+
+    def header_to_bytes(self) -> bytes:
+        return struct.pack(
+            self.encoding,
+            self.signature,
+            self.checksum,
+            self.version,
+            self.hdr_size,
+            self.alignment,
+            self.size,
+            self.total_size,
+            self.flags,
+            0,
+        )
+
+    def update_checksum(self) -> None:
+        """Calculates the checksum based on the sum of bytes."""
+        self.checksum = 256 - ((self.sum_of_bytes() - self.checksum) % 256)
+
+    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
+
+    def get_entry_data_offset(self, tag_id: int) -> int:
+        """Returns offset of data of a TE from the base of the TL."""
+        for te in self.entries:
+            if te.id == tag_id:
+                return te.offset + te.hdr_size
+
+        raise ValueError(f"Tag {tag_id} not found in TL!")
+
+    def add_transfer_entry(self, tag_id: int, data: bytes) -> "TransferEntry":
+        """Appends a TransferEntry into the internal list of TE's."""
+        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
+
+    def add_transfer_entry_from_struct_format(
+        self, tag_id: int, struct_format: str, *args
+    ):
+        struct_format = "<" + struct_format
+        data = struct.pack(struct_format, *args)
+        return self.add_transfer_entry(tag_id, data)
+
+    def add_entry_point_info_transfer_entry(self, entry: dict) -> "TransferEntry":
+        """Add entry_point_info transfer entry
+
+        :param entry: Dictionary of the transfer entry, in the same format as
+        the YAML file.
+        """
+        ep_info = entry["ep_info"]
+        header = ep_info["h"]
+
+        # size of the entry_point_info struct
+        entry_point_size = 88
+
+        attr = header["attr"]
+        if type(attr) is str:
+            # convert string of flags names to an integer
+
+            # bit number  | 0                     | 1                    |
+            # ------------|-----------------------|----------------------|
+            # 0           | secure                | non-secure           |
+            # 1           | little endian         | big-endian           |
+            # 2           | disable secure timer  | enable secure timer  |
+            # 3           | executable            | non-executable       |
+            # 4           | first exe             | not first exe        |
+            #
+            # Bit 5 and bit 0 are used to determine the security state.
+
+            flag_names = {
+                "EP_SECURE": 0x0,
+                "EP_NON_SECURE": 0x1,
+                "EP_REALM": 0x21,
+                "EP_EE_LITTLE": 0x0,
+                "EP_EE_BIG": 0x2,
+                "EP_ST_DISABLE": 0x0,
+                "EP_ST_ENABLE": 0x4,
+                "EP_NON_EXECUTABLE": 0x0,
+                "EP_EXECUTABLE": 0x8,
+                "EP_FIRST_EXE": 0x10,
+            }
+
+            # create list of integer flags, then bitwise-or them together
+            flags = [flag_names[f.strip()] for f in attr.split("|")]
+            attr = reduce(lambda x, y: x | y, flags)
+
+        return self.add_transfer_entry_from_struct_format(
+            0x102,
+            transfer_entry_formats[0x102]["format"],
+            header["type"],
+            header["version"],
+            entry_point_size,
+            attr,
+            ep_info["pc"],
+            ep_info["spsr"],
+            *ep_info["args"],
+        )
+
+    def add_transfer_entry_from_dict(
+        self,
+        entry: dict,
+    ) -> "TransferEntry":
+        """Add a transfer entry from data in a dictionary
+
+        The dictionary should have the same format as the entries in the yaml
+        config files. See the readme for more detail.
+
+        :param entry: Dictionary containing the data described above.
+        """
+        # Tag_id is either a tag name or a tag id. Use it to get the TE format.
+        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"]
+
+        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
+            )
+        else:
+            raise ValueError(f"Invalid transfer entry {entry}.")
+
+    def add_transfer_entry_from_file(self, tag_id: int, path: Path) -> "TransferEntry":
+        with open(path, "rb") as f:
+            return self.add_transfer_entry(tag_id, f.read())
+
+    def write_to_file(self, file: Path) -> None:
+        """Write the contents of the TL to a file."""
+        with open(file, "wb") as f:
+            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()
+                        )
+                    )
+                )
+
+    def remove_tag(self, tag: int) -> None:
+        self.entries = list(filter(lambda te: te.id != tag, self.entries))
+        self.size = self.hdr_size + sum(map(lambda te: te.size, self.entries))
+        self.update_checksum()
+
+
+def align(n, alignment):
+    return int(math.ceil(n / alignment) * alignment)